Skip to content

Instantly share code, notes, and snippets.

@CN-CODEGOD
Last active December 17, 2024 17:45
Show Gist options
  • Save CN-CODEGOD/2358dea6164fc608fbb110231f05d47c to your computer and use it in GitHub Desktop.
Save CN-CODEGOD/2358dea6164fc608fbb110231f05d47c to your computer and use it in GitHub Desktop.
powershell AUTO completion
1.The ValidateSet attribute specifies a set of valid values for a parameter or variable and enables tab completion. PowerShell generates an error if a parameter or variable value doesn't match a value in the set. In the following example, the value of the Fruit parameter can only be Apple, Banana, or Pear.
[ValidateSet('Apple', 'Banana', 'Pear')]
2.You can use a Class to dynamically generate the values for ValidateSet at runtime. In the following example, the valid values for the variable $Sound are generated via a Class named SoundNames that checks three filesystem paths for available sound files:
Class SoundNames : System.Management.Automation.IValidateSetValuesGenerator {
[string[]] GetValidValues() {
$SoundPaths = '/System/Library/Sounds/',
'/Library/Sounds',
'~/Library/Sounds'
$SoundNames = ForEach ($SoundPath in $SoundPaths) {
If (Test-Path $SoundPath) {
(Get-ChildItem $SoundPath).BaseName
}
}
return [string[]] $SoundNames
}
}
Param(
[ValidateSet([SoundNames])]
[string]$Sound
)
3.ArgumentCompletions attribute
The ArgumentCompletions attribute allows you to add tab completion values to a specific parameter. An ArgumentCompletions attribute must be defined for each parameter that needs tab completion. The ArgumentCompletions attribute is similar to ValidateSet. Both attributes take a list of values to be presented when the user presses Tab after the parameter name. However, unlike ValidateSet, the values are not validated and more like suggestions. Therefore the user can supply any value, not just the values in the list.
The ArgumentCompletions attribute should not be confused with the ArgumentCompleter attribute, which needs a scriptblock to define the options. the specified values are available
The syntax is as follows:
function Test-ArgumentCompletions {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ArgumentCompletions('Fruits', 'Vegetables')]
$Type,
[Parameter()]
[ArgumentCompletions('Apple', 'Banana', 'Orange')]
$Fruit,
[Parameter()]
[ArgumentCompletions('Onion', 'Carrot', 'Lettuce')]
$Vegetable
)
}
4.ArgumentCompleter attribute
The ArgumentCompleter attribute allows you to add tab completion values to a specific parameter. An ArgumentCompleter attribute must be defined for each parameter that needs tab completion.
To add an ArgumentCompleter attribute, you need to define a script block that determines the values. The script block must take the following parameters in the order specified below. The parameter's names don't matter as the values are provided positionally.
The syntax is as follows:
function MyArgumentCompleter{
param ( $commandName,
$parameterName,
$wordToComplete,
$commandAst,
$fakeBoundParameters )
$possibleValues = @{
Fruits = @('Apple', 'Orange', 'Banana')
Vegetables = @('Onion', 'Carrot', 'Lettuce')
}
if ($fakeBoundParameters.ContainsKey('Type')) {
$possibleValues[$fakeBoundParameters.Type] | Where-Object {
$_ -like "$wordToComplete*"
}
} else {
$possibleValues.Values | ForEach-Object {$_}
}
}
function Test-ArgumentCompleter {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ValidateSet('Fruits', 'Vegetables')]
$Type,
[Parameter(Mandatory=$true)]
[ArgumentCompleter({ MyArgumentCompleter @args })]
$Value
)
}
5.Class-based argument completers
Beginning in PowerShell 7.2, a new feature was added that allows you to define more generic implementations of parameterized argument completers.
By deriving from ArgumentCompleterAttribute, it's possible to create generic completers that can be reused, for example:
[DirectoryCompleter(ContainingFile="pswh.exe", Depth=2)]
[DateCompleter(WeekDay='Monday', From="LastYear")]
[GitCommits(Branch='release')]
class:
using namespace System.Collections
using namespace System.Collections.Generic
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
class NumberCompleter : IArgumentCompleter {
[int] $From
[int] $To
[int] $Step
NumberCompleter([int] $from, [int] $to, [int] $step) {
if ($from -gt $to) {
throw [ArgumentOutOfRangeException]::new("from")
}
$this.From = $from
$this.To = $to
$this.Step = $step -lt 1 ? 1 : $step
}
[IEnumerable[CompletionResult]] CompleteArgument(
[string] $CommandName,
[string] $parameterName,
[string] $wordToComplete,
[CommandAst] $commandAst,
[IDictionary] $fakeBoundParameters) {
$resultList = [List[CompletionResult]]::new()
$local:to = $this.To
$local:step = $this.Step
for ($i = $this.From; $i -lt $to; $i += $step) {
$resultList.Add([CompletionResult]::new($i.ToString()))
}
return $resultList
}
}
class NumberCompletionsAttribute : ArgumentCompleterAttribute, IArgumentCompleterFactory {
[int] $From
[int] $To
[int] $Step
NumberCompletionsAttribute([int] $from, [int] $to, [int] $step) {
$this.From = $from
$this.To = $to
$this.Step = $step
}
[IArgumentCompleter] Create() { return [NumberCompleter]::new($this.From, $this.To, $this.Step) }
}
usage:
function Add{
param(
[NumberCompletions(0, 100, 5)]
[int] $X,
[NumberCompletions(0, 100, 5)]
[int] $Y
)
$X + $Y
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment