Building PowerShell auto-completion using TabExpansionPlusPlus – Advanced – Part 2


In this series of blog posts, we discuss some more advanced topics relating to “argument completion”.

Previous blog post covered supporting the parameter context and improving performance using argument caching.

Providing TabExpansionPlusPlus support in your own modules

It is possible to provide argument completion for your own modules (and other) using the TabExpansionPlusPlus module.
Here’s some code on how you could hook in from your own module.

Code from <yourModule>.psm1:

# Providing TabExpansionPlusPlus support
Write-Verbose -Message 'Loading support for TabExpansionPlusPlus'

if(Get-Module -Name TabExpansionPlusPlus -ListAvailable)

{ Invoke-Expression -Command "$((Get-Module –Name <yourModule> -ListAvailable).ModuleBase)\<yourModule>.ArgumentCompleters.ps1" }

Troubleshooting custom argument completers

Debugging a custom completer can be a little confusing.
One simple way to debug is to set a line breakpoint in your custom completer and then call TabExpansion2 explicitly.

Here is an example:

PS> set-PSBreakpoint –Script .\HotFix.ArgumentCompleters.ps1 -line 62

PS> $Line = 'Get-HotFix –Id '

PS> TabExpansion2 -inputScript $Line -cursorColumn $Line.Length

Hit Line breakpoint on 'Microsoft.PowerShell.Core.ArgumentCompleters.ps1:62'

Using built-in TabExpansionPlusPlus ISE code snippets

Included in the module TabExpansionPlusPlus (v1.1) – based on contributions from the Dutch PowerShell MVP Bartosz Bielawski – are code snippets from building argument completers.

Once you import the code snippet in the ISE, the magic lights up…

PS> Import-IseSnippet -Module TabExpansionPlusPlus –ListAvailable

image_thumb[4]

Creating argument completers is now accelerated…

image_thumb[2]

I have also provided some extra extensions which are only available on GitHub for now here.

image
Unfortunately, in the recent updated version 1.2, these ISE snippets were missed, but you can still find them here.
Just copy the Snippets folder in the TabExpansionPlusPlus module folder.
image

Being independent of TabExpansionPlusPlus

So, you want to have no dependency on an external module like TabExpansionPlusPlus?  And also give up all the additional argument completers for those many modules it provides, including the argument caching mechanism, etc…
But yes, it is possible…

All you will need to create is an additional helper function to provide the “completion results”.

And as you probably remember, writing custom argument completers consists out of following steps:

  • Step 0 – Provide a helper function to build argument completion results
  • Step 1 – Create an “Argument Completer” function/scriptblock (that will provide the list of valid argument list).
  • Step 2 – Register the “Argument Completer” for the command with the specific parameter using the above function/scriptblock.

Step 0 – Provide a helper function to build argument completion results

By creating the helper function New-CompletionResult (see below), you can remove the dependency on the external PowerShell module TabExpansionPlusPlus.
This function is responsible for building the list of argument completions/results.

# Helper function to create argument completion results
function New-CompletionResult
{
    param(
        [Parameter(Mandatory)]
        [string]$CompletionText,
        [string]$ListItemText = $CompletionText,
        [System.Management.Automation.CompletionResultType]$CompletionResultType = [System.Management.Automation.CompletionResultType]::ParameterValue,
        [string]$ToolTip = $CompletionText
    )
    New-Object System.Management.Automation.CompletionResult $CompletionText, $ListItemText, $CompletionResultType, $ToolTip

Step 1 – Create Argument Completer

This function (or scriptblock) will be invoked every time that auto-completion is invoked.

function VerbCompletion
{     
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)     
   
    Get-Verb –Verb "$wordToComplete*" | ForEach-Object { New-CompletionResult -CompletionText $_.Verb -ToolTip ("Group: " + $_.Group) }
}

Step 2 – Register Argument Completer

This command registers your custom argument completer function with the appropriate PowerShell commands and parameters.
The cmdlet Register-ArgumentCompleter is built-in starting from PowerShell version 5 and so does no longer require the external PowerShell module TabExpansionPlusPlus.

IMPORTANT: The only gotcha is that the cmdlet does not have a parameter -Description.
So remove that from any existing code.

Register-ArgumentCompleter `

        -CommandName Get-Verb `

        -Parameter Verb `

        -ScriptBlock $function:VerbCompletion `

        -Description 'This argument completer handles the -Verb parameter of the Get-Verb command.'

Hope this helps…

Advertisements