summaryrefslogtreecommitdiff
path: root/vendor/github.com/spf13/cobra/bash_completionsV2.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/spf13/cobra/bash_completionsV2.go')
-rw-r--r--vendor/github.com/spf13/cobra/bash_completionsV2.go152
1 files changed, 120 insertions, 32 deletions
diff --git a/vendor/github.com/spf13/cobra/bash_completionsV2.go b/vendor/github.com/spf13/cobra/bash_completionsV2.go
index 1cce5c329..d2397aa36 100644
--- a/vendor/github.com/spf13/cobra/bash_completionsV2.go
+++ b/vendor/github.com/spf13/cobra/bash_completionsV2.go
@@ -146,7 +146,7 @@ __%[1]s_process_completion_results() {
if (((directive & shellCompDirectiveFilterFileExt) != 0)); then
# File extension filtering
- local fullFilter filter filteringCmd
+ local fullFilter="" filter filteringCmd
# Do not use quotes around the $completions variable or else newline
# characters will be kept.
@@ -177,20 +177,71 @@ __%[1]s_process_completion_results() {
__%[1]s_handle_special_char "$cur" =
# Print the activeHelp statements before we finish
+ __%[1]s_handle_activeHelp
+}
+
+__%[1]s_handle_activeHelp() {
+ # Print the activeHelp statements
if ((${#activeHelp[*]} != 0)); then
- printf "\n";
- printf "%%s\n" "${activeHelp[@]}"
- printf "\n"
-
- # The prompt format is only available from bash 4.4.
- # We test if it is available before using it.
- if (x=${PS1@P}) 2> /dev/null; then
- printf "%%s" "${PS1@P}${COMP_LINE[@]}"
- else
- # Can't print the prompt. Just print the
- # text the user had typed, it is workable enough.
- printf "%%s" "${COMP_LINE[@]}"
+ if [ -z $COMP_TYPE ]; then
+ # Bash v3 does not set the COMP_TYPE variable.
+ printf "\n";
+ printf "%%s\n" "${activeHelp[@]}"
+ printf "\n"
+ __%[1]s_reprint_commandLine
+ return
fi
+
+ # Only print ActiveHelp on the second TAB press
+ if [ $COMP_TYPE -eq 63 ]; then
+ printf "\n"
+ printf "%%s\n" "${activeHelp[@]}"
+
+ if ((${#COMPREPLY[*]} == 0)); then
+ # When there are no completion choices from the program, file completion
+ # may kick in if the program has not disabled it; in such a case, we want
+ # to know if any files will match what the user typed, so that we know if
+ # there will be completions presented, so that we know how to handle ActiveHelp.
+ # To find out, we actually trigger the file completion ourselves;
+ # the call to _filedir will fill COMPREPLY if files match.
+ if (((directive & shellCompDirectiveNoFileComp) == 0)); then
+ __%[1]s_debug "Listing files"
+ _filedir
+ fi
+ fi
+
+ if ((${#COMPREPLY[*]} != 0)); then
+ # If there are completion choices to be shown, print a delimiter.
+ # Re-printing the command-line will automatically be done
+ # by the shell when it prints the completion choices.
+ printf -- "--"
+ else
+ # When there are no completion choices at all, we need
+ # to re-print the command-line since the shell will
+ # not be doing it itself.
+ __%[1]s_reprint_commandLine
+ fi
+ elif [ $COMP_TYPE -eq 37 ] || [ $COMP_TYPE -eq 42 ]; then
+ # For completion type: menu-complete/menu-complete-backward and insert-completions
+ # the completions are immediately inserted into the command-line, so we first
+ # print the activeHelp message and reprint the command-line since the shell won't.
+ printf "\n"
+ printf "%%s\n" "${activeHelp[@]}"
+
+ __%[1]s_reprint_commandLine
+ fi
+ fi
+}
+
+__%[1]s_reprint_commandLine() {
+ # The prompt format is only available from bash 4.4.
+ # We test if it is available before using it.
+ if (x=${PS1@P}) 2> /dev/null; then
+ printf "%%s" "${PS1@P}${COMP_LINE[@]}"
+ else
+ # Can't print the prompt. Just print the
+ # text the user had typed, it is workable enough.
+ printf "%%s" "${COMP_LINE[@]}"
fi
}
@@ -201,6 +252,8 @@ __%[1]s_extract_activeHelp() {
local endIndex=${#activeHelpMarker}
while IFS='' read -r comp; do
+ [[ -z $comp ]] && continue
+
if [[ ${comp:0:endIndex} == $activeHelpMarker ]]; then
comp=${comp:endIndex}
__%[1]s_debug "ActiveHelp found: $comp"
@@ -223,16 +276,21 @@ __%[1]s_handle_completion_types() {
# If the user requested inserting one completion at a time, or all
# completions at once on the command-line we must remove the descriptions.
# https://github.com/spf13/cobra/issues/1508
- local tab=$'\t' comp
- while IFS='' read -r comp; do
- [[ -z $comp ]] && continue
- # Strip any description
- comp=${comp%%%%$tab*}
- # Only consider the completions that match
- if [[ $comp == "$cur"* ]]; then
- COMPREPLY+=("$comp")
- fi
- done < <(printf "%%s\n" "${completions[@]}")
+
+ # If there are no completions, we don't need to do anything
+ (( ${#completions[@]} == 0 )) && return 0
+
+ local tab=$'\t'
+
+ # Strip any description and escape the completion to handled special characters
+ IFS=$'\n' read -ra completions -d '' < <(printf "%%q\n" "${completions[@]%%%%$tab*}")
+
+ # Only consider the completions that match
+ IFS=$'\n' read -ra COMPREPLY -d '' < <(IFS=$'\n'; compgen -W "${completions[*]}" -- "${cur}")
+
+ # compgen looses the escaping so we need to escape all completions again since they will
+ # all be inserted on the command-line.
+ IFS=$'\n' read -ra COMPREPLY -d '' < <(printf "%%q\n" "${COMPREPLY[@]}")
;;
*)
@@ -243,11 +301,25 @@ __%[1]s_handle_completion_types() {
}
__%[1]s_handle_standard_completion_case() {
- local tab=$'\t' comp
+ local tab=$'\t'
+
+ # If there are no completions, we don't need to do anything
+ (( ${#completions[@]} == 0 )) && return 0
# Short circuit to optimize if we don't have descriptions
if [[ "${completions[*]}" != *$tab* ]]; then
- IFS=$'\n' read -ra COMPREPLY -d '' < <(compgen -W "${completions[*]}" -- "$cur")
+ # First, escape the completions to handle special characters
+ IFS=$'\n' read -ra completions -d '' < <(printf "%%q\n" "${completions[@]}")
+ # Only consider the completions that match what the user typed
+ IFS=$'\n' read -ra COMPREPLY -d '' < <(IFS=$'\n'; compgen -W "${completions[*]}" -- "${cur}")
+
+ # compgen looses the escaping so, if there is only a single completion, we need to
+ # escape it again because it will be inserted on the command-line. If there are multiple
+ # completions, we don't want to escape them because they will be printed in a list
+ # and we don't want to show escape characters in that list.
+ if (( ${#COMPREPLY[@]} == 1 )); then
+ COMPREPLY[0]=$(printf "%%q" "${COMPREPLY[0]}")
+ fi
return 0
fi
@@ -256,23 +328,39 @@ __%[1]s_handle_standard_completion_case() {
# Look for the longest completion so that we can format things nicely
while IFS='' read -r compline; do
[[ -z $compline ]] && continue
- # Strip any description before checking the length
- comp=${compline%%%%$tab*}
+
+ # Before checking if the completion matches what the user typed,
+ # we need to strip any description and escape the completion to handle special
+ # characters because those escape characters are part of what the user typed.
+ # Don't call "printf" in a sub-shell because it will be much slower
+ # since we are in a loop.
+ printf -v comp "%%q" "${compline%%%%$tab*}" &>/dev/null || comp=$(printf "%%q" "${compline%%%%$tab*}")
+
# Only consider the completions that match
[[ $comp == "$cur"* ]] || continue
+
+ # The completions matches. Add it to the list of full completions including
+ # its description. We don't escape the completion because it may get printed
+ # in a list if there are more than one and we don't want show escape characters
+ # in that list.
COMPREPLY+=("$compline")
+
+ # Strip any description before checking the length, and again, don't escape
+ # the completion because this length is only used when printing the completions
+ # in a list and we don't want show escape characters in that list.
+ comp=${compline%%%%$tab*}
if ((${#comp}>longest)); then
longest=${#comp}
fi
done < <(printf "%%s\n" "${completions[@]}")
- # If there is a single completion left, remove the description text
+ # If there is a single completion left, remove the description text and escape any special characters
if ((${#COMPREPLY[*]} == 1)); then
__%[1]s_debug "COMPREPLY[0]: ${COMPREPLY[0]}"
- comp="${COMPREPLY[0]%%%%$tab*}"
- __%[1]s_debug "Removed description from single completion, which is now: ${comp}"
- COMPREPLY[0]=$comp
- else # Format the descriptions
+ COMPREPLY[0]=$(printf "%%q" "${COMPREPLY[0]%%%%$tab*}")
+ __%[1]s_debug "Removed description from single completion, which is now: ${COMPREPLY[0]}"
+ else
+ # Format the descriptions
__%[1]s_format_comp_descriptions $longest
fi
}