Update vendor spf13/cobra to fix completion error in bash 3

This commit is contained in:
Kazuki Suda
2018-02-19 22:47:19 +09:00
parent 2f09876c44
commit e604a7fdb1
10 changed files with 215 additions and 99 deletions

View File

@@ -21,8 +21,8 @@ const (
func writePreamble(buf *bytes.Buffer, name string) {
buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
buf.WriteString(`
__debug()
buf.WriteString(fmt.Sprintf(`
__%[1]s_debug()
{
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
@@ -31,13 +31,13 @@ __debug()
# Homebrew on Macs have version 1.3 of bash-completion which doesn't include
# _init_completion. This is a very minimal version of that function.
__my_init_completion()
__%[1]s_init_completion()
{
COMPREPLY=()
_get_comp_words_by_ref "$@" cur prev words cword
}
__index_of_word()
__%[1]s_index_of_word()
{
local w word=$1
shift
@@ -49,7 +49,7 @@ __index_of_word()
index=-1
}
__contains_word()
__%[1]s_contains_word()
{
local w word=$1; shift
for w in "$@"; do
@@ -58,9 +58,9 @@ __contains_word()
return 1
}
__handle_reply()
__%[1]s_handle_reply()
{
__debug "${FUNCNAME[0]}"
__%[1]s_debug "${FUNCNAME[0]}"
case $cur in
-*)
if [[ $(type -t compopt) = "builtin" ]]; then
@@ -85,7 +85,7 @@ __handle_reply()
local index flag
flag="${cur%%=*}"
__index_of_word "${flag}" "${flags_with_completion[@]}"
__%[1]s_index_of_word "${flag}" "${flags_with_completion[@]}"
COMPREPLY=()
if [[ ${index} -ge 0 ]]; then
PREFIX=""
@@ -103,7 +103,7 @@ __handle_reply()
# check if we are handling a flag with special work handling
local index
__index_of_word "${prev}" "${flags_with_completion[@]}"
__%[1]s_index_of_word "${prev}" "${flags_with_completion[@]}"
if [[ ${index} -ge 0 ]]; then
${flags_completion[${index}]}
return
@@ -139,21 +139,21 @@ __handle_reply()
}
# The arguments should be in the form "ext1|ext2|extn"
__handle_filename_extension_flag()
__%[1]s_handle_filename_extension_flag()
{
local ext="$1"
_filedir "@(${ext})"
}
__handle_subdirs_in_dir_flag()
__%[1]s_handle_subdirs_in_dir_flag()
{
local dir="$1"
pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
}
__handle_flag()
__%[1]s_handle_flag()
{
__debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
__%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
# if a command required a flag, and we found it, unset must_have_one_flag()
local flagname=${words[c]}
@@ -164,27 +164,30 @@ __handle_flag()
flagname=${flagname%%=*} # strip everything after the =
flagname="${flagname}=" # but put the = back
fi
__debug "${FUNCNAME[0]}: looking for ${flagname}"
if __contains_word "${flagname}" "${must_have_one_flag[@]}"; then
__%[1]s_debug "${FUNCNAME[0]}: looking for ${flagname}"
if __%[1]s_contains_word "${flagname}" "${must_have_one_flag[@]}"; then
must_have_one_flag=()
fi
# if you set a flag which only applies to this command, don't show subcommands
if __contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
if __%[1]s_contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
commands=()
fi
# keep flag value with flagname as flaghash
if [ -n "${flagvalue}" ] ; then
flaghash[${flagname}]=${flagvalue}
elif [ -n "${words[ $((c+1)) ]}" ] ; then
flaghash[${flagname}]=${words[ $((c+1)) ]}
else
flaghash[${flagname}]="true" # pad "true" for bool flag
# flaghash variable is an associative array which is only supported in bash > 3.
if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
if [ -n "${flagvalue}" ] ; then
flaghash[${flagname}]=${flagvalue}
elif [ -n "${words[ $((c+1)) ]}" ] ; then
flaghash[${flagname}]=${words[ $((c+1)) ]}
else
flaghash[${flagname}]="true" # pad "true" for bool flag
fi
fi
# skip the argument to a two word flag
if __contains_word "${words[c]}" "${two_word_flags[@]}"; then
if __%[1]s_contains_word "${words[c]}" "${two_word_flags[@]}"; then
c=$((c+1))
# if we are looking for a flags value, don't show commands
if [[ $c -eq $cword ]]; then
@@ -196,13 +199,13 @@ __handle_flag()
}
__handle_noun()
__%[1]s_handle_noun()
{
__debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
__%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
if __%[1]s_contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
must_have_one_noun=()
elif __contains_word "${words[c]}" "${noun_aliases[@]}"; then
elif __%[1]s_contains_word "${words[c]}" "${noun_aliases[@]}"; then
must_have_one_noun=()
fi
@@ -210,9 +213,9 @@ __handle_noun()
c=$((c+1))
}
__handle_command()
__%[1]s_handle_command()
{
__debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
__%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
local next_command
if [[ -n ${last_command} ]]; then
@@ -225,30 +228,30 @@ __handle_command()
fi
fi
c=$((c+1))
__debug "${FUNCNAME[0]}: looking for ${next_command}"
__%[1]s_debug "${FUNCNAME[0]}: looking for ${next_command}"
declare -F "$next_command" >/dev/null && $next_command
}
__handle_word()
__%[1]s_handle_word()
{
if [[ $c -ge $cword ]]; then
__handle_reply
__%[1]s_handle_reply
return
fi
__debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
__%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
if [[ "${words[c]}" == -* ]]; then
__handle_flag
elif __contains_word "${words[c]}" "${commands[@]}"; then
__handle_command
elif [[ $c -eq 0 ]] && __contains_word "$(basename "${words[c]}")" "${commands[@]}"; then
__handle_command
__%[1]s_handle_flag
elif __%[1]s_contains_word "${words[c]}" "${commands[@]}"; then
__%[1]s_handle_command
elif [[ $c -eq 0 ]] && __%[1]s_contains_word "$(basename "${words[c]}")" "${commands[@]}"; then
__%[1]s_handle_command
else
__handle_noun
__%[1]s_handle_noun
fi
__handle_word
__%[1]s_handle_word
}
`)
`, name))
}
func writePostscript(buf *bytes.Buffer, name string) {
@@ -260,7 +263,7 @@ func writePostscript(buf *bytes.Buffer, name string) {
if declare -F _init_completion >/dev/null 2>&1; then
_init_completion -s || return
else
__my_init_completion -n "=" || return
__%[1]s_init_completion -n "=" || return
fi
local c=0
@@ -269,13 +272,13 @@ func writePostscript(buf *bytes.Buffer, name string) {
local local_nonpersistent_flags=()
local flags_with_completion=()
local flags_completion=()
local commands=("%s")
local commands=("%[1]s")
local must_have_one_flag=()
local must_have_one_noun=()
local last_command
local nouns=()
__handle_word
__%[1]s_handle_word
}
`, name))
@@ -300,7 +303,7 @@ func writeCommands(buf *bytes.Buffer, cmd *Command) {
buf.WriteString("\n")
}
func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string) {
func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string, cmd *Command) {
for key, value := range annotations {
switch key {
case BashCompFilenameExt:
@@ -308,7 +311,7 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s
var ext string
if len(value) > 0 {
ext = "__handle_filename_extension_flag " + strings.Join(value, "|")
ext = fmt.Sprintf("__%s_handle_filename_extension_flag ", cmd.Name()) + strings.Join(value, "|")
} else {
ext = "_filedir"
}
@@ -326,7 +329,7 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s
var ext string
if len(value) == 1 {
ext = "__handle_subdirs_in_dir_flag " + value[0]
ext = fmt.Sprintf("__%s_handle_subdirs_in_dir_flag ", cmd.Name()) + value[0]
} else {
ext = "_filedir -d"
}
@@ -335,7 +338,7 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s
}
}
func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag) {
func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
name := flag.Shorthand
format := " "
if len(flag.NoOptDefVal) == 0 {
@@ -343,10 +346,10 @@ func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag) {
}
format += "flags+=(\"-%s\")\n"
buf.WriteString(fmt.Sprintf(format, name))
writeFlagHandler(buf, "-"+name, flag.Annotations)
writeFlagHandler(buf, "-"+name, flag.Annotations, cmd)
}
func writeFlag(buf *bytes.Buffer, flag *pflag.Flag) {
func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
name := flag.Name
format := " flags+=(\"--%s"
if len(flag.NoOptDefVal) == 0 {
@@ -354,7 +357,7 @@ func writeFlag(buf *bytes.Buffer, flag *pflag.Flag) {
}
format += "\")\n"
buf.WriteString(fmt.Sprintf(format, name))
writeFlagHandler(buf, "--"+name, flag.Annotations)
writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
}
func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
@@ -380,9 +383,9 @@ func writeFlags(buf *bytes.Buffer, cmd *Command) {
if nonCompletableFlag(flag) {
return
}
writeFlag(buf, flag)
writeFlag(buf, flag, cmd)
if len(flag.Shorthand) > 0 {
writeShortFlag(buf, flag)
writeShortFlag(buf, flag, cmd)
}
if localNonPersistentFlags.Lookup(flag.Name) != nil {
writeLocalNonPersistentFlag(buf, flag)
@@ -392,9 +395,9 @@ func writeFlags(buf *bytes.Buffer, cmd *Command) {
if nonCompletableFlag(flag) {
return
}
writeFlag(buf, flag)
writeFlag(buf, flag, cmd)
if len(flag.Shorthand) > 0 {
writeShortFlag(buf, flag)
writeShortFlag(buf, flag, cmd)
}
})
@@ -491,17 +494,20 @@ func (c *Command) GenBashCompletionFile(filename string) error {
return c.GenBashCompletion(outFile)
}
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists.
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
// and causes your command to report an error if invoked without the flag.
func (c *Command) MarkFlagRequired(name string) error {
return MarkFlagRequired(c.Flags(), name)
}
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag, if it exists.
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
// and causes your command to report an error if invoked without the flag.
func (c *Command) MarkPersistentFlagRequired(name string) error {
return MarkFlagRequired(c.PersistentFlags(), name)
}
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists.
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
// and causes your command to report an error if invoked without the flag.
func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
}