程序具有子命令时完成 [英] Completion when program has sub-commands

查看:96
本文介绍了程序具有子命令时完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个命令行工具,该工具使用类似于Mercurial,Git,Subversion& c.的子命令,因为它的一般用法是:

>myapp [OPTS] SUBCOMMAND [SUBCOMMAND-OPTS] [ARGS]

例如

>myapp --verbose speak --voice=samantha --quickly "hello there"

我现在正在为它完成Zsh的构建,但是很快发现它是一个非常复杂的野兽.我已经看过_hg_git补全,但是它们非常复杂并且方法不同(我很难理解它们),但是它们似乎都分别处理每个子命令.

有人知道是否可以使用内置函数(_arguments_valuespick_variant& c.)正确处理子命令的概念,包括处理常规选项和子命令具体选项合适吗?还是最好的方法是手动处理常规选项和子命令?

一个点头的例子将不胜感激.

非常感谢.

解决方案

您是对的,因为为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 ,您可以找到有关整个系统的更多信息,尽管它有些密集.

I have written a command-line tool that uses sub-commands much like Mercurial, Git, Subversion &c., in that its general usage is:

>myapp [OPTS] SUBCOMMAND [SUBCOMMAND-OPTS] [ARGS]

E.g.

>myapp --verbose speak --voice=samantha --quickly "hello there"

I'm now in the process of building Zsh completion for it but have quickly found out that it is a very complex beast. I have had a look at the _hg and _git completions but they are very complex and different in approach (I struggle to understand them), but both seem to handle each sub-command separately.

Does anyone know if there a way using the built in functions (_arguments, _values, pick_variant &c.) to handle the concept of sub-commands correctly, including handling general options and sub-command specific options appropriately? Or would the best approach be to manually handle the general options and sub-command?

A noddy example would be very much appreciated.

Many thanks.

解决方案

you are right in that writing completion scripts for zsh can be quite difficult. Your best bet is to use an existing one as a guide. The one for git is way too much for a beginner, imo. You can use this repo:

https://github.com/zsh-users/zsh-completions

As for your question, you have use the concept of state. You define your subcommands in a list, and then identify via $state which command you are in. Then you define the options for each command. You can see this in the completion script for play. A simplified version is below:

_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

(If you are going to paste this, use the original source, as this won't work).

It looks daunting, but the general idea is not that complicated. The subcommand comes first (_play_cmds is a list of subcommands with a description for each one), then come the arguments. The arguments are built based on which subcommand you are choosing. Note that you can group multiple subcommands, if they share arguments.

with man zshcompsys you can find more info about the whole system, although it is somewhat dense.

这篇关于程序具有子命令时完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆