2013-02-13 4 views
12

PowerShell 3.0のPowerShell関数またはGet-ServiceやGet-Processなどのコマンドレットのパラメータタブの補完はどのように実装しますか?PowerShellコマンドレットのパラメータ値タブの完了

私はValidateSetが既知のリストで動作することを認識していますが、必要に応じてリストを生成したいと思います。

Adam Driscoll hints that it is possibleのコマンドレットについては、残念ながら詳しくは触れていません。関数については、

Trevor Sullivan shows a techniqueですが、私が理解するように、彼のコードは関数が定義された時点でリストを生成します。

+0

ここにお読みください:http://www.powertheshell.com/dynamicargumentcompletion/ –

+0

いいえ、私はそれを見つけられませんでした。非常に有益な情報 –

+0

http://powertab.codeplexをご覧ください。com/itはpowershell v.2の「動的インテリジェンス」ですが、私はそれも3.0で大丈夫です –

答えて

2

古典的に、私は正規表現を使用。

例えば、

function TabExpansion { 

    param($line, $lastWord) 

    if ($line -match '(-(\w+))\s+([^-]*$)') 
    { 
    ### Resolve Command name & parameter name 
     $_param = $matches[2] + '*' 
     $_opt = $Matches[3].Split(" ,")[-1] + '*' 
     $_base = $Matches[3].Substring(0,$Matches[3].Length-$Matches[3].Split(" ,")[-1].length) 

     $_cmdlet = [regex]::Split($line, '[|;=]')[-1] 

     if ($_cmdlet -match '\{([^\{\}]*)$') 
     { 
      $_cmdlet = $matches[1] 
     } 

     if ($_cmdlet -match '\(([^()]*)$') 
     { 
      $_cmdlet = $matches[1] 
     } 

     $_cmdlet = $_cmdlet.Trim().Split()[0] 

     $_cmdlet = @(Get-Command -type 'Cmdlet,Alias,Function,Filter,ExternalScript' $_cmdlet)[0] 

     while ($_cmdlet.CommandType -eq 'alias') 
     { 
      $_cmdlet = @(Get-Command -type 'Cmdlet,Alias,Function,Filter,ExternalScript' $_cmdlet.Definition)[0] 
     } 

    ### Currently target is Get-Alias & "-Name" parameter 

     if ("Get-Alias" -eq $_cmdlet.Name -and "Name" -like $_param) 
     { 
      Get-Alias -Name $_opt | % { $_.Name } | sort | % { $_base + ($_ -replace '\s','` ') } 
      break; 
     } 
    } 
} 

リファレンス http://gallery.technet.microsoft.com/scriptcenter/005d8bc7-5163-4a25-ad0d-25cffa90faf5


ポッシュ-GitはGitTabExpansion.ps1にTabExpansionBackupにTabExpansionをリネーム。
そして、補完されたTabExpansionは、補完がgitコマンドと一致しないとき、元のTabExpansion(TabExpansionBackup)を呼び出します。
あなたがしなければならないことは、TabExpansionBackupを再定義することだけです。

(猫\ GitTabExpansion.ps1 |。-last選択18)
============================== GitTabExpansion .ps1という==============================

if (Test-Path Function:\TabExpansion) { 
    Rename-Item Function:\TabExpansion TabExpansionBackup 
} 

function TabExpansion($line, $lastWord) { 
    $lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart() 

    switch -regex ($lastBlock) { 
     # Execute git tab completion for all git-related commands 
     "^$(Get-AliasPattern git) (.*)" { GitTabExpansion $lastBlock } 
     "^$(Get-AliasPattern tgit) (.*)" { GitTabExpansion $lastBlock } 

     # Fall back on existing tab expansion 
     default { if (Test-Path Function:\TabExpansionBackup) { TabExpansionBackup $line $lastWord } } 
    } 
} 

=========== ========================================== ==================

再定義TabExpansionBackup(原TabExpansion)

function TabExpansionBackup { 
    ... 

    ### Resolve Command name & parameter name 

    ... 

    ### Currently target is Get-Alias & "-Name" parameter 

    ... 
} 
+0

私はposh-gitが既に私の環境でこの機能を定義しているのを見ています。既存の定義を拡張/サブクラス化する方法はありますか? –

7

私は同じことをしたいので、私はしばらくこれに戸惑いました。私は本当に満足しているものをまとめました。

DynamicParamからValidateSet属性を追加できます。ここでは、ValidateSetをXMLファイルからオンザフライで生成した例を示します。次のコードで「ValidateSetAttribute」を参照してください。それに

function Foo() { 
    [CmdletBinding()] 
    Param() 
    DynamicParam { 
     # 
     # The "modules" param 
     # 
     $modulesAttributeCollection = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute] 

     # [parameter(mandatory=..., 
     #  ... 
     #)] 
     $modulesParameterAttribute = new-object System.Management.Automation.ParameterAttribute 
     $modulesParameterAttribute.Mandatory = $true 
     $modulesParameterAttribute.HelpMessage = "Enter one or more module names, separated by commas" 
     $modulesAttributeCollection.Add($modulesParameterAttribute)  

     # [ValidateSet[(...)] 
     $moduleNames = @() 
     foreach($moduleXmlInfo in Select-Xml -Path "C:\Path\to\my\xmlFile.xml" -XPath "//enlistment[@name=""wp""]/module") { 
      $moduleNames += $moduleXmlInfo.Node.Attributes["name"].Value 
     } 
     $modulesValidateSetAttribute = New-Object -type System.Management.Automation.ValidateSetAttribute($moduleNames) 
     $modulesAttributeCollection.Add($modulesValidateSetAttribute) 

     # Remaining boilerplate 
     $modulesRuntimeDefinedParam = new-object -Type System.Management.Automation.RuntimeDefinedParameter("modules", [String[]], $modulesAttributeCollection) 

     $paramDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary 
     $paramDictionary.Add("modules", $modulesRuntimeDefinedParam) 
     return $paramDictionary 
    } 
    process { 
     # Do stuff 
    } 
} 

そのモジュールは、XMLファイルにあった場合、私は

Foo -modules M<press tab> 

、それは意志タブ完全な「MarcusModule」と入力することができます。さらに、私はXMLファイルを編集することができ、タブ補完の動作は直ちに変更されます。関数を再インポートする必要はありません。

+0

これは素晴らしいです。ありがとう。 – majkinetor

+0

http://stackoverflow.com/a/23001637/288393 –

関連する問題