Я работаю в основном в gvim и многих терминалах. Первоначально я предпочитал открывать все мои файлы в одном экземпляре vim. Для этого я использовал псевдоним, чтобы открывать файлы с моих терминалов на текущем «сервере vim».
alias rv="gvim --remote-silent"
Но наличие множества файлов из нескольких проектов, открытых в одном экземпляре vim, влияет на мою производительность, поэтому я обновляю свой псевдоним до функции.
# 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;
}
Теперь у этого нового rv
есть свои варианты. Я могу использовать это, чтобы:
- список доступных серверов vim (-l --list)
- установить сервер vim по умолчанию для текущей оболочки (-s --set)
- показать сервер vim по умолчанию (-i --info)
- открывать файлы на определенном сервере vim (-t --target)
- открыть файлы на сервере vim по умолчанию:
rv files...
Тем не менее, поскольку я использую функцию rv
вместо псевдонима, я теряю завершение zsh, которое ранее мне нравилось. Я прочитал о создании функции завершения _rv
, которая покажет rv
опции, но я хочу объединить мои варианты завершения с существующими вариантами завершения vim. Я знаю, что могут быть некоторые конфликты с rv
's' -s
и vim
's' -s
, но я полагаю, что я могу справиться с этим элегантно с --
разделителем.
TLDR; Итак, как мне создать скрипт завершения, который сочетает в себе _arguments
опции для обоих _rv
и _vim
? Я предпочитаю использовать повторно, _vim
если это возможно, вместо копирования в список своих аргументов _rv
.
Вот мой _rv
. Обновлено 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 "$@"
Текущее поведение
В настоящее время _rv
завершение будет полезным, но не идеальным.
- Когда я печатаю
rv <TAB>
, я не вижу опции vim. Отображаются только параметры rv и пути к файлам._vim
заканчивает пути к файлам для меня, так что ура! - Когда я печатаю
rv -s <TAB>
, я вижу список серверов vim, но также отображаются пути к файлам. Файл не разрешен в этой точке в команде, и не должен появляться в автозаполнении.
Ожидаемое поведение
- Когда я печатаю
rv <TAB>
, я ожидаю увидеть: 1) опции rv, 2) опции vim, 3) список путей к файлам - Когда я печатаю
rv -s <TAB>
, я ожидаю увидеть: 1) имена серверов vim (как указано в_rv_vim_servers
. - Когда я печатаю
rv /valid/file/path/<TAB>
, я ожидаю увидеть только список путей к файлам. Поскольку_vim
такая возможность уже есть, я бы предпочел на нее положиться.
compdef
имеет -n
параметр, который говорит, что «предотвращает перезапись любых завершений, уже определенных для команды или контекста». Итак, вы пытались compdef _vim rv
следовать compdev -n _rv rv
?
_vim
файл, но перед этим переписать _arguments
функцию с помощью локальной функции? Тем самым вы получите аргументы от _vim
. Может быть, с отдельным процессом Zsh.