我有一个命令
ts
,它接受一个命令和该命令的参数作为其参数。我希望制表符补全“做正确的事”,即:
当我输入时,例如
ts foo<tab>
bash 应该尝试自动完成并找到以“foo”开头的任何命令。我已经这样工作了:
complete -F __ts_bash_completions ts
__ts_bash_completions () {
COMPREPLY=();
# if there's only one word on the command line
if [ "$COMP_CWORD" -eq 1 ]; then
COMPREPLY=($(compgen -c -- "${COMP_WORDS[COMP_CWORD]}"));
一旦有了完整的命令名称,我希望后续参数的制表符补全使用第一个参数的制表符补全语义。如果没有为第一个参数定义完成函数,我也可以正常工作。继续上面的内容,这是有效的:
# otherwise ...
else
local command_completion_function="$(complete -p ${COMP_WORDS[1]} 2>/dev/null|sed 's/.*-F \([^ ]*\) .*/\1/')"
if [ -z "$command_completion_function" ]; then
COMPREPLY=($(compgen -W "$(ls)" -- "${COMP_WORDS[COMP_CWORD]}"));
但我正在努力解决最后一个要求,即如果有is可用的完成功能,则应该使用它,而我就是无法让那个该死的东西工作。我已经看到了这个问题及其答案并试图对其进行概括。再次,继续上面的内容:
else
echo using $command_completion_function
echo COMP_CWORD="$COMP_CWORD"
echo COMP_LINE="$COMP_LINE"
echo COMP_WORDS="${COMP_WORDS[*]}"
COMP_CWORD=$(( $COMP_CWORD - 1 ))
COMP_LINE=$(echo $COMP_LINE|sed "s/^${COMP_WORDS[0]} //")
unset COMP_WORDS[0]
echo COMP_CWORD="$COMP_CWORD"
echo COMP_LINE="$COMP_LINE"
echo COMP_WORDS="${COMP_WORDS[*]}"
$command_completion_function
fi
fi
}
一切看起来都不错,就我从各种
echo
变量的COMP_*
来看,但是有人能发现这个愚蠢的错误吗?
else
部分:
else
local myname='ts'
local padding=$( printf '%*s' ${#myname} ' ' )
local realcmd=${COMP_WORDS[1]}
# Change
#
# ts realcmd arg1 arg2 ...
#
# to
#
# realcmd arg1 arg2 ...
#
COMP_LINE=$( printf '%s\n' "$COMP_LINE" \
| sed -E -e "s/^$myname( +)$realcmd/$realcmd\1$padding/" )
COMP_WORDS=( "${COMP_WORDS[@]:1}" )
(( --COMP_CWORD ))
$command_completion_function "$realcmd" "$2" "$3"
fi