Eu tenho uma função chamada load_pg, que é definida assim:
load_pg () {
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U $1 -d $2 $3
}
E estou tentando preencher automaticamente cada parâmetro, com o seguinte código:
#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*)
}
Infelizmente, nada acontece quando pressiono TAB. O que estou fazendo de errado? Eu tentei usar o código doseguinte resposta
Responder1
Primeiro obstáculo: a sintaxe de um argumento _arguments
é onde não é permitido ficar vazio. Se você adicionar uma mensagem, verá algum progresso:n:message:action
message
_arguments -s \
"1:username:_ldpguser" \
"2:database:_ldpgdb" \
"3:dump file:_ldpgfile"
O próximo obstáculo é que as funções auxiliares são definidas após _arguments
as execuções, portanto, na primeira vez que você completar os argumentos, receberá uma mensagem de erro reclamando que uma das funções não existe. Defina as funções antes de usá-las. Melhor, torne explícita a definição da _load_pg
função e chame-a no final do arquivo carregado automaticamente. Isso parece desajeitado, mas é assim que a maioria das funções de conclusão multifuncionais fornecidas com o zsh são escritas.
#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 "$@"
Isso fornece o núcleo da função. Você então desejará limpar as funções individuais. No mínimo:
compadd $USER
parece inútil: se você quiser chamar a função apenas com seu nome de usuário, por que não incorporá-la? Para completar nomes de usuários, chame_users
.- A substituição de comandos substitui todos os espaços em branco. Para dividir linhas, use o
@
ef
sinalizadores de expansão de parâmetro. Você provavelmente também deve tornar seugrep
comando mais preciso e poderá combiná-lo comgrep
. - Ao chamar
compadd
uma ação de_arguments
, passe as opções contextuais em$expl
. - Você pode fornecer uma descrição para conclusões com
_describe
. $(ls *.dump*)
é uma maneira complicada de escrever “*.dump*
e, se não houver correspondência, faça algo que dependa das configurações atuais do shell”.Não analise a saída dels
, ok? Você poderia usarN
qualificador globalter uma lista vazia de conclusões quando não há correspondência. No entanto, você deve ligar_files
que cuida do preenchimento dos arquivos nos subdiretórios, entre outras sutilezas.
#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 "$@"