如何使用给定的参数集bash完成GNU long选项?

问题描述 投票:0回答:1

GNU建议使用-name = value语法为长选项传递参数。它使长选项可以接受本身是可选的参数。

假设您有完整的可能参数集。您如何为这种选择编写bash完成代码?我希望完成功能在完成明确的参数时(而不是之前)增加空间。

command-line-arguments gnu bash-completion
1个回答
0
投票

这里是我为完成虚构命令gnu-options的代码中给出的GNU选项而编写的模板代码。我认为辅助函数__ltrim_completions可用于许多补全。

# Hack for given strings $2,$3,... possibly being in $1 and $COMP_WORDBREAKS
# Only the part after each match is listed as a completion.
# Run 'shopt -s extdebug; declare -F __ltrim_colon_completions; shopt -u extdebug'
# to see location for the respective function for colon only.
__ltrim_completions ()
{
    local cur=$1; shift
    while [[ ${1+x} ]]; do
        if [[ "$cur" == *$1* && "$COMP_WORDBREAKS" == *$1* ]]; then
            local x_word=${cur%"${cur##*$1}"}
            local i=${#COMPREPLY[*]}
            while [[ $((--i)) -ge 0 ]]; do
                COMPREPLY[$i]=${COMPREPLY[$i]#"$x_word"}
            done
        fi
        shift
    done
}

_gnu_options(){
    local IFS=$'\n' # needed for handling trailing space of some options and all arguments
    local cur prev words cword opts opts_with_args i wordlist
    local -A args
    # Do not treat : and = as word breaks even if they are in $COMP_WORDBREAKS:
    _init_completion -n : -n = || return

    # DEFINE OPTIONS THAT DO NOT TAKE AN ARGUMENT HERE:
    opts=(option0 option1)
    # DEFINE OPTIONS THAT TAKE AN ARGUMENT HERE:
    opts_with_args=(with-args0 with-args1 with-args2)
    # DEFINE THE ARGUMENTS FOR THE OPTIONS HERE:
    args[${opts_with_args[0]}]= # no pre-defined arguments for this one
    args[${opts_with_args[1]}]=\
'arg10
arg11'
    # single line definition:
    args[${opts_with_args[2]}]=$'arg20\narg21\narg22'

    wordlist=()

    for i in ${opts_with_args[*]}; do
        if [[ $cur = --$i=* ]]; then
            if [[ ${args[$i]} ]]; then
                local j
                for j in ${args[$i]}; do wordlist+=("--$i=$j "); done
                COMPREPLY=( $( compgen -W "${wordlist[*]}" -- $cur ) )
                __ltrim_completions "$cur" =
            fi
            return 0
        fi
    done
    for i in ${opts[*]}; do wordlist+=("--$i "); done
    for i in ${opts_with_args[*]}; do wordlist+=("--$i="); done
    COMPREPLY=( $( compgen -W "${wordlist[*]}" -- "$cur" ) )
    return 0
} && complete -o nospace -F _gnu_options gnu-options
© www.soinside.com 2019 - 2024. All rights reserved.