PowerShell module for complete native command parameters and arguments
Inspired by the fish shell's advanced completion features, this module dynamically loads completion definition scripts from specific directories for Unix-like shells such as bash, zsh, and fish. This approach ensures fast startup times. Additionally, the completions provided by this module are designed to have low priority, ensuring they do not interfere with custom completion scripts for specific commands.
- PowerShell >= 7.6.0-preview.5
Install-Module -Name NativeCommandCompleter.psmNote
NativeCommandCompleter.psm provides only the completion framework.
To install completion definitions for individual commands, please install NativeCommandCompleter.completions.
Install-Module -Name NativeCommandCompleter.completionscd path/to/dir
git clone https://github.com/teramako/NativeCommandCompleter.psm.gitcd NativeCommandCompleter.psm
dotnet build ./srccd ($env:PSModulePath -split [System.IO.Path]::PathSeparator)[0]
ln -s path/to/dir/NativeCommandCompleter.psmEdit the profile loaded at PowerShell startup
& $env:EDITOR $PROFILEAdd the following code:
Import-Module -Name NativeCommandCompleter.psmNote
If you have installed NativeCommandCompleter.completions, please import that module as well.
Import-Module -Name NativeCommandCompleter.completionsTip
I recommend changing the style of the selection.
Set-PSReadLineOption -Colors @{
Selection = $PSStyle.Reverse;
}Path(s) of the directory where the completion scripts for each command are located.
(The path separator is ; on Windows and : on Unix-like OS)
The target file ({command-name}.ps1) is searched and read during completion dymanically.
Once loaded and registered, the completion code is cached and will not be reloaded until it is unregistered.
If not specified, the {profile directory}/completions and {module directory}/completions directories are set automatically.
Completion definitions for common commands are available as a separate module: NativeCommandCompleter.completions
flowchart TD
START@{ shape: manual-input, label: "PSReadLine\nTab key pressed"}
B[Determine completion type]
C{What type?}
D[Standard completion\npath, parameter name, etc.]
E[Check Register-ArgumentCompleter\nfor command-specific completer]
F{Specific completer\nregistered?}
G[Run command-specific\nScriptBlock]
END([Show completion candidates])
START ==> B ==> C
C -->|PS / Cmdlet| D --> END
C ==>|Native command| E ==> F
F -->|Yes| G --> END
F ==>|No - fallback| RunCompleter
subgraph NativeCommandCompleter.psm
RunCompleter[NativeCommandCompleter\nRun completer]
SearchCache{Search completer definition}
SearchCache2{Search completer definition}
BuildCompletionCandidates[Build completion candidates]
BuildCompletionCandidates2[Build completion candidates\nfrom return values]
SearchCompleterScript{Search PS_COMPLETE_PATH for .ps1 script}
RunCompletionScript[Run the completion script]
CompleterCache[(Completer Cahe)]
CompleterCache -.- SearchCache
CompleterCache -.- SearchCache2
RunCompleter ==> SearchCache
RunCompletionScript -.->|Register| CompleterCache
SearchCache ==>|Found| BuildCompletionCandidates
SearchCache ==>|Not found| SearchCompleterScript
SearchCompleterScript ==>|Found| RunCompletionScript
RunCompletionScript ==> SearchCache2
SearchCache2 ==>|Found| BuildCompletionCandidates
SearchCache2 ==>|Not found| BuildCompletionCandidates2
end
BuildCompletionCandidates ==> END
BuildCompletionCandidates2 ==> END
| Cmdlet | Description |
|---|---|
| New-CommandCompleter | Create a CommandCompleter object. |
| New-ParamCompleter | Create a parameter's completer. |
| New-ParamStyle | Create or get parameter style instance. |
| Register-NativeCompleter | Create and register a CommandCompleter object. |
| Unregister-NativeCompleter | Unregister the command completer. |
Write the definition of command completion using the Cmdlets above.
Edit: example1.ps1 in ${env:PS_COMPLETE_PATH}
Register-NativeCompleter -Name example1 -Parameters @(
# [-h, --help] -- Flag
New-ParamCompleter -ShortName h -LongName help -Description 'Display help'
# [-v, --version] -- Flag
New-ParamCompleter -ShortName v -LongName version -Description 'Display version'
# [--type {typeA|typeB|typeC}] -- Options that require an argument
New-ParamCompleter -LongName type -Description 'Select type' -Arguments @(
"typeA `tDescription A",
"typeB `tDescription B",
"typeC `tDescription C"
)
)Edit: example2.ps1 in ${env:PS_COMPLETE_PATH}
Register-NativeCompleter -Name example2 -SubCommands @(
# example2 add ...
New-CommandCompleter -Name add -Description -ArgumentCompleter {
param([int] $position, [int] $argumentIndex)
# ...
}
# example2 list ...
New-CommandCompleter -Name list -Description -Parameters @(
# [-a, --all] -- Flag
New-ParamCompleter -ShortName a -LongName all -Description 'Show all'
)
)Edit: git.ps1 in <profile directory>/completions
<#
.SYNOPSIS
Regsiter `git` command completer with `posh-git`
.DESCRIPTION
This script will be loaded by `NativeCommandCompleter.psm` poershell module.
.LINK
dahlbyk/posh-git: A PowerShell environment for Git
https://github.com/dahlbyk/posh-git
#>
param($wordToComplete, $commandAst, $cursorPosition)
Import-Module posh-git
# Reset the variable in the global scope
$global:GitPromptScriptBlock = $GitPromptScriptBlock
# The first time, generate the completion list manually
TabExpansion2 -inputScript $commandAst.ToString().PadRight($cursorPosition) `
-cursorColumn $cursorPosition `
| Select-Object -ExpandProperty CompletionMatchesThis code is not executed when PowerShell starts up and loads the profile.
It is loaded the first time tab completion for the git command is triggered.
Edit: dotnet.ps1 in <profile directory>/completions
<#
.SYNOPSIS
Regsiter `dotnet` command completer
.DESCRIPTION
This script will be loaded by `NativeCommandCompleter.psm` poershell module.
.LINK
How to enable tab completion for the .NET CLI
https://learn.microsoft.com/en-us/dotnet/core/tools/enable-tab-autocomplete
#>
param($wordToComplete, $commandAst, $cursorPosition)
Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
dotnet complete --position $cursorPosition $commandAst.ToString() | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
# The first time, generate the completion list manually
TabExpansion2 -inputScript $commandAst.ToString().PadRight($cursorPosition) `
-cursorColumn $cursorPosition `
| Select-Object -ExpandProperty CompletionMatches
The example and mechanism are almost identical to those of posh-git in Example 3.
The completion provided by NativeCommandCompleter.psm has a lower priority;
if a completion code with a specified command name is registered, completion will be performed using that code.
