From 341ee8dc0efeb50f3aa74c90bcc5c80a7d3e96f1 Mon Sep 17 00:00:00 2001 From: MrNaif2018 Date: Wed, 1 Feb 2023 17:39:18 +0300 Subject: [PATCH] Backport [v2]: Fix some issues in bash autocompletion --- autocomplete/bash_autocomplete | 22 ++++++++++++++++++---- help_test.go | 22 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/autocomplete/bash_autocomplete b/autocomplete/bash_autocomplete index f0f624183b..fea6ee33ad 100755 --- a/autocomplete/bash_autocomplete +++ b/autocomplete/bash_autocomplete @@ -2,17 +2,31 @@ : ${PROG:=$(basename ${BASH_SOURCE})} +# Macs have bash3 for which the bash-completion package doesn't include +# _init_completion. This is a minimal version of that function. +_cli_init_completion() { + COMPREPLY=() + _get_comp_words_by_ref "$@" cur prev words cword +} + _cli_bash_autocomplete() { if [[ "${COMP_WORDS[0]}" != "source" ]]; then - local cur opts base + local cur opts base words COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" + if declare -F _init_completion >/dev/null 2>&1; then + _init_completion -n "=:" || return + else + _cli_init_completion -n "=:" || return + fi + words=("${words[@]:0:$cword}") if [[ "$cur" == "-"* ]]; then - opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --generate-bash-completion ) + requestComp="${words[*]} ${cur} --generate-bash-completion" else - opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion ) + requestComp="${words[*]} --generate-bash-completion" fi - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + opts=$(eval "${requestComp}" 2>/dev/null) + COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 fi } diff --git a/help_test.go b/help_test.go index 8e9396dc8f..84277f016f 100644 --- a/help_test.go +++ b/help_test.go @@ -1195,6 +1195,28 @@ func TestDefaultCompleteWithFlags(t *testing.T) { argv: []string{"cmd", "--generate-bash-completion"}, expected: "futz\n", }, + { + name: "autocomplete-with-spaces", + c: &Context{App: &App{ + Name: "cmd", + Flags: []Flag{ + &BoolFlag{Name: "happiness"}, + &Int64Flag{Name: "everybody-jump-on"}, + }, + }}, + cmd: &Command{ + Name: "putz", + Subcommands: []*Command{ + {Name: "help"}, + }, + Flags: []Flag{ + &BoolFlag{Name: "excitement"}, + &StringFlag{Name: "hat-shape"}, + }, + }, + argv: []string{"cmd", "--url", "http://localhost:8000", "h", "--generate-bash-completion"}, + expected: "help\n", + }, } { t.Run(tc.name, func(ct *testing.T) { writer := &bytes.Buffer{}