vendor/github.com/spf13/cobra/bash_completionsV2.go
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
child 265 05c40b36d3b2
--- a/vendor/github.com/spf13/cobra/bash_completionsV2.go	Tue Aug 23 22:33:28 2022 +0200
+++ b/vendor/github.com/spf13/cobra/bash_completionsV2.go	Tue Aug 23 22:39:43 2022 +0200
@@ -78,7 +78,7 @@
         directive=0
     fi
     __%[1]s_debug "The completion directive is: ${directive}"
-    __%[1]s_debug "The completions are: ${out[*]}"
+    __%[1]s_debug "The completions are: ${out}"
 }
 
 __%[1]s_process_completion_results() {
@@ -111,13 +111,18 @@
         fi
     fi
 
+    # Separate activeHelp from normal completions
+    local completions=()
+    local activeHelp=()
+    __%[1]s_extract_activeHelp
+
     if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
         # File extension filtering
         local fullFilter filter filteringCmd
 
-        # Do not use quotes around the $out variable or else newline
+        # Do not use quotes around the $completions variable or else newline
         # characters will be kept.
-        for filter in ${out[*]}; do
+        for filter in ${completions[*]}; do
             fullFilter+="$filter|"
         done
 
@@ -129,7 +134,7 @@
 
         # Use printf to strip any trailing newline
         local subdir
-        subdir=$(printf "%%s" "${out[0]}")
+        subdir=$(printf "%%s" "${completions[0]}")
         if [ -n "$subdir" ]; then
             __%[1]s_debug "Listing directories in $subdir"
             pushd "$subdir" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return
@@ -138,52 +143,110 @@
             _filedir -d
         fi
     else
-        __%[1]s_handle_standard_completion_case
+        __%[1]s_handle_completion_types
     fi
 
     __%[1]s_handle_special_char "$cur" :
     __%[1]s_handle_special_char "$cur" =
+
+    # Print the activeHelp statements before we finish
+    if [ ${#activeHelp} -ne 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[@]}"
+        fi
+    fi
+}
+
+# Separate activeHelp lines from real completions.
+# Fills the $activeHelp and $completions arrays.
+__%[1]s_extract_activeHelp() {
+    local activeHelpMarker="%[8]s"
+    local endIndex=${#activeHelpMarker}
+
+    while IFS='' read -r comp; do
+        if [ "${comp:0:endIndex}" = "$activeHelpMarker" ]; then
+            comp=${comp:endIndex}
+            __%[1]s_debug "ActiveHelp found: $comp"
+            if [ -n "$comp" ]; then
+                activeHelp+=("$comp")
+            fi
+        else
+            # Not an activeHelp line but a normal completion
+            completions+=("$comp")
+        fi
+    done < <(printf "%%s\n" "${out}")
+}
+
+__%[1]s_handle_completion_types() {
+    __%[1]s_debug "__%[1]s_handle_completion_types: COMP_TYPE is $COMP_TYPE"
+
+    case $COMP_TYPE in
+    37|42)
+        # Type: menu-complete/menu-complete-backward and insert-completions
+        # 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[@]}")
+        ;;
+
+    *)
+        # Type: complete (normal completion)
+        __%[1]s_handle_standard_completion_case
+        ;;
+    esac
 }
 
 __%[1]s_handle_standard_completion_case() {
-    local tab comp
-    tab=$(printf '\t')
+    local tab=$'\t' comp
+
+    # Short circuit to optimize if we don't have descriptions
+    if [[ "${completions[*]}" != *$tab* ]]; then
+        IFS=$'\n' read -ra COMPREPLY -d '' < <(compgen -W "${completions[*]}" -- "$cur")
+        return 0
+    fi
 
     local longest=0
+    local compline
     # Look for the longest completion so that we can format things nicely
-    while IFS='' read -r comp; do
+    while IFS='' read -r compline; do
+        [[ -z $compline ]] && continue
         # Strip any description before checking the length
-        comp=${comp%%%%$tab*}
+        comp=${compline%%%%$tab*}
         # Only consider the completions that match
-        comp=$(compgen -W "$comp" -- "$cur")
+        [[ $comp == "$cur"* ]] || continue
+        COMPREPLY+=("$compline")
         if ((${#comp}>longest)); then
             longest=${#comp}
         fi
-    done < <(printf "%%s\n" "${out[@]}")
-
-    local completions=()
-    while IFS='' read -r comp; do
-        if [ -z "$comp" ]; then
-            continue
-        fi
-
-        __%[1]s_debug "Original comp: $comp"
-        comp="$(__%[1]s_format_comp_descriptions "$comp" "$longest")"
-        __%[1]s_debug "Final comp: $comp"
-        completions+=("$comp")
-    done < <(printf "%%s\n" "${out[@]}")
-
-    while IFS='' read -r comp; do
-        COMPREPLY+=("$comp")
-    done < <(compgen -W "${completions[*]}" -- "$cur")
+    done < <(printf "%%s\n" "${completions[@]}")
 
     # If there is a single completion left, remove the description text
     if [ ${#COMPREPLY[*]} -eq 1 ]; then
         __%[1]s_debug "COMPREPLY[0]: ${COMPREPLY[0]}"
-        comp="${COMPREPLY[0]%%%% *}"
+        comp="${COMPREPLY[0]%%%%$tab*}"
         __%[1]s_debug "Removed description from single completion, which is now: ${comp}"
-        COMPREPLY=()
-        COMPREPLY+=("$comp")
+        COMPREPLY[0]=$comp
+    else # Format the descriptions
+        __%[1]s_format_comp_descriptions $longest
     fi
 }
 
@@ -202,45 +265,48 @@
 
 __%[1]s_format_comp_descriptions()
 {
-    local tab
-    tab=$(printf '\t')
-    local comp="$1"
-    local longest=$2
+    local tab=$'\t'
+    local comp desc maxdesclength
+    local longest=$1
 
-    # Properly format the description string which follows a tab character if there is one
-    if [[ "$comp" == *$tab* ]]; then
-        desc=${comp#*$tab}
-        comp=${comp%%%%$tab*}
+    local i ci
+    for ci in ${!COMPREPLY[*]}; do
+        comp=${COMPREPLY[ci]}
+        # Properly format the description string which follows a tab character if there is one
+        if [[ "$comp" == *$tab* ]]; then
+            __%[1]s_debug "Original comp: $comp"
+            desc=${comp#*$tab}
+            comp=${comp%%%%$tab*}
 
-        # $COLUMNS stores the current shell width.
-        # Remove an extra 4 because we add 2 spaces and 2 parentheses.
-        maxdesclength=$(( COLUMNS - longest - 4 ))
+            # $COLUMNS stores the current shell width.
+            # Remove an extra 4 because we add 2 spaces and 2 parentheses.
+            maxdesclength=$(( COLUMNS - longest - 4 ))
 
-        # Make sure we can fit a description of at least 8 characters
-        # if we are to align the descriptions.
-        if [[ $maxdesclength -gt 8 ]]; then
-            # Add the proper number of spaces to align the descriptions
-            for ((i = ${#comp} ; i < longest ; i++)); do
-                comp+=" "
-            done
-        else
-            # Don't pad the descriptions so we can fit more text after the completion
-            maxdesclength=$(( COLUMNS - ${#comp} - 4 ))
-        fi
+            # Make sure we can fit a description of at least 8 characters
+            # if we are to align the descriptions.
+            if [[ $maxdesclength -gt 8 ]]; then
+                # Add the proper number of spaces to align the descriptions
+                for ((i = ${#comp} ; i < longest ; i++)); do
+                    comp+=" "
+                done
+            else
+                # Don't pad the descriptions so we can fit more text after the completion
+                maxdesclength=$(( COLUMNS - ${#comp} - 4 ))
+            fi
 
-        # If there is enough space for any description text,
-        # truncate the descriptions that are too long for the shell width
-        if [ $maxdesclength -gt 0 ]; then
-            if [ ${#desc} -gt $maxdesclength ]; then
-                desc=${desc:0:$(( maxdesclength - 1 ))}
-                desc+="…"
+            # If there is enough space for any description text,
+            # truncate the descriptions that are too long for the shell width
+            if [ $maxdesclength -gt 0 ]; then
+                if [ ${#desc} -gt $maxdesclength ]; then
+                    desc=${desc:0:$(( maxdesclength - 1 ))}
+                    desc+="…"
+                fi
+                comp+="  ($desc)"
             fi
-            comp+="  ($desc)"
+            COMPREPLY[ci]=$comp
+            __%[1]s_debug "Final comp: $comp"
         fi
-    fi
-
-    # Must use printf to escape all special characters
-    printf "%%q" "${comp}"
+    done
 }
 
 __start_%[1]s()
@@ -281,7 +347,8 @@
 # ex: ts=4 sw=4 et filetype=sh
 `, name, compCmd,
 		ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
-		ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
+		ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs,
+		activeHelpMarker))
 }
 
 // GenBashCompletionFileV2 generates Bash completion version 2.