Estou começando a aprender sobre scripts de conclusão do bash e comecei a trabalhar em um para uma ferramenta que uso o tempo todo. Primeiro construí o script usando uma lista de opções:
_zf_comp()
{
local cur prev actions
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
actions="change configure create disable enable show"
COMPREPLY=($(compgen -W "${actions}" -- ${cur}))
return 0
}
complete -F _zf_comp zf
Isso funciona bem. Em seguida, decidi criar dinamicamente a lista de ações disponíveis. Eu coloquei o seguinte comando:
zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*3\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\-", $1); print $1}' | tr \n " " | sed 's/^ *\(.*\) *$//'
O que basicamente faz o seguinte:
- Pega todo o texto no comando "zf" depois de "Provedores e suas ações:"
- Pega todas as linhas que começam com "zf" (eu tive que fazer algum trabalho interessante aqui porque o comando ZF imprime em cores)
- Pegue a segunda parte do comando e remova todos os espaços dela (a parte de espaços provavelmente não é mais necessária)
- Classifique a lista
- Livrar-se de quaisquer duplicatas
- Traçar traços (adicionei isso ao tentar depurar o problema - provavelmente não necessário)
- Apare todas as novas linhas
- Apare todos os espaços iniciais e finais
O comando acima produz:
$ zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*3\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\-", $1); print $1}' | tr \n " " | sed 's/^ *\(.*\) *$//'
change configure create disable enable show
$
Então, parece-me que está produzindo exatamente a mesma string que eu tinha no meu roteiro original. Mas quando eu faço:
_zf_comp()
{
local cur prev actions
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
actions='zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*3\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\-", $1); print $1}' | tr \n " " | sed 's/^ *\(.*\) *$//''
COMPREPLY=($(compgen -W "${actions}" -- ${cur}))
return 0
}
complete -F _zf_comp zf
Meu preenchimento automático começa a funcionar. Primeiro, ele não completará automaticamente qualquer coisa com um "n", e segundo, quando ele fizer autocomplete ("zf create", por exemplo), ele não me permitirá voltar atrás no comando concluído.
O primeiro problema em que estou completamente perplexo. O segundo que estou pensando talvez tenha a ver com os caracteres de escape do texto colorido.
Alguma ideia? Está me deixando louco!