Como posso preencher automaticamente cada parâmetro de uma maneira diferente?

Como posso preencher automaticamente cada parâmetro de uma maneira diferente?

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:actionmessage

_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 _argumentsas 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_pgfunçã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 $USERparece 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 seu grepcomando mais preciso e poderá combiná-lo com grep.
  • Ao chamar compadduma 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_filesque 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 "$@"

informação relacionada