Como posso autocompletar cada parâmetro de uma maneira diferente?

2

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
}

Estou tentando autocompletar 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? Tentei usar o código da seguinte resposta

    
por Geo 09.10.2013 / 11:37

1 resposta

2

Primeiro obstáculo: a sintaxe de um argumento para _arguments é n:message:action , em que message não pode ficar vazio. Se você adicionar uma mensagem, verá algum progresso:

_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 depois que _arguments for executado, então, na primeira vez que você completar os argumentos, você 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 função _load_pg e chame-a no final do arquivo carregado automaticamente. Isso parece desajeitado, mas é o modo como a maioria das funções de conclusão multifuncionais fornecidas com o zsh é escrita.

#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 lhe dá o núcleo da função. Você vai querer 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 criá-la? Para completar nomes de usuários, chame _users .
  • Substitui substitutos de comando em todos os espaços em branco. Para dividir linhas, use os sinalizadores de expansão de parâmetro @ e f . Você provavelmente também deve tornar seu comando grep mais preciso, e você poderá combiná-lo com grep .
  • Quando você chamar compadd em uma ação de _arguments , passe as opções contextuais em $expl .
  • Você pode fornecer uma descrição para as conclusões com _describe .
  • $(ls *.dump*) é uma maneira complicada de escrever " *.dump* e, se não houver correspondência, fazer algo que dependa das configurações atuais da shell". Não analise a saída de ls , mmmkay? Você pode usar o N qualificador de glob para ter uma lista vazia de conclusões quando houver sem correspondência. No entanto, você deve chamar _files que cuida da conclusão dos arquivos em 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 "$@"
    
por 10.10.2013 / 02:36