Как можно автозаполнить каждый параметр по-разному?

Как можно автозаполнить каждый параметр по-разному?

У меня есть функция load_pg, которая определена следующим образом:

load_pg () {
    pg_restore --verbose --clean --no-acl --no-owner -h localhost -U $1 -d $2 $3
}

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

#compdef load_pg
_arguments -s \
  "1::_ldpguser" \
  "2::_ldpgdb" \
  "3::_ldpgfile"

_ldpguser () {
  compadd $USER
}

_ldpgdb () {
  compadd $(cat config/database.yml | grep -i database | awk '{print $2}')
}

_ldpgfile () {
  compadd $(ls *.dump*)
}

К сожалению, ничего не происходит, когда я нажимаю TAB. Что я делаю не так? Я пробовал использовать код изследующий ответ

решение1

Первое препятствие: синтаксис аргумента to, _argumentsгде не допускается быть пустым. Если вы добавите сообщение, вы увидите некоторый прогресс:n:message:actionmessage

_arguments -s \
  "1:username:_ldpguser" \
  "2:database:_ldpgdb" \
  "3:dump file:_ldpgfile"

Следующее препятствие заключается в том, что вспомогательные функции определяются после _argumentsвыполнения, поэтому при первом завершении аргументов вы получите сообщение об ошибке, жалующееся на то, что одна из функций не существует. Определите функции перед их использованием. Лучше сделайте определение функции _load_pgявным и вызовите ее в конце автоматически загружаемого файла. Это выглядит неуклюже, но именно так написано большинство многофункциональных функций завершения, поставляемых с zsh.

#compdef load_pg

_ldpguser () {
  compadd $USER
}

_ldpgdb () {
  compadd $(cat config/database.yml | grep -i database | awk '{print $2}')
}

_ldpgfile () {
  compadd $(ls *.dump*)
}

_load_pg () {
  _arguments -s \
    "1:user:_ldpguser" \
    "2:database:_ldpgdb" \
    "3:dump file:_ldpgfile"
}

_load_pg "$@"

Это дает вам ядро ​​функции. Затем вам нужно будет очистить отдельные функции. Как минимум:

  • compadd $USERкажется бессмысленным: если вы хотите вызывать функцию только с вашим именем пользователя, почему бы не встроить ее? Чтобы завершить имена пользователей, вызовите _users.
  • Подстановка команды заменяет все пробелы. Чтобы разделить строки, используйте @иf флаги расширения параметров. Вам также, вероятно, следует сделать вашу grepкоманду более точной, и вы, возможно, сможете объединить ее с grep.
  • При вызове compaddдействия из _argumentsпередайте ему контекстные параметры в $expl.
  • Вы можете предоставить описание для дополнений с_describe.
  • $(ls *.dump*)— это замысловатый способ написать « *.dump*и если совпадений нет, сделать что-то в зависимости от текущих настроек оболочки».Не анализируйте выводls, ммм ладно? Вы могли бы использоватьN квалификатор globчтобы иметь пустой список завершений, когда нет совпадений. Однако вместо этого вы должны вызвать_filesкоторый, помимо прочих тонкостей, заботится о заполнении файлов в подкаталогах.
#compdef load_pg

_ldpgdb () {
  compadd $expl[@] -- "${(@f)$(<config/database.yml grep -i database | awk '{print $2}')}"
}

_load_pg () {
  _arguments -s \
    '1:user:_users' \
    '2:database:_ldpgdb' \
    '3:dump file:_files -g "*.dump*"'
}

_load_pg "$@"

Связанный контент