Подтвердить что ты не робот

Завершение, когда программа имеет подкоманды

Я написал инструмент командной строки, который использует подкоманды, подобные 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.) для правильной обработки концепции подкоманд, включая обработку общих параметров и подкоманды конкретные варианты? Или лучше всего будет вручную обрабатывать общие параметры и подкоманду?

Приятный пример будет очень оценен.

Большое спасибо.

4b9b3361

Ответ 1

вы правы в том, что скрипты для записи для zsh могут быть довольно сложными. Лучше всего использовать существующую в качестве руководства. Один для git слишком много для новичка, imo. Вы можете использовать это репо:

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

Что касается вашего вопроса, вы используете концепцию состояния. Вы определяете свои подкоманды в списке, а затем определяете через $state, в какой команде вы находитесь. Затем вы определяете параметры для каждой команды. Вы можете увидеть это в завершении script для воспроизведения. Ниже приведена упрощенная версия:

_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 вы можете найти больше информации обо всей системе, хотя она несколько плотная.