I'm trying to use Register-ArgumentCompleter to implement subcommand completion with the following behaviour:
> mycommand <tab>
subcommandA subcommandB subcommandC
> mycommand subcommandA <tab>
optionA1 optionA2
> mycommand subcommandB <tab>
optionB1 optionB2
I would also like to split each subcommand into its own script in a commands/ directory and discover them dynamically. I have achieved call forwarding and top-level completion with the following code:
Function mycommand {
[CmdletBinding()]
Param(
[parameter(Mandatory = $true)]
[String] $command,
[parameter(ValueFromRemainingArguments = $true)]
[String[]]$arguments
)
# Forward all arguments
& "$PSScriptRoot\commands\$command.ps1" @arguments
}
Register-ArgumentCompleter -CommandName mycommand -ParameterName command -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
return @(Get-ChildItem "$PSScriptRoot\commands" | %{ $_.Basename } | Sort -Unique)
}
Register-ArgumentCompleter -CommandName nrm -ParameterName arguments -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
# (1) I land here with the correct `$fakeBoundParameters.command`. Now what?
}
I have tried to call back into TabExpansion2 from (1) with the following code:
# Remove mycommand and subcommandX, replace with subcommandX's script path
$command = $fakeBoundParameters.command
$subtokens = $($commandAst.CommandElements | Select-Object -Skip 2)
$inputScript = "`"$PSScriptRoot\commands\$command.ps1`" $subtokens "
$(TabExpansion2 -inputScript $inputScript -cursorColumn $inputScript.Length -options $null).CompletionMatches
... but CompletionMatches comes back empty. I'm also unsure about passing the cursor position, to which I don't have access from my ArgumentCompleter.
Is there a simple way to forward the completion request to the subcommand's script?