Isso parece algo como um problema XY; o que exatamente motiva essa mudança da conclusão por meio de uma opção fornecida? Como poderia a mudança ser feita através de uma variável de ambiente, ou por que a conclusão precisa variar?
De qualquer forma, um arquivo em algum momento durante o processamento da opção pode causar problemas, dependendo de onde -f ...
aparece em relação a outras coisas na linha de comando. Além disso, o código de conclusão será chamado repetidamente, de modo que a manutenção do estado entre diferentes chamadas para a mesma e novas instâncias de um comando podem ser complicadas. E também $(cat /tmp/file_with_opts)
é ruim, pois é desnecessariamente bifurcada em cat
e, em seguida, divide o conteúdo em ... bem, quem sabe.
Com esses problemas em mente, uma maneira de descobrir quais opções estão disponíveis é adicionar algo como set > ~/tmp/what-is-set
a uma parte apropriada do código de conclusão e, em seguida, pressionar a tecla com o cursor em vários locais com e sem -f ...
option e, em seguida, verifique o arquivo de saída para ver as coisas que estão disponíveis para um script de conclusão:
% grep file_ what-is-set
BUFFER='foo -f file_with_opts '
RBUFFER=' -f file_with_opts '
opt_args=( [-f]=file_with_opts )
words=( foo '' -f file_with_opts )
Nesse caso, terminei a tabulação logo após foo
e antes de -f ...
, portanto, para variar o comportamento de conclusão, era possível verificar BUFFER
ou, melhor ainda, a words
como BUFFER
poderia ter -f ...
de outros comandos não relacionados ao seu programa que podem confundir seu script de conclusão.
Portanto, se passarmos por cima de words
, podemos variar o arquivo que será lido, dependendo se (sem muita verificação de erros) a opção -f ...
estiver presente com algo como:
#compdef foo
local curcontext="$curcontext" state line ret=1
_arguments -C -S \
'-f[input file]:filename:_files' \
'*:options:->vary' \
&& ret=0
case "$state" in
vary)
integer i
local optsfile
#set > ~/tmp/what-is-set
# default filename
optsfile=~/tmp/file_with_opts
for (( i = 1; i <= $#words - 1; i++ )); do
if [[ $words[$i] == -f ]]; then
optsfile=$words[$((i+1))]
break
fi
done
# cat-free read of file with split on newlines
t=(${(f)"$(<$optsfile)"})
_wanted t expl "available options" compadd -a t
;;
esac
return $ret
Pode ser útil estudar as conclusões existentes no diretório $fpath[-1]
.