我写了一个命令行工具,它使用的子命令非常像Mercurial,Git,Subversion& c,因为它的一般用法是:
>myapp [OPTS] SUBCOMMAND [SUBCOMMAND-OPTS] [ARGS]
例如.
>myapp --verbose speak --voice=samantha --quickly "hello there"
我现在正在构建Zsh完成的过程,但很快就发现它是一个非常复杂的野兽.我看过了_hg和_git的完成,但是它们的方法非常复杂和不同(我很难理解它们),但是它们似乎都分别处理每个子命令.
有没有人知道有没有使用内置函数(_arguments,_values,pick_variant& c.)来正确处理子命令的概念,包括适当地处理一般选项和子命令特定选项?或者最好的方法是手动处理一般选项和子命令?
一个肮脏的例子将非常感激.
非常感谢.
解决方法
你是正确的,为zsh写的完成脚本可能相当困难.你最好的办法是用现有的一个作为指导.对于初学者,imo来说,git的方法太多了.你可以使用这个repo:
https://github.com/zsh-users/zsh-completions
对于你的问题,你使用状态的概念.您可以在列表中定义子命令,然后通过$state来标识您所在的命令.然后定义每个命令的选项.你可以在完成脚本中看到这一点.简化版本如下:
_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是一个子命令的列表,其中包含每个子命令的描述),然后来参数.参数是根据您选择的子命令构建的.请注意,如果共享参数,则可以对多个子命令进行分组.
与人zshcompsys,你可以找到更多关于整个系统的信息,虽然它有点密集.