У меня есть функция 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:action
message
_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 "$@"