I am writing a CLI application and want to enable shell completion. The package I am using to write the CLI app supports a few shells out of the box, but not Powershell. So I am writing my own for it.
There are of course a lot of iterations as I try to get this built correctly, and it "feels" like my tab auto-completion is using some older version of my script even though I try to update it.
I am doing this.
$script = {
param($wordToComplete, $commandAst, $cursorPosition)
# do stuff that returns list of completion options
}
Register-ArgumentCompleter -Native -CommandName <cliapp> -ScriptBlock $script
Is there a way to de-register the argument completer and "start over"?
This script is being stored in echo $profile
if it matters.
I can remove the script entirely from the profile, and it still seems to persist, even after windows being closed and re-opened.
Details of $PSversionTable
. Should I be using some other version as well?
Name Value
---- -----
PSVersion 5.1.14393.5127
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14393.5127
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Any help is appreciated.
CodePudding user response:
Register-ArgumentCompleter
has no complementary cmdlet for removing specific completers (or clearing all currently registered completers) - verify with Get-Command *-ArgumentCompleter
). Presumably, the rationale is that such completers are meant to be registered once in a session and then used for the remainder of that session.
- Note that
Register-ArgumentCompleter
never installs a completer persistently. - If you want completers to be available in every session, add
Register-ArgumentCompleter
calls to your$PROFILE
file (which in turn implies that sessions started via the CLI's-NoProfile
switch won't see them).
However, given that only one completer can be in effect for a given name passed to -CommandName
:
You can effectively remove an active completer for a given
-CommandName
by re-invokingRegister-ArgumentCompleter
with-ScriptBlock $null
.You can redefine an active completer for a given
-CommandName
by re-invokingRegister-ArgumentCompleter
and passing a new completer script block to-ScriptBlock
.
You can verify this as follows:
Define a dummy command (function) to register a completer for:
function foo {}
Define the initial completer for it:
Register-ArgumentCompleter -CommandName foo -ScriptBlock { 'initial' }
Type
foo
(note the trailing space) followed by Tab and see the argument expand toinitial
.Redefine the completer:
Register-ArgumentCompleter -CommandName foo -ScriptBlock { 'redefined' }
Type
foo
followed by Tab and see the argument now expand toredefined
.