为 Cmdlet 添加自定义参数完成器?
Add Custom Argument Completer for Cmdlet?
如何向 PowerShell Cmdlet 添加动态参数选项卡完成?
当我键入此内容并点击 tab
时,我希望它完成制表符。
PM> Paket-Add -NuGet FSharp.Co
这些是我想在此示例中使用的值:
PM> Paket-FindPackages -SearchText FSharp.Co
FSharp.Core
FSharp.Core.3
FSharp.Configuration
FSharp.Core.Fluent-3.1
FSharp.Core.Fluent-4.0
FSharp.Compiler.Tools
FSharp.Compatibility.Scala
FSharp.Compatibility.OCaml
FSharp.Compiler.CodeDom
FSharp.Compiler.Service
FSharp.Control.Reactive
FSharp.Compatibility.Haskell
FSharp.Compatibility.OCaml.Numerics
FSharp.Compatibility.OCaml.Format
FSharp.Compatibility.OCaml.System
FSharp.Collections.ParallelSeq
FSharp.Compatibility.StandardML
FSharp.Compatibility.OCaml.LexYacc
FSharp.Control.AsyncSeq
我发现 this answer 提供了几个有用的链接,我说我应该 运行 Get-Content function:TabExpansion2
:
看起来像CommandCompletion.CompleteInput needs to implemented. I thought I read somewhere that there is a Hashtable
of commands to functions. If so, where is it and how do I install custom ones? I'm using Chocolatey to distribute Paket.PowerShell. Here is the Cmdlet code。
2015-06-20 更新:
我最终让它与这里的代码一起工作:
https://github.com/fsprojects/Paket/blob/76de1c44853ce09029ba157855525f435d951b85/src/Paket.PowerShell/ArgumentTabCompletion.ps1
# https://github.com/mariuszwojcik/RabbitMQTools/blob/master/TabExpansions.ps1
function createCompletionResult([string]$text, [string]$value, [string]$tooltip) {
if ([string]::IsNullOrEmpty($value)) { return }
if ([string]::IsNullOrEmpty($text)) { $text = $value }
if ([string]::IsNullOrEmpty($tooltip)) { $tooltip = $value }
$completionText = @{$true="'$value'"; $false=$value }[$value -match "\W"]
$completionText = $completionText -replace '\[', '``[' -replace '\]', '``]'
New-Object System.Management.Automation.CompletionResult $completionText, $text, 'ParameterValue', $tooltip | write
}
$findPackages = {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Paket-FindPackages -SearchText $wordToComplete -Max 100 | % {
createCompletionResult $_ $_ $_ | write
}
}
$findPackageVersions = {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
if (-not $fakeBoundParameter.NuGet){ return }
Paket-FindPackageVersions -Name $fakeBoundParameter.NuGet -Max 100 | % {
createCompletionResult $_ $_ $_ | write
}
}
# create and add $global:options to the list of completers
# http://www.powertheshell.com/dynamicargumentcompletion/
if (-not $global:options) { $global:options = @{CustomArgumentCompleters = @{};NativeArgumentCompleters = @{}}}
$global:options['CustomArgumentCompleters']['Paket-Add:NuGet'] = $findPackages
$global:options['CustomArgumentCompleters']['Paket-Add:Version'] = $findPackageVersions
$function:tabexpansion2 = $function:tabexpansion2 -replace 'End\r\n{','End { if ($null -ne $options) { $options += $global:options} else {$options = $global:options}'
完整的参数名称很重要。重命名它们将使其不起作用。
这些被称为Dynamic parameters and are described in about_Functions_Advanced_Parameters。
The following example shows a sample function with standard
parameters named Name and Path, and an optional dynamic parameter
named DP1.The DP1 parameter is in the PSet1 parameter set and has a
type of Int32. The DP1 parameter is available in the Sample function
only when the value of the Path parameter contains "HKLM:", indicating
that it is being used in the HKEY_LOCAL_MACHINE registry drive.
function Get-Sample {
[CmdletBinding()]
Param ([String]$Name, [String]$Path)
DynamicParam
{
if ($path -match ".*HKLM.*:")
{
$attributes = new-object System.Management.Automation.ParameterAttribute
$attributes.ParameterSetName = "__AllParameterSets"
$attributes.Mandatory = $false
$attributeCollection = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$attributeCollection.Add($attributes)
$dynParam1 = new-object -Type System.Management.Automation.RuntimeDefinedParameter("dp1", [Int32], $attributeCollection)
$paramDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
$paramDictionary.Add("dp1", $dynParam1)
return $paramDictionary
}
}
}
Here's another example that does validation sets dynamically.
我重新阅读了您的问题,看起来您可能只需要一个静态的、预定义的特定参数的 Tab 完成值列表。如果是这样,那么您可以简单地 use the [ValidateSet()]
attribute:
function Get-Something {
[CmdletBinding()]
param(
[ValidateSet('One','Two','Three')]
[String]
$MyParam
)
}
但是如果这些值需要在运行时确定,那么请参阅上面关于动态参数的部分。
您可能需要查看 TabExpansion++ module,它旨在使扩展制表符补全更容易。
我刚玩了几分钟,根据示例,我想你想要这样的东西:
Import-Module TabExpansion++
function PaketAddNugetCompletion
{
[ArgumentCompleter(Parameter = 'Nuget', Command = 'Paket-Add')]
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Paket-FindPackages -SearchText $wordToComplete |
ForEach-Object {
# not quite sure what property to use off the result, but this might work.
New-CompletionResult -CompletionText $_
}
}
如何向 PowerShell Cmdlet 添加动态参数选项卡完成?
当我键入此内容并点击 tab
时,我希望它完成制表符。
PM> Paket-Add -NuGet FSharp.Co
这些是我想在此示例中使用的值:
PM> Paket-FindPackages -SearchText FSharp.Co
FSharp.Core
FSharp.Core.3
FSharp.Configuration
FSharp.Core.Fluent-3.1
FSharp.Core.Fluent-4.0
FSharp.Compiler.Tools
FSharp.Compatibility.Scala
FSharp.Compatibility.OCaml
FSharp.Compiler.CodeDom
FSharp.Compiler.Service
FSharp.Control.Reactive
FSharp.Compatibility.Haskell
FSharp.Compatibility.OCaml.Numerics
FSharp.Compatibility.OCaml.Format
FSharp.Compatibility.OCaml.System
FSharp.Collections.ParallelSeq
FSharp.Compatibility.StandardML
FSharp.Compatibility.OCaml.LexYacc
FSharp.Control.AsyncSeq
我发现 this answer 提供了几个有用的链接,我说我应该 运行 Get-Content function:TabExpansion2
:
看起来像CommandCompletion.CompleteInput needs to implemented. I thought I read somewhere that there is a Hashtable
of commands to functions. If so, where is it and how do I install custom ones? I'm using Chocolatey to distribute Paket.PowerShell. Here is the Cmdlet code。
2015-06-20 更新:
我最终让它与这里的代码一起工作: https://github.com/fsprojects/Paket/blob/76de1c44853ce09029ba157855525f435d951b85/src/Paket.PowerShell/ArgumentTabCompletion.ps1
# https://github.com/mariuszwojcik/RabbitMQTools/blob/master/TabExpansions.ps1
function createCompletionResult([string]$text, [string]$value, [string]$tooltip) {
if ([string]::IsNullOrEmpty($value)) { return }
if ([string]::IsNullOrEmpty($text)) { $text = $value }
if ([string]::IsNullOrEmpty($tooltip)) { $tooltip = $value }
$completionText = @{$true="'$value'"; $false=$value }[$value -match "\W"]
$completionText = $completionText -replace '\[', '``[' -replace '\]', '``]'
New-Object System.Management.Automation.CompletionResult $completionText, $text, 'ParameterValue', $tooltip | write
}
$findPackages = {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Paket-FindPackages -SearchText $wordToComplete -Max 100 | % {
createCompletionResult $_ $_ $_ | write
}
}
$findPackageVersions = {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
if (-not $fakeBoundParameter.NuGet){ return }
Paket-FindPackageVersions -Name $fakeBoundParameter.NuGet -Max 100 | % {
createCompletionResult $_ $_ $_ | write
}
}
# create and add $global:options to the list of completers
# http://www.powertheshell.com/dynamicargumentcompletion/
if (-not $global:options) { $global:options = @{CustomArgumentCompleters = @{};NativeArgumentCompleters = @{}}}
$global:options['CustomArgumentCompleters']['Paket-Add:NuGet'] = $findPackages
$global:options['CustomArgumentCompleters']['Paket-Add:Version'] = $findPackageVersions
$function:tabexpansion2 = $function:tabexpansion2 -replace 'End\r\n{','End { if ($null -ne $options) { $options += $global:options} else {$options = $global:options}'
完整的参数名称很重要。重命名它们将使其不起作用。
这些被称为Dynamic parameters and are described in about_Functions_Advanced_Parameters。
The following example shows a sample function with standard parameters named Name and Path, and an optional dynamic parameter named DP1.The DP1 parameter is in the PSet1 parameter set and has a type of Int32. The DP1 parameter is available in the Sample function only when the value of the Path parameter contains "HKLM:", indicating that it is being used in the HKEY_LOCAL_MACHINE registry drive.
function Get-Sample {
[CmdletBinding()]
Param ([String]$Name, [String]$Path)
DynamicParam
{
if ($path -match ".*HKLM.*:")
{
$attributes = new-object System.Management.Automation.ParameterAttribute
$attributes.ParameterSetName = "__AllParameterSets"
$attributes.Mandatory = $false
$attributeCollection = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$attributeCollection.Add($attributes)
$dynParam1 = new-object -Type System.Management.Automation.RuntimeDefinedParameter("dp1", [Int32], $attributeCollection)
$paramDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
$paramDictionary.Add("dp1", $dynParam1)
return $paramDictionary
}
}
}
Here's another example that does validation sets dynamically.
我重新阅读了您的问题,看起来您可能只需要一个静态的、预定义的特定参数的 Tab 完成值列表。如果是这样,那么您可以简单地 use the [ValidateSet()]
attribute:
function Get-Something {
[CmdletBinding()]
param(
[ValidateSet('One','Two','Three')]
[String]
$MyParam
)
}
但是如果这些值需要在运行时确定,那么请参阅上面关于动态参数的部分。
您可能需要查看 TabExpansion++ module,它旨在使扩展制表符补全更容易。
我刚玩了几分钟,根据示例,我想你想要这样的东西:
Import-Module TabExpansion++
function PaketAddNugetCompletion
{
[ArgumentCompleter(Parameter = 'Nuget', Command = 'Paket-Add')]
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Paket-FindPackages -SearchText $wordToComplete |
ForEach-Object {
# not quite sure what property to use off the result, but this might work.
New-CompletionResult -CompletionText $_
}
}