你是对的,为 zsh 编写完成脚本可能非常困难。您最好的选择是使用现有的作为指南。git 的一个对于初学者来说太多了,imo。你可以使用这个仓库:
https://github.com/zsh-users/zsh-completions
至于您的问题,您使用了state的概念。您在列表中定义子命令,然后通过$state识别您所在的命令。然后定义每个命令的选项。您可以在play的完成脚本中看到这一点。简化版如下:
_play() {
local ret=1
_arguments -C \
'1: :_play_cmds' \
'*::arg:->args' \
&& ret=0
case $state in
(args)
case $line[1] in
(build-module|list-modules|lm|check|id)
_message 'no more arguments' && ret=0
;;
(dependencies|deps)
_arguments \
'1:: :_play_apps' \
'(--debug)--debug[Debug mode (even more informations logged than in verbose mode)]' \
'(--jpda)--jpda[Listen for JPDA connection. The process will suspended until a client is plugged to the JPDA port.]' \
'(--sync)--sync[Keep lib/ and modules/ directory synced. Delete unknow dependencies.]' \
'(--verbose)--verbose[Verbose Mode]' \
&& ret=0
;;
esac
esac
(如果您要粘贴此内容,请使用原始来源,因为这不起作用)。
它看起来令人生畏,但总体思路并不复杂。子命令首先出现(_play_cmds 是一个子命令列表,每个命令都有描述),然后是参数。参数是根据您选择的子命令构建的。请注意,如果多个子命令共享参数,您可以将它们分组。
使用man zshcompsys您可以找到有关整个系统的更多信息,尽管它有些密集。