Как отложить завершение оболочки для другой команды в bash и zsh? - PullRequest
10 голосов
/ 01 апреля 2019

Я пытаюсь написать утилиту сценария оболочки, которая упаковывает другие утилиты оболочки в один CLI, и пытаюсь заставить завершение оболочки работать в zsh и bash.

Например, допустим, CLI назван util:

util aws [...args] #=> runs aws
util docker [...args] #=> runs docker
util terraform [...args] #=> runs terraform

В идеале мне хотелось бы, чтобы в zsh и bash было разрешено говорить «завершить эту подкоманду X как другую команду Y» независимо от реализации завершения для завернутых сценариев.

Что-то вроде:

compdef 'util aws'='aws'
compdef 'util docker'='docker'
compdef 'util terraform'='terraform'

Целью растяжения было бы допустить завершение произвольной подкоманды подкоманде в другом двоичном файле:

util aws [...args] #=> completes against `aws`
util ecr [...args] #=> completes against `aws ecr`

Возможно ли что-нибудь из этого? Я пытался эмулировать сценарии завершения отдельных двоичных файлов, однако существует значительное различие в том, как пишутся другие сценарии завершения.

1 Ответ

1 голос
/ 13 апреля 2019

Я ничего не знаю о zsh, но могу предложить решение для bash. Он делегирует, используя функцию _complete (которую я нашел после предложения Муру - хороший вызов!).

Во втором разделе функции представлены дополнения к самой команде util, которая, как я предполагаю, здесь будет просто списком подкоманд. Конечно, вы можете приспособить это к вашим потребностям.

Первый раздел обрабатывает делегирование в случае, когда была введена полная подкоманда, и, необязательно, цель для завершения в соответствии с завершением подкоманды.

Функция

_delegate() {
  local cur subs
  cur="${COMP_WORDS[COMP_CWORD]}" # partial word, if any
  subs="ssh aws docker terraform"
  if [[ $COMP_CWORD == 2 ]]; then
    # Two whole words before the cursor - delegate to the second arg
    _command $2
  else
    # complete with the list of subcommands 
    COMPREPLY=( $(compgen -W "${subs}" -- ${cur}) )
  fi
}

Установка

njv@pandion:~$ complete -F _delegate util

Демо

1d [njv@eidolon:~] $ util
aws        docker     ssh        terraform
1d [njv@eidolon:~] $ util ssh
::1                        gh                         ip6-localhost              ubuntu.members.linode.com
eidolon                    github.com                 ip6-loopback
ff02::1                    ip6-allnodes               localhost
ff02::2                    ip6-allrouters             ubuntu
1d [njv@eidolon:~] $ util ssh ip6-
ip6-allnodes    ip6-allrouters  ip6-localhost   ip6-loopback
...