我想用以下调用约定为一个程序编写zsh补全:
program [generaloptions] operation [operationoptions]
其中operation
为--install
, --upgrade
…中的一个
到目前为止,我只有一般选项和操作选项。我的代码看起来像这样:
local generaloptions; generaloptions=(...)
local installoptions; installoptions=(...)
local upgradeoptions; upgradeoptions=(...)
case "$state" in
(install)
_arguments -s
"$installoptions[@]"
&& ret=0
(upgrade)
_arguments -s
"$upgradeoption[@]"
&& ret=0
*)
_arguments -s
"$generaloptions[@]"
'--install[...]: :->install'
'--upgrade[...]: :->upgrade'
&& ret=0
问题是,在我输入操作和第一个操作选项后,状态被重置为*)
情况。
$ program --install --installoption --<tab>
list of general options
如何将下一个状态设置为与前一个状态相同?哪个命令具有类似的调用约定,以便我可以查看该命令的补全代码?
主要问题是操作从--
开始,因此很难在参数中找到它们。例如,在git中,所有子命令都是一个没有破折号的单词。git像这样解决了这个问题:
- 查找不带破折号的第一个参数,因为这必须是子命令
- 根据子命令调度到该子命令的命令行参数。
所以git在中调度每个对完成函数的调用(这就是我所说的"保持状态")。
我解决这个问题的方法是通过查看许多补全函数并找到一个具有类似调用约定的命令。我发现最有用的命令是pacman
。以下是我从中提取的内容:
# This somehow disassembles the commandline options
args=( ${${${(M)words:#-*}#-}:#-*}
case $args in
*i)
_arguments -s
${installoptions}
'(-i[...]'
&& ret=0
;;
*u)
_arguments -s
${upgradeoption}
'-u[...]'
&& ret=0
;;
*)
case ${(M)words:#--*} in
*--install*)
_arguments -s
${installoptions}
'--install[...]'
&& ret=0
;;
*--upgrade*)
_arguments -s
${upgradeoption}
'--upgrade[...]'
&& ret=0
;;
*)
_arguments -s
{generaloptions}
&& ret=0
;;
esac
esac
我知道,有很多出版物,但我想你明白了重点。还请注意,我将--install
和--upgrade
选项从一般情况移到了操作情况。如果不这样做,如果您想在--install
或--upgrade
之后完成,则会丢失参数