Сделайте разбор самостоятельно
Если вы используете :help <q-args>
, вы получите строку в кавычках, которую вы можете split()
на две разделенные пробелами части:
command! -nargs=+ Sub execute '%substitute/' . split(<q-args>, ' ')[0] . '/' . split(<q-args>, ' ')[1] . '/g'
Мы можем избежать синтаксического анализа дважды с помощью небольшого количества метапрограммирования (call()
) и printf()
:
command! -nargs=+ Sub execute call('printf', ['%%substitute/%s/%s/g'] + split(<q-args>, ' '))
Это работает, но обработка ошибок все еще не хороша (если вы передадите только один аргумент, он будет жаловаться на E766: Insufficient arguments for printf()
). Вы получите больше контроля, извлекая код в функцию :function
Vim может разобрать аргументы
Отдельная :function
также позволяет Vim выполнять анализ аргументов за вас с помощью :help <f-args>
.
command! -nargs=+ Sub call Sub(<f-args>)
function! Sub( ... )
execute printf('%%substitute/%s/%s/g', a:1, a:2)
endfunction
С помощью функции вы можете легко проверить правильность количества аргументов:
function! Sub( ... )
if a:0 != 2
echo "Need two arguments"
return
endif
...
Недостатком функции является то, что ошибки (например, шаблон не совпадает, буфер не модифицируется) приводят к многострочному недружественному сообщению об ошибке. try...catch
нужно будет использовать для получения красивого однострочного сообщения об ошибке.
Бонус: где его взять оттуда
- Поскольку вы скрываете команду
:s
(и используемые разделители) от пользователя, я думаю, что не обязательно требовать экранирования разделителей. Используйте escape(a:1, '/')
вместо a:1
/ a:2
.
- С
:help :command-range
вы по-прежнему можете использовать команду по умолчанию для работы со всем буфером, но также разрешать пропуск других диапазонов.
Также подумайте, действительно ли команда набирает вес. Независимо от используемого синтаксического анализа, пробелы в аргументах проблематичны, недостаток, которого нет у оригинала :s
. Единственное преимущество, которое я вижу, заключается в том, что набрать текст немного проще, но того же можно добиться с помощью сопоставления (ей), которое предварительно заполняет командную строку командой не завершено :s
и помещает курсор прямо посередине.