Вы правы в том, что написание скриптов завершения для zsh может быть довольно сложным.Лучше всего использовать существующую в качестве руководства.Один для мерзавца это слишком много для начинающего, 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 вы можете найти больше информации обо всей системе, хотя она несколько плотная.