主要問題
我的問題是是否可以使用哈希表優化函式的創建和后續的自動完成設定。
我想優化的功能,例如使用ForEach下面的哈希表:
Function wu([string]$PackageName) {winget upgrade --include-unknown $PackageName}
Function wui([string]$PackageName) {winget upgrade -i $PackageName}
Function wi([string]$PackageName) {winget install $PackageName}
Function wii([string]$PackageName) {winget install -i -e $PackageName}
Function ws([string]$PackageName) {winget search $PackageName}
我已調整的后續自動完成設定-CommandName以及我創建"$Local:ast".Replace('wu ', 'winget upgrade ')"的wu功能需要針對Function上述所有其他設定進行調整。原始自動完成的來源是https://github.com/microsoft/winget-cli/blob/master/doc/Completion.md
據我了解,我需要為每個Function. 我也想通過ForEach呼叫來優化它:
Register-ArgumentCompleter -Native -CommandName wu -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
[Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()
$Local:word = $wordToComplete.Replace('"', '""')
$Local:ast = $commandAst.ToString().Replace('"', '""')
winget complete --word="$Local:word" --commandline "$Local:ast".Replace('wu ', 'winget upgrade ') --position $cursorPosition | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
這是我創建的哈希表,我無法正確使用它們來創建Functions 和自動完成配置:
$functions = @{
"wu" = "winget upgrade --include-unknown";
"wui" = "winget upgrade -i -e";
"wi" = "winget install -i";
"wii" = "winget install -i -e";
"ws" = "winget search"
}
我嘗試了類似的方法來創建函式,但它沒有評估運算式:
ForEach($item in $functions.keys) {
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("Function $item ([string]$PackageName) {$($functions[$item])}")
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
第二個問題(已回答)
我仍然有兩個用于自動完成部分的代碼塊。一個用于原始winget命令(使用-CommandName wingetand --commandline "$Local:ast"),一個用于我的哈希表命令(使用-CommandName $funcNameand --commandline "$Local:new_ast"。我可以將它們巧妙地組合成一個代碼塊:
# Hashtable autocomplete configuration
foreach($funcName in $functions.PSBase.Keys){
Register-ArgumentCompleter -Native -CommandName $funcName -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
[Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()
$Local:word = $wordToComplete.Replace('"', '""')
$Local:ast = $commandAst.ToString().Replace('"', '""')
$Local:new_ast = $Local:ast -replace '^w[uis]{1,2}\b', {
if($functions.ContainsKey($_.Value)){ return $functions[$_.Value] } return $_.Value
}
winget complete --word="$Local:word" --commandline "$Local:new_ast" --position $cursorPosition | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
}
# Original autocomplete configuration
Register-ArgumentCompleter -Native -CommandName winget -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
[Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()
$Local:word = $wordToComplete.Replace('"', '""')
$Local:ast = $commandAst.ToString().Replace('"', '""')
winget complete --word="$Local:word" --commandline "$Local:ast" --position $cursorPosition | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
我認為這樣的事情可能會起作用,因為winget正則運算式會忽略它,因為它不在函式哈希表中。但我無法弄清楚語法,因為型別是KeyCollection:
foreach($funcName in $($functions.PSBase.Keys @{'winget'}))
回答
$PROFILE感謝@mathias-r-jessen完成的結果:
$functions = @{
"wu" = "winget upgrade --include-unknown";
"wui" = "winget upgrade -i -e";
"wi" = "winget install -i";
"wii" = "winget install -i -e";
"ws" = "winget search"
}
foreach($funcName in $functions.PSBase.Keys){
New-Item function:\ -Name $funcName -Value $([scriptblock]::Create($functions[$funcName])) | Out-Null
}
foreach($funcName in @($functions.PSBase.Keys; 'winget')){
Register-ArgumentCompleter -Native -CommandName $funcName -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
[Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new()
$Local:word = $wordToComplete.Replace('"', '""')
$Local:ast = $commandAst.ToString().Replace('"', '""')
$Local:new_ast = $Local:ast -replace '^w[uis]{1,2}\b', {
if($functions.ContainsKey($_.Value)){ return $functions[$_.Value] } return $_.Value
}
winget complete --word="$Local:word" --commandline "$Local:new_ast" --position $cursorPosition | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
}
uj5u.com熱心網友回復:
以編程方式注冊函式就像在functions:驅動器中創建新專案一樣簡單:
$functions = @{
"wu" = "winget upgrade --include-unknown";
"wui" = "winget upgrade -i -e";
"wi" = "winget install -i";
"wii" = "winget install -i -e";
"ws" = "winget search"
}
foreach($funcName in $functions.PSBase.Keys){
New-Item function:\ -Name $funcName -Value $functions[$funcName]
}
這將使用鍵作為函式名注冊表中的所有鍵值條目,并將值作為函式體的源代碼。
確保在全域范圍內執行此代碼(即,通過從組態檔腳本呼叫注冊代碼或顯式匯出生成的函式(如果是模塊的一部分))。
對于引數完成者,使用-replace搜索以 開頭的任何 2 或 3 字母單詞w,然后使用腳本塊作為匹配評估器來查找正確的翻譯:
$functions = @{
"wu" = "winget upgrade --include-unknown";
"wui" = "winget upgrade -i -e";
"wi" = "winget install -i";
"wii" = "winget install -i -e";
"ws" = "winget search"
}
$commandLine = 'wu somePackage'
$commandLine -replace '^w[uis]{1,2}\b', {
if($functions.ContainsKey($_.Value)){
return $functions[$_.Value]
}
return $_.Value
}
$translated現在保存字串值"winget upgrade --include-unknown somePackage"
在 6.1 之前的 PowerShell 版本中,您可以通過直接呼叫來實作相同的目的[regex]::Replace():
$functions = @{
"wu" = "winget upgrade --include-unknown";
"wui" = "winget upgrade -i -e";
"wi" = "winget install -i";
"wii" = "winget install -i -e";
"ws" = "winget search"
}
$commandLine = 'wu somePackage'
$translated = [regex]::Replace($commandLine, '^w[uis]{1,2}\b', {
param($match)
if($functions.ContainsKey($match.Value)){
return $functions[$match.Value]
}
return $match.Value
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/478634.html
標籤:电源外壳 功能 哈希表 powershell-7.0
