From ba90879ff0ea161098f8fd34bb46db64cd7fcda4 Mon Sep 17 00:00:00 2001 From: Evan Fiordeliso Date: Mon, 13 Nov 2023 18:37:37 -0500 Subject: [PATCH] Add powershell completions implementation --- completions_powershell.go | 65 +++++++++++++++++++++++++++++++++++++-- tpl_funcs.go | 5 +++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/completions_powershell.go b/completions_powershell.go index 3c4cf4b..ea55e56 100644 --- a/completions_powershell.go +++ b/completions_powershell.go @@ -19,12 +19,71 @@ var powerShellTpl = template.Must(template.New("PowerShell").Funcs(tplFuncs).Par {{- $progName := $rootCmd.Name -}} {{- $varName := $rootCmd.Name | camel -}} +{{- define "cmd" -}} +{{- $progName := .ProgName -}} +{{- if .Cmd.IsRoot }} +{{- /**/}} '{{ $progName }}' { +{{- else }} +{{- /**/}} '{{ $progName }};{{ join (split .Cmd.CommandPath " ") ";" }}' { +{{- end -}} +{{- range .Cmd.Opts -}} +{{ if ne .Name "" }} + [CompletionResult]::new('--{{ .Name }}', '{{ .Name }}', [CompletionResultType]::ParameterName, '{{ .Description }}') +{{- end -}} +{{- if ne .ShortName "" }} + [CompletionResult]::new('-{{ .ShortName }}', '{{ .ShortName }}', [CompletionResultType]::ParameterName, '{{ .Description }}') +{{- end -}} +{{- end }} +{{- range .Cmd.Subcommands }} + [CompletionResult]::new('{{ .Name }}', '{{ .Name }}', [CompletionResultType]::ParameterValue, '{{ .ShortDescription }}') +{{- end }} + break; + } +{{- range .Cmd.Subcommands }} +{{ template "cmd" (map "Cmd" . "ProgName" $progName) }} +{{- end -}} +{{- end -}} +using namespace System.Management.Automation +using namespace System.Management.Automation.Language + [scriptblock]$__{{ $varName }}CompleterBlock = { param( - $WordToComplete, - $CommandAst, - $CursorPosition + $wordToComplete, + $commandAst, + $cursorPosition ) + + $commandElements + $command = @( + '{{ $progName }}' + for ($i = 1; $i -lt $commandElements.Count; $i++) { + $element = $commandElements[$i] + if ($element -isnot [StringConstantExpressionAst] -or + $element.StringConstantType -ne [StringConstantType]::BareWord -or + $element.Value.StartsWith('-') -or + $element.Value -eq $wordToComplete) { + break + } + $element.Value + } + ) -join ';' + + $completions = @( + switch ($command) { +{{ template "cmd" (map "Cmd" $rootCmd "ProgName" $progName) }} + } +{{- range .GlobalOpts -}} +{{- if ne .Name "" }} + [CompletionResult]::new('--{{ .Name }}', '{{ .Name }}', [CompletionResultType]::ParameterName, '{{ .Description }}') +{{- end -}} +{{- if ne .ShortName "" }} + [CompletionResult]::new('-{{ .ShortName }}', '{{ .ShortName }}', [CompletionResultType]::ParameterName, '{{ .Description }}') +{{- end -}} +{{- end -}} + ) + + $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | + Sort-Object -Property ListItemText } Register-ArgumentCompleter -CommandName {{ $progName }} -ScriptBlock $__{{ $varName }}CompleterBlock diff --git a/tpl_funcs.go b/tpl_funcs.go index db95e70..ab29b83 100644 --- a/tpl_funcs.go +++ b/tpl_funcs.go @@ -11,6 +11,7 @@ import ( var tplFuncs = template.FuncMap{ "map": tplMap, "cat": tplCat, + "split": tplSplit, "join": tplJoin, "under": tplUnder, "varPrefix": tplVarPrefix, @@ -41,6 +42,10 @@ func tplCat(strs ...string) string { return strings.Join(strs, "") } +func tplSplit(s string, sep string) []string { + return strings.Split(s, sep) +} + func tplJoin(strs []string, sep string) string { return strings.Join(strs, sep) }