1

我想为具有以下调用约定的程序编写 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

如何将下一个状态设置为与旧状态相同?哪个命令有类似的调用约定,所以我可以看一下这个命令的补全代码?

4

1 回答 1

0

主要问题是运算以 a 开头--,因此很难在参数中找到它们。例如,在 git 中,所有子命令都只是一个没有破折号的单词。所以git解决这个问题是这样的:

  1. 查找不带破折号的第一个参数,因为这必须是子命令
  2. 基于子命令向该子命令的命令行参数分派。

所以 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

我知道,有很多重复,但我想你明白了。另请注意,我将--installand--upgrade选项从一般情况移至操作情况。如果你不这样做,如果你想在之后完成,你就会失去论点--install或者--upgrade

于 2014-07-24T18:46:38.617 回答