# SPDX-License-Identifier: GPL-2.0 _para_complete() { local prg=$1 # the program to execute, either para_client or para_audioc local cur OLD_IFS list opt local -i n old_extglob=1 ddpos=-1 # position of the double-dash arg # This awk script extracts short and long options from the help output. local script='{ if ($1 ~ "^-[a-zA-Z]," && $2 ~ "^--[a-zA-Z]") { print substr($1, 0, 2); gsub("=.*", "", $2) print $2 } else if ($1 ~ "^--[a-zA-Z]") { gsub("=.*", "", $1) print $1 } }' # Ask readline to recreate COMP_WORDS using space as the only delimiter. if [[ "$COMP_WORDBREAKS" != ' ' ]]; then COMP_WORDBREAKS=' ' return 124 fi n=$COMP_POINT cur= while ((n > 0)); do let n--; [[ "${COMP_LINE:$n:1}" == ' ' ]] && break cur="${COMP_LINE:$n:1}$cur" done for ((n = 0; n < $COMP_CWORD; n++)); do [[ "${COMP_WORDS[$n]}" != '--' ]] && continue ddpos=$n break done # Figure out whether we need to complete according to options of the # given program or according to its subcommands. The 'para' shortcut # is expected to be aliased to 'para_client --' and we always complete # on subcommands in this case. if [[ "$cur" == -* ]] && [[ "${COMP_WORDS[0]}" != 'para' ]]; then # If '--' is none of the previous words, we complete on options # of the given program. if ((ddpos < 0 || COMP_CWORD < ddpos)); then list=$($prg --help | awk "$script") COMPREPLY=($(compgen -W "$list" -- "$cur")) return fi fi # Rebuild the command line with the first word and anything up to # "--" stripped off. Then call the given program with --complete on # the remainder. Treat the 'para' shortcut as if no double-dash had # been given. i.e. only strip off the first word. if [[ "${COMP_WORDS[0]}" == 'para' ]] || ((ddpos < 0)); then n=0 else n=$ddpos fi shopt -pq extglob || old_extglob=0 shopt -s extglob list=${COMP_LINE:0:$COMP_POINT} while ((n >= 0)); do list=${list##+([^ ])} # remove argument list=${list##*( )} # remove leading whitespace let n-- done ((!old_extglob)) && shopt -u extglob # prg relies on COMP_POINT and COMP_LINE, so adjust these export COMP_POINT=${#list} export COMP_LINE=$list COMPREPLY=($($prg --complete 2>/dev/null)) ((${#COMPREPLY[@]} == 0)) && return # oops, $prg did not write any output # The last line of the output contains the options for compopt, prefixed # with '-o='. n=$((${#COMPREPLY[@]} - 1)) OLD_IFS=$IFS IFS=',' for opt in ${COMPREPLY[$n]#-o=}; do case "$opt" in filenames) compopt -o default;; nospace) compopt -o nospace;; esac done IFS=$OLD_IFS unset COMPREPLY[$n] COMPREPLY=($(compgen -W "${COMPREPLY[*]}" -- "$cur")) } _para_audioc() { _para_complete para_audioc } _para_client() { _para_complete para_client } complete -F _para_audioc para_audioc complete -F _para_client para_client para