Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 88 additions & 46 deletions autocomplete/bash_autocomplete
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,105 @@

# This is a shell completion script auto-generated by https://github.com/urfave/cli for bash.

# Macs have bash3 for which the bash-completion package doesn't include
# _init_completion. This is a minimal version of that function.
# macOS still ships Bash 3, where bash-completion may not provide
# _init_completion. This is a minimal compatible fallback.
__%[1]s_init_completion() {
COMPREPLY=()
_get_comp_words_by_ref "$@" cur prev words cword
if declare -F _comp_initialize >/dev/null 2>&1; then
_comp_initialize "$@"
else
_get_comp_words_by_ref "$@" cur prev words cword
fi
}

__%[1]s_build_completion_request() {
local -a words_before_cursor=("${COMP_WORDS[@]:0:${COMP_CWORD}}")
local current_word="${COMP_WORDS[COMP_CWORD]}"

if [[ "${current_word}" == "-"* ]]; then
printf '%%s %%s --generate-shell-completion' "${words_before_cursor[*]}" "${current_word}"
else
printf '%%s --generate-shell-completion' "${words_before_cursor[*]}"
fi
}

# Keep Bash 3 compatibility: associative arrays require Bash 4+, so
# descriptions are looked up via parallel indexed arrays.
__%[1]s_find_description_for() {
local candidate="$1"
local i

for i in "${!__cli_completion_tokens[@]}"; do
if [[ "${__cli_completion_tokens[i]}" == "${candidate}" ]]; then
printf '%%s' "${__cli_completion_descriptions[i]}"
return 0
fi
done

return 1
}

__%[1]s_bash_autocomplete() {
if [[ "${COMP_WORDS[0]}" != "source" ]]; then
local cur opts base words
local words=("${COMP_WORDS[@]}")

if [[ "${words[0]}" != "source" ]]; then
local cur opts
local cword="${COMP_CWORD}"
local request_comp

COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
if declare -F _init_completion >/dev/null 2>&1; then
_init_completion -n "=:" || return
else
__%[1]s_init_completion -n "=:" || return
fi
words=("${words[@]:0:$cword}")
if [[ "$cur" == "-"* ]]; then
requestComp="${words[*]} ${cur} --generate-shell-completion"
else
requestComp="${words[*]} --generate-shell-completion"
fi
opts=$(eval "${requestComp}" 2>/dev/null)
cur="${words[$cword]}"

__%[1]s_init_completion -n "=:" || return

request_comp="$(__%[1]s_build_completion_request)"
opts=$(eval "${request_comp}" 2>/dev/null)

# Completion output lines use "token:description" format.
# Keep token/description in parallel arrays for Bash 3 compatibility.
__cli_completion_tokens=()
__cli_completion_descriptions=()

# Separate completions and descriptions
local completions=()
local descriptions=()
local line
local longest=0
while IFS=$'\n' read -r line; do
local comp_part desc_part
if [[ "$line" == *:* ]]; then
comp_part="${line%%:*}"
desc_part="${line#*:}"
else
comp_part="$line"
desc_part=""
fi
completions+=("$comp_part")
descriptions+=("$desc_part")
(( ${#comp_part} > longest )) && longest=${#comp_part}
done <<< "$opts"

# Format completions with aligned descriptions
for i in "${!completions[@]}"; do
local padded_completion="${completions[i]}"
local pad_len=$((longest - ${#padded_completion}))
if (( pad_len > 0 )); then
padded_completion="${padded_completion}$(head -c $pad_len < /dev/zero | tr '\0' ' ')"
fi
local token="${line}"
local description=""

if [[ -n "${descriptions[i]}" ]]; then
COMPREPLY+=("${padded_completion} -- ${descriptions[i]}")
else
COMPREPLY+=("${padded_completion}")
if [[ "${line}" == *:* ]]; then
token="${line%%:*}"
description="${line#*:}"
fi

if [[ -z "${token}" ]]; then
continue
fi
done

__cli_completion_tokens+=("${token}")
__cli_completion_descriptions+=("${description}")
(( ${#token} > longest )) && longest=${#token}
done <<< "${opts}"

local matches=( $(compgen -W "${__cli_completion_tokens[*]}" -- "${cur}") )

# COMP_TYPE=63 means Bash is listing matches (usually on second TAB).
if [[ "${COMP_TYPE:-}" == "63" && ${#matches[@]} -gt 0 ]]; then
local listed=()
local candidate
for candidate in "${matches[@]}"; do
local desc="$(__%[1]s_find_description_for "${candidate}")"

if [[ -n "${desc}" ]]; then
local padded="$(printf '%%-*s' "${longest}" "${candidate}")"
listed+=("${padded} -- ${desc}")
else
listed+=("${candidate}")
fi
done
COMPREPLY=("${listed[@]}")
else
COMPREPLY=("${matches[@]}")
fi

return 0
fi
Expand Down