Training Completers
Synopsis
Dynamic tab completion is great, but sometimes you just cannot determine legal values reliably, all by yourself. This is where the ability to "train" your completers comes in - that is, to either manually add values, or automagically learn from the user's input!
Description
There are fundamentally two ways to train your completers:
- Automatically, based on the input a command receives. This is designed for convenient use and can happen after validating the input (to prevent learning undesirable values).
- Manually, by adding them with the
Add-PSFTeppCompletioncommand.
No matter which way they are added, they can be combined with dynamic completion. Learned values can also be unlearned (see below).
Automatic Training
To enable automatic training of completers, three steps must be taken:
- The Completer must be configured for Auto-Training
- The Completer must be assigned via Attribute, not via command!
- The code must call
Update-PSFTeppCompletionwhen it wants to train input
Logically, Automatic Training cannot be combined with [PsfValidateSet(...)], as the validation would happen before the training, preventing new values from being accepted.
Example
Register-PSFTeppScriptblock -Name "alcohol.type" -ScriptBlock {
@{ Text = 'Beer'; ToolTip = 'Elixir of the gods'}
@{ Text = 'Mead'; ToolTip = 'Elixir of the angry gods' }
@{ Text = 'Whiskey'; ToolTip = 'Unleash the Irishman in you!' }
@{ Text = 'Wine'; ToolTip = 'For the discriminating somelier' }
@{ Text = 'Vodka'; ToolTip = 'Beware, before it is too late' }
@{ Text = 'Rum (3y)'; ToolTip = 'Barkeepers Delight' }
@{ Text = 'Rum (5y)'; ToolTip = 'Well aged, combines well' }
@{ Text = 'Rum (7y)'; ToolTip = 'Oldtimer, use for cocktails that need some character' }
} -AutoTraining
function Get-Alcohol {
[CmdletBinding()]
Param (
[PsfArgumentCompleter('alcohol.type')]
[string]
$Type,
[string]
$Unit = "Pitcher"
)
if ($Type -eq 'Kölsch') { throw "Would go bad before serving!" }
Update-PSFTeppCompletion
Write-Host "Drinking a $Unit of $Type"
}
With this, the command comes with a few pre-defined beverages it can complete:
Get-Alcohol -Type <TAB>
But now when we provide a new value:
Get-Alcohol -Type Mojito
It will now also offer the new value (however without a friendly tooltip):
Get-Alcohol -Type <TAB>
Manual Training
Manual Training requires no particular configuration and allows assignment via command or attribute. It also allows adding tooltips to your completion. Finally, it can be applied to any completer defined, including those configured for Automatic Training.
Example
Register-PSFTeppScriptblock -Name "alcohol.type" -ScriptBlock {
@{ Text = 'Beer'; ToolTip = 'Elixir of the gods'}
@{ Text = 'Mead'; ToolTip = 'Elixir of the angry gods' }
@{ Text = 'Whiskey'; ToolTip = 'Unleash the Irishman in you!' }
@{ Text = 'Wine'; ToolTip = 'For the discriminating somelier' }
@{ Text = 'Vodka'; ToolTip = 'Beware, before it is too late' }
@{ Text = 'Rum (3y)'; ToolTip = 'Barkeepers Delight' }
@{ Text = 'Rum (5y)'; ToolTip = 'Well aged, combines well' }
@{ Text = 'Rum (7y)'; ToolTip = 'Oldtimer, use for cocktails that need some character' }
}
function Get-Alcohol {
[CmdletBinding()]
Param (
[string]
$Type,
[string]
$Unit = "Pitcher"
)
if ($Type -eq 'Kölsch') { throw "Would go bad before serving!" }
Add-PSFTeppCompletion -Name alcohol.type -Options $Type
Write-Host "Drinking a $Unit of $Type"
}
# Add some completion
Add-PSFTeppCompletion -Name alcohol.type -Options @{ Text = 'Margarita'; Tooltip = 'A proper Mexican' }
# Actually assign the completion to the command
Register-PSFTeppArgumentCompleter -Command Get-Alcohol -Parameter Type -Name 'alcohol.type'
With this, we can now complete the alcohol types with the ones calculated by the scriptblock, plus the one we predefined:
Get-Alcohol -Type <TAB>
But now when we provide a new value:
Get-Alcohol -Type Mojito
It will now also offer the new value (however without a friendly tooltip):
Get-Alcohol -Type <TAB>
Managing Learned Values
There are two commands that can be used to interact with the learned values:
Get-PSFTeppCompletionto see what has been learnedRemove-PSFTeppCompletionto remove an undesired value from the list of trained values.
Example
# List Currently trained values
Get-PSFTeppCompletion -Name alcohol.type
Completion Text
---------- ----
alcohol.type Mojito
alcohol.type Margarita
# Remove all currently trained values
Get-PSFTeppCompletion -Name alcohol.type | Remove-PSFTeppCompletion
Persisting learned completions across sessions
PSFramework Tab Completion does not offer a direct feature to persist the trained completions across sessions.
This can be implemented on your own however, using a combination of Get-PSFTeppCompletion, Export-PSFClixml, Import-PSFClixml and Add-PSFTeppCompletion.
If you wish to implement this, be sure to do so responsibly in regards to secrets or sensitive data. Also consider aging entries.