17

Does anyone have an example showing how to override the TabExpansion2 function in Windows PowerShell 3.0? I know how to override the old TabExpansion function, but I want to provide a list of items for the intellisense in PowerShell ISE. I looked at the definition of TabExpansion2 and it wasn't easily understandable how I inject my own code in the the tab expansion process.

Michael Kelley
  • 3,579
  • 4
  • 37
  • 41

2 Answers2

16

I think this example should give you a good starting point: Windows Powershell Cookbook: Sample implementation of TabExpansion2. The example code shows that you can add code both before and after the default calls to [CommandCompletion]::CompleteInput.

For instance, you can add an entry to the $options hashtable named CustomArgumentCompleters to get custom completion for command arguments. The entry should be a hashtable where the keys are argument names (e.g. "ComputerName" or "Get-ChildItem:Filter") and the values are arrays of values that could be used to complete that parameter. Powertheshell.com also has an article about this: Dynamic Argument Completion. You can also specify custom completions for native executables, using the NativeArgumentCompleters option (again, keys are command names and values are arrays of possible completions).

OnceCompleteInput has returned, you can store the result in $result for further analysis. The result is an instance of the CommandCompletion class. If the default completion didn't find any matches, you can add your own CompletionResult entries to the list of matches:

$result.CompletionMatches.Add(
   (New-Object Management.Automation.CompletionResult "my completion string") )

Don't forget to return $result from the function so the completion actually happens.

Finally, a note on troubleshooting: the code that calls TabCompletion2 seems to squelch all console-based output (not surprisingly), so if you want to write debugging messages for yourself, you might try writing them to a separate text file. For instance, you could change the End function in TabCompletion2 to look like this:

$result = [System.Management.Automation.CommandCompletion]::CompleteInput(
    $inputScript, $cursorColumn, $options)
$result | Get-Member | Add-Content "c:\TabCompletionLog.txt"
$result
Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Charlie
  • 44,214
  • 4
  • 43
  • 69
  • Is this documented anywhere formally? How did this information originally get out? –  Apr 22 '13 at 17:33
  • 1
    Sadly I haven't seen any formal documentation, but I'd love to see it if it exists. – Charlie Apr 22 '13 at 19:11
12

Here is an example of overridden TabExpansion2 - TabExpansion2.ps1 (disclaimer: I'm the author) and several used-in-practice profiles with completers for it:

The points of interest:

  • TabExpansion2.ps1 does minimum work on loading. Potentially expensive initialization is performed once when completion really happens.
  • Overridden TabExpansion2 provides extension mechanism via one or more profiles *ArgumentCompleters.ps1 in the path. Profiles are invoked once on the first call of TabExpansion2. Several profiles may come with different independent modules, tools, and etc. and used simultaneously.
  • In addition to standard custom argument completers and native argument completers this custom TabExpansion2 supports result processors which tweak the results from the built-in completion and input processors which can intercept and replace the built-in completion.
  • It works around read only empty built-in results in some cases.
  • ArgumentCompleters.ps1 contains an example of an input processor witch replaces the built-in completion of types and namespaces with an alternative, more useful sometimes.
  • Another completer provides completion in comments: help tags (.Synopsis, .Description, etc.) and completion of commented out code, why not?
Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Roman Kuzmin
  • 40,627
  • 11
  • 95
  • 117