GNU建议使用-name = value语法为长选项传递参数。它使长选项可以接受本身是可选的参数。
假设您有完整的可能参数集。您如何为这种选择编写bash完成代码?我希望完成功能在完成明确的参数时(而不是之前)增加空间。
这里是我为完成虚构命令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