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

Многоуровневое Bash Завершение

В настоящее время у меня есть файл завершения Bash, который завершает единственный параметр из списка разрешенных команд для script (называемый "pbt" ). Это рабочий файл Bash Completion:

_pbt_complete()
{
  local cur goals

  COMPREPLY=()
  cur=${COMP_WORDS[COMP_CWORD]}
  goals='asadmin clean deploy'
  cur=`echo $cur`
  COMPREPLY=($(compgen -W "${goals}" ${cur}))
}

complete -F _pbt_complete pbt

Итак, если я звоню

pbt <tab>

Bash завершается всеми разрешенными командами (asadmin, clean, deploy), что хорошо.

Теперь я хочу добавить "второй" уровень к завершению. Так, например, если я напечатаю

pbt asadmin <tab>

он должен заполнить все параметры, доступные только внутри asadmin - "environment" (которые я также определю внутри файла завершения Bash), например, pbt asadmin [start-domain|stop-domain] Но если я напечатаю

pbt deploy <tab>

он должен выполнить другой набор параметров, например pbt deploy [all|current]. Поэтому параметры для второй команды всегда должны зависеть от первой команды. Как я могу это сделать в файле завершения?

4b9b3361

Ответ 1

Благодаря комментарию mkb я просмотрел p4-example, который был - в отличие от примера Git;) - достаточно просто для меня адаптировать его к моему делу. Вот рабочая версия, которая делает именно то, что я просил:

have pbt &&
_pbt_complete()
{
  local cur prev

  COMPREPLY=()
  cur=${COMP_WORDS[COMP_CWORD]}
  prev=${COMP_WORDS[COMP_CWORD-1]}

  if [ $COMP_CWORD -eq 1 ]; then
    COMPREPLY=( $(compgen -W "asadmin deploy" -- $cur) )
  elif [ $COMP_CWORD -eq 2 ]; then
    case "$prev" in
      "asadmin")
        COMPREPLY=( $(compgen -W "start-domain stop-domain" -- $cur) )
        ;;
      "deploy")
        COMPREPLY=( $(compgen -W "all current" -- $cur) )
        ;;
      *)
        ;;
    esac
  fi

  return 0
} &&
complete -F _pbt_complete pbt

Ответ 2

Вы можете посмотреть, как делается завершение для git, в качестве примера. (Это занимает 2257 строк определений функций и дополнительных 14 переменных в моей настройке bash.)