NativeCommandCompletion/NativeCommandCompletion.psm1
class NativeCommandCompletionResult : System.Management.Automation.CompletionResult { [string]$TextType NativeCommandCompletionResult( [string]$CompletionText, [string]$ListItemText, [System.Management.Automation.CompletionResultType]$ResultType, [string]$ToolTip, [string]$TextType) : base($CompletionText, $ListItemText, $ResultType, $ToolTip) { $this.TextType = $TextType } } $nativeCommandCompleters = @{} function New-CompletionResult { [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter(Mandatory)] [string]$CompletionText, [string]$TextType, [string]$ToolTip = $CompletionText, [string]$ListItemText = $CompletionText, [System.Management.Automation.CompletionResultType]$ResultType ) if (!$ResultType) { if ($CompletionText.StartsWith('-')) { $ResultType = [System.Management.Automation.CompletionResultType]::ParameterName } elseif ($TextType -like '*Command') { $ResultType = [System.Management.Automation.CompletionResultType]::Command } else { $ResultType = [System.Management.Automation.CompletionResultType]::Text } } if ($Force -or $pscmdlet.ShouldProcess($CompletionText, "Add new completion result")) { New-Object NativeCommandCompletionResult $CompletionText, $ListItemText, $ResultType, $ToolTip, $TextType } } Set-Alias -Name COMPGEN -Value New-CompletionResult function Register-Completer { param ( [Parameter(Mandatory)] [string]$Name, $Completer, [Alias('Option')] $Parameter ) if (!$nativeCommandCompleters.ContainsKey($Name)) { $nativeCommandCompleters[$Name] = @{} } if ($Completer) { $nativeCommandCompleters[$Name].completer = $Completer } if ($Parameter) { $nativeCommandCompleters[$Name].parameter = $Parameter } } function Get-Completer { param ( [Parameter(Mandatory)] [string]$Name, [Alias('Option')] [switch]$Parameter ) if ($Parameter) { $nativeCommandCompleters[$Name].parameter } else { $nativeCommandCompleters[$Name].completer } } function Invoke-Completer { param ( [Parameter(Mandatory, Position = 0)] [string]$Name, [Alias('Option')] [switch]$Parameter, [Object[]]$ArgumentList ) if ($Parameter.IsPresent) { $cmpltr = $nativeCommandCompleters[$Name].parameter } else { $cmpltr = $nativeCommandCompleters[$Name].completer } if ($cmpltr -is [scriptblock]) { $cmpltr = Invoke-Command -ScriptBlock $cmpltr -ArgumentList $ArgumentList } foreach ($c in $cmpltr) { if ($c -is [NativeCommandCompletionResult]) { $c } else { New-CompletionResult -CompletionText $c -TextType Text -ResultType ([System.Management.Automation.CompletionResultType]::Text) -Force } } } function Register-NativeCommandArgumentCompleter { param ( [Parameter(Mandatory)] [string] $CommandName, [Parameter(Mandatory)] [scriptblock] $ScriptBlock ) $script = $ScriptBlock $CommandName, (Get-Alias -Definition $CommandName -ErrorAction Ignore).Name | ForEach-Object { if ($_) { Register-ArgumentCompleter -CommandName $_ -ScriptBlock $script -Native } } } |