Release v0.2.4

- Implement the completion script for PowerShell
- Add global options to zsh completion script
This commit is contained in:
Evan Fiordeliso 2023-11-13 19:08:01 -05:00
commit 1fbc94aa49
5 changed files with 114 additions and 6 deletions

View File

@ -9,11 +9,82 @@ import (
func WritePowerShellCompletions(out io.Writer, rootCmd *Command) error { func WritePowerShellCompletions(out io.Writer, rootCmd *Command) error {
return powerShellTpl.Execute(out, map[string]any{ return powerShellTpl.Execute(out, map[string]any{
"rootCmd": rootCmd, "RootCmd": rootCmd,
"globalOpts": opt.Globals(), "GlobalOpts": opt.Globals(),
}) })
} }
var powerShellTpl = template.Must(template.New("PowerShell").Parse(` var powerShellTpl = template.Must(template.New("PowerShell").Funcs(tplFuncs).Parse(`
{{- $rootCmd := .RootCmd -}}
{{- $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
)
$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
`)) `))

View File

@ -38,9 +38,13 @@ var zshTpl = template.Must(template.New("zsh").Funcs(tplFuncs).Parse(`
_arguments _arguments
{{- end -}} {{- end -}}
{{- range .Cmd.Opts -}} {{- range .Cmd.Opts -}}
{{ " " }}\ {{- if ne .Name ""}} \
'--{{ .Name }}[{{ .Description }}]'
{{- end }}
{{- if ne .ShortName ""}} \
'-{{ .ShortName }}[{{ .Description }}]' '-{{ .ShortName }}[{{ .Description }}]'
{{- end }} {{- end }}
{{- end }}
{{- if gt (len .Cmd.Subcommands) 0 -}} {{- if gt (len .Cmd.Subcommands) 0 -}}
{{ " " }}\ {{ " " }}\
'1: :{_describe 'command' {{ $varPrefix }}commands}' \ '1: :{_describe 'command' {{ $varPrefix }}commands}' \
@ -63,6 +67,18 @@ var zshTpl = template.Must(template.New("zsh").Funcs(tplFuncs).Parse(`
function _{{ $varName }} { function _{{ $varName }} {
{{ template "cmd" (map "Cmd" .RootCmd) -}} {{ template "cmd" (map "Cmd" .RootCmd) -}}
{{- if gt (len .GlobalOpts) 0 }}
_arguments
{{- range .GlobalOpts -}}
{{- if ne .Name ""}} \
'--{{ .Name }}[{{ .Description }}]'
{{- end }}
{{- if ne .ShortName ""}} \
'-{{ .ShortName }}[{{ .Description }}]'
{{- end }}
{{- end }}
{{- end }}
} }
compdef _{{ $varName }} {{ $progName }} compdef _{{ $varName }} {{ $progName }}

2
go.mod
View File

@ -1,3 +1,5 @@
module go.fifitido.net/cmd module go.fifitido.net/cmd
go 1.21.3 go 1.21.3
require github.com/iancoleman/strcase v0.3.0

2
go.sum
View File

@ -0,0 +1,2 @@
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=

View File

@ -4,11 +4,14 @@ import (
"fmt" "fmt"
"strings" "strings"
"text/template" "text/template"
"github.com/iancoleman/strcase"
) )
var tplFuncs = template.FuncMap{ var tplFuncs = template.FuncMap{
"map": tplMap, "map": tplMap,
"cat": tplCat, "cat": tplCat,
"split": tplSplit,
"join": tplJoin, "join": tplJoin,
"under": tplUnder, "under": tplUnder,
"varPrefix": tplVarPrefix, "varPrefix": tplVarPrefix,
@ -19,6 +22,8 @@ var tplFuncs = template.FuncMap{
"sub": tplSub, "sub": tplSub,
"dec": tplDec, "dec": tplDec,
"mult": tplMult, "mult": tplMult,
"pascal": tplPascal,
"camel": tplCamel,
} }
func tplMap(vals ...any) (map[string]any, error) { func tplMap(vals ...any) (map[string]any, error) {
@ -37,12 +42,16 @@ func tplCat(strs ...string) string {
return strings.Join(strs, "") return strings.Join(strs, "")
} }
func tplSplit(s string, sep string) []string {
return strings.Split(s, sep)
}
func tplJoin(strs []string, sep string) string { func tplJoin(strs []string, sep string) string {
return strings.Join(strs, sep) return strings.Join(strs, sep)
} }
func tplUnder(s string) string { func tplUnder(s string) string {
return strings.ToLower(strings.ReplaceAll(strings.ReplaceAll(s, " ", "_"), "-", "_")) return strcase.ToSnake(s)
} }
func tplVarPrefix(s string) string { func tplVarPrefix(s string) string {
@ -80,3 +89,11 @@ func tplDec(i int) int {
func tplMult(a, b int) int { func tplMult(a, b int) int {
return a * b return a * b
} }
func tplPascal(s string) string {
return strcase.ToCamel(s)
}
func tplCamel(s string) string {
return strcase.ToLowerCamel(s)
}