From 2b6ea89c9e01f390860e41d6e28d2c02dea9c632 Mon Sep 17 00:00:00 2001 From: Ethan Dickson Date: Thu, 15 Aug 2024 05:50:20 +0000 Subject: [PATCH] handle completions with spaces + case insensitive enums --- completion/bash.go | 18 +++++++++--------- completion/powershell.go | 2 +- completion/zsh.go | 2 +- option.go | 2 +- values.go | 15 ++++++++------- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/completion/bash.go b/completion/bash.go index 8e3a1b1..14282eb 100644 --- a/completion/bash.go +++ b/completion/bash.go @@ -43,19 +43,19 @@ func (b *bash) ProgramName() string { const bashCompletionTemplate = ` _generate_{{.Name}}_completions() { - # Capture the line excluding the command, and everything after the current word local args=("${COMP_WORDS[@]:1:COMP_CWORD}") - # Set COMPLETION_MODE and call the command with the arguments, capturing the output - local completions=$(COMPLETION_MODE=1 "{{.Name}}" "${args[@]}") + declare -a output + mapfile -t output < <(COMPLETION_MODE=1 "{{.Name}}" "${args[@]}") - # Use the command's output to generate completions for the current word - COMPREPLY=($(compgen -W "$completions" -- "${COMP_WORDS[COMP_CWORD]}")) + declare -a completions + mapfile -t completions < <( compgen -W "$(printf '%q ' "${output[@]}")" -- "$2" ) - # Ensure no files are shown, even if there are no matches - if [ ${#COMPREPLY[@]} -eq 0 ]; then - COMPREPLY=() - fi + local comp + COMPREPLY=() + for comp in "${completions[@]}"; do + COMPREPLY+=("$(printf "%q" "$comp")") + done } # Setup Bash to use the function for completions for '{{.Name}}' complete -F _generate_{{.Name}}_completions {{.Name}} diff --git a/completion/powershell.go b/completion/powershell.go index b002065..cc083bd 100644 --- a/completion/powershell.go +++ b/completion/powershell.go @@ -80,7 +80,7 @@ $_{{.Name}}_completions = { Invoke-Expression $Command | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { "$_" | _{{.Name}}_escapeStringWithSpecialChars } - rm env:COMPLETION_MODE + $env:COMPLETION_MODE = '' } Register-ArgumentCompleter -CommandName {{.Name}} -ScriptBlock $_{{.Name}}_completions ` diff --git a/completion/zsh.go b/completion/zsh.go index 831dc65..b2793b0 100644 --- a/completion/zsh.go +++ b/completion/zsh.go @@ -42,7 +42,7 @@ const zshCompletionTemplate = ` _{{.Name}}_completions() { local -a args completions args=("${words[@]:1:$#words}") - completions=($(COMPLETION_MODE=1 "{{.Name}}" "${args[@]}")) + completions=(${(f)"$(COMPLETION_MODE=1 "{{.Name}}" "${args[@]}")"}) compadd -a completions } compdef _{{.Name}}_completions {{.Name}} diff --git a/option.go b/option.go index fccc67e..2780fc6 100644 --- a/option.go +++ b/option.go @@ -352,7 +352,7 @@ func (optSet OptionSet) ByFlag(flag string) *Option { } for i := range optSet { opt := &optSet[i] - if opt.Flag == flag || opt.FlagShorthand == flag { + if opt.Flag == flag { return opt } } diff --git a/values.go b/values.go index 0cd1993..79c8e2c 100644 --- a/values.go +++ b/values.go @@ -530,7 +530,7 @@ func EnumOf(v *string, choices ...string) *Enum { func (e *Enum) Set(v string) error { for _, c := range e.Choices { - if v == c { + if strings.EqualFold(v, c) { *e.Value = v return nil } @@ -642,7 +642,7 @@ type EnumArray struct { func (e *EnumArray) Append(s string) error { for _, c := range e.Choices { - if s == c { + if strings.EqualFold(s, c) { *e.Value = append(*e.Value, s) return nil } @@ -658,7 +658,7 @@ func (e *EnumArray) Replace(ss []string) error { for _, s := range ss { found := false for _, c := range e.Choices { - if s == c { + if strings.EqualFold(s, c) { found = true break } @@ -680,11 +680,12 @@ func (e *EnumArray) Set(v string) error { if err != nil { return err } - err = e.Replace(ss) - if err != nil { - return err + for _, s := range ss { + err := e.Append(s) + if err != nil { + return err + } } - *e.Value = append(*e.Value, ss...) return nil }