Estou adicionando o bash-completion a uma ferramenta existente.
Depois que alguém passar a -s
bandeira, gostaria de oferecer várias opções de conclusão do bash:
Closed
Feedback
"In Progress"
New
Rejected
Resolved
O espaço "In Progress"
está causando um problema.
#!/usr/bin/env bash
_remote-redmine()
{
local cur
COMPREPLY=()
cur=${COMP_WORDS[$COMP_CWORD]}
case "${COMP_WORDS[($COMP_CWORD-1)]}" in
-s)
s_opts=( "New" "In Progress" "Resolved" "Feedback" "Closed" "Rejected" )
COMPREPLY=( $( compgen -W "${s_opts[*]}" -- "$cur") )
;;
esac
return 0
}
complete -F _remote-redmine remote-redmine
Quando executo a ferramenta, recebo:
$ remote-redmine -s <tab><tab>
Closed Feedback In New Progress Rejected Resolved
Mas eu gostaria de obter:
$ remote-redmine -s <tab><tab>
Closed Feedback "In Progress" New Rejected Resolved
ou
$ remote-redmine -s <tab><tab>
Closed Feedback In\ Progress New Rejected Resolved
Coisas que tentei:
s_opts=( ... "In\ Progress" ... )
: Sem diferenças_opts( ... "In\\ Progress" ...)
: Sem diferenças_opts( ... "In\\\ Progress" ...)
: Duas opções sãoIn\
eProgress
s_opts( ... "\"In Progress\"" ...)
: Sem diferençacompgen -o nospace ...
: Sem diferençacompgen -o noquote ...
: Sem diferençaPelo menos
compgen
pode colocarIn Progress
uma linha, mas isso não se traduz emcomplete
$ compgen -W 'New "In Progress"' New In Progress
Escapar de aspas extras ajuda
compgen
, mas isso não se traduz emcomplete
:$ compgen -W 'New "\"In Progress\""' New "In Progress"
Escapar do espaço três vezes ajuda, mas ainda não se traduz em
complete
:$ compgen -W 'New In\\\ Progress' New In\ Progress
Achei que escapar do espaço sete vezes seria promissor porque resolveria
complete
alguns deles, mas isso também não ajudou:$ compgen -W 'New In\\\\\\\ Progress' New In\\\ Progress ... $ remote-redmine -s <tab><tab> ... In\\\ New Progress ...
Ignorar
compgen
funcionará, mas perco o preenchimento automático em guias únicas e a filtragem em guias duplasCOMPREPLY=( ... 'In\ Progress' ... ) COMPREPLY=( ,,, '"In Progress"' ... )
Isso tem a ver com a divisão de palavras e o valor padrão de IFS, sem surpresa.
Em
A expansão do array
[*]
une os elementos do array em uma única string, usando o primeiro caractereIFS
como separador. É espaço por padrão, portanto a distinção entre um espaço em um valor e um espaço como separador é perdida. Felizmente,compgen -W
interpreta o argumento como uma sequência de valores separados porIFS
caracteres, por isso funciona corretamente[*]
se você apenas mudarIFS
para algo parecido:
ou qualquer outra coisa que não apareça nos valores.Então, em
você está dividindo implicitamente a string impressa usando
compgen
(IFS
e passando-a por globbing), mascompgen
parece imprimir especificamente os valores separados por novas linhas. Fazer isso com a divisão exigiria a configuraçãoIFS
da nova linha, mas seria realmente mais adequado para leitura comreadarray
, já que ele usa novas linhas de qualquer maneira e não se glob.Então, você poderia fazer
Ou, como uma nova linha funciona em ambos os lugares, você pode simplesmente definir
IFS=$'\n'
e dividir a saída como antes, mas ainda deve desativar o globbing durante a função, e isso é mais uma parte do estado global para salvar e restaurar.