Я працюю здебільшого у гвімі та багатьох терміналах. Спочатку я вважав за краще відкрити всі свої файли в одному екземплярі 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і vim» -s, але я думаю, що я можу це елегантно впоратися з --роздільником.
TLDR; Отже, як створити сценарій завершення, який поєднує в собі _argumentsваріанти як _rvі _vim? Я вважаю за краще повторно використовувати, _vimякщо можливо, замість того, щоб вставити копію в список аргументів _rv.
Ось моя _rv. Оновлено 6.10.2014 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.