Eu trabalho principalmente no gvim e em muitos terminais. Originalmente, eu preferia abrir todos os meus arquivos em uma única instância do vim. Para esse fim, usei um alias para abrir arquivos dos meus terminais no atual 'servidor vim'.
alias rv="gvim --remote-silent"
Mas ter muitos arquivos de vários projetos abertos em uma única instância do vim afeta minha produtividade, por isso estou atualizando meu alias para uma função.
# main function
rv() {
local args options server
options=$(getopt -o hils:t: -l "help,info,list,set:,target:" -- "$@")
if [[ $? -ne 0 ]]; then
echo "Failed to parse options."
return 1
fi
# a little magic, necessary when using getopt
eval set -- "$options"
# go through the options with a case and use shift to analyze one option at a time.
while true; do
case "$1" in
-h|--help)
echo "Usage: $0 [-hil] [--help] [--info] [--list]";
echo " $0 {-s | --set} <name> [<file1 file2...>]";
echo " $0 {-t | --target} <name>] <file1 file2...>";
return 0;;
-i|--info)
gvim_show_info;
return 0;;
-l|--list)
gvim_list_servers;
return 0;;
-s|--set)
gvim_set_server_name ${2:u};
shift 2;;
-t|--target)
server="$2";
shift 2;;
--)
shift;
break;;
esac
done
if [[ "$#" -eq 0 ]]; then
# if no files specified...
if [[ -n "$server" ]]; then
# throw error if --target option was specified.
echo "Error! --target requires one or more filenames."
return 1;
fi
else
# if files were specified...
if [[ -n "$server" ]]; then
# if --target was specified
gvim_run_remote $server "$@"
else
gvim_run_remote $(gvim_get_default_server) "$@"
fi
fi
return 0;
}
Agora, este novo rv
possui suas próprias opções. Eu posso usá-lo para:
- lista servidores vim disponíveis (-l --list)
- defina o servidor vim padrão para o shell atual (-s --set)
- mostre o servidor vim padrão (-i --info)
- abrir arquivos em um servidor vim específico (-t --target)
- abra arquivos no servidor vim padrão:
rv files...
No entanto, como estou usando uma função para, em rv
vez de um alias, perco a conclusão do zsh de que desfrutei anteriormente. Eu li sobre a criação de uma função de conclusão,, _rv
que mostrará rv
as opções, mas quero combinar minhas opções de conclusão com as opções de conclusão do vim existentes. Eu sei que pode haver alguns conflitos com rv
's' -s
e vim
's -s
, mas acho que posso lidar com isso de maneira elegante com o --
separador.
TLDR; Então, como crio um script de conclusão que combina as _arguments
opções para ambos _rv
e _vim
? Prefiro reutilizar, _vim
se possível, em vez de copiar e colar sua lista de argumentos _rv
.
Aqui está o meu _rv
. Atualizado 2014/6/10 16:10
#compdef rv
_rv() {
typeset -A opt_args
local alternatives
alternatives=(
'args:rv options:_rv_options'
'files:file:_vim_files'
)
_alternative $alternatives && return 0
return 1
}
_rv_options() {
local arguments
arguments=(
'(-i -l -s -t --info --list --set --target)'{-h,--help}'[Print usage info.]'
'(-h -l -s -t --help --list --set --target)'{-i,--info}'[Print default vim server. As stored in $GVIM_SERVER.]'
'(-i -h -s -t --info --help --set --target)'{-l,--list}'[Print list of existing vim servers.]'
'(-i -h -l -t --info --help --list --target)'{-s,--set}'[Set default vim server for the current shell.]:vim servers:_rv_vim_servers'
'(-i -h -l -s --info --help --list --set)'{-t,--target}'[Open files in a particular vim server.]:vim servers:_rv_vim_servers'
)
_arguments -s -C $arguments && return 0
return 1
}
_rv_vim_servers() {
local -a servers
servers=( ${(f)"$(_call_program servers vim --serverlist 2>/dev/null)"} )
_wanted servers expl server compadd -M 'm:{a-z}={A-Z}' -a servers && return
}
# invoke the completion command during autoload
_rv "$@"
Comportamento Atual
Atualmente, a _rv
conclusão é utilizável, mas não ideal.
- Quando digito
rv <TAB>
, não vejo as opções do vim. Apenas opções de rv e caminhos de arquivo são exibidos._vim
está completando caminhos de arquivos para mim, então viva isso! - Quando digito
rv -s <TAB>
, vejo a lista de servidores vim, mas também os caminhos dos arquivos são exibidos. Um arquivo não é permitido neste momento no comando e não deve aparecer no preenchimento automático.
Comportamento esperado
- Quando digito
rv <TAB>
, espero ver: 1) opções rv, 2) opções vim, 3) lista de caminhos de arquivos - Quando digito
rv -s <TAB>
, espero ver: 1) nomes de servidores vim (conforme fornecido por_rv_vim_servers
. - Quando digito
rv /valid/file/path/<TAB>
, espero ver apenas uma lista de caminhos de arquivos. Como_vim
já tem esse recurso, eu preferiria confiar nele.
compdef
possui uma -n
opção que diz "impede que quaisquer conclusões já definidas para o comando ou contexto sejam substituídas". Então, você já tentou compdef _vim rv
seguir compdev -n _rv rv
?
_vim
arquivo original , mas antes de substituir a _arguments
função por uma função local personalizada? Ao fazer isso, você obteria os argumentos _vim
. Talvez com um processo zsh separado.