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] .