Возможно, это не тот ответ, который вы ищете, но я не удержался от написания сценария VIM для этого. Я положил его в мой .vimrc, и он работает для меня:
map ; :call Semicolon()<CR>
function Semicolon()
let s:pos1 = getpos(".")
normal! ;
let s:pos2 = getpos(".")
if s:pos1 == s:pos2
normal! 2;
endif
endfunction
Основная идея заключается в том, что ;
не перейдет к следующему совпадению, а 2;
(если есть совпадение). Сценарий поддерживает ;
после любого из tTfF
. Самый простой способ реализовать команду ,
- написать аналогичную функцию для этого.
EDIT
Изменил сценарий после отличного предложения Люка
EDIT2
Хорошо, эти вещи всегда сложнее, чем я думаю. Текущее сопоставление имеет следующие проблемы:
- Предположим, вы выполнили поиск как
tr
выше. Что теперь делать d;
или c;
? Насколько я понимаю, они должны удалить или изменить до первого r
, а не второго. Эту проблему можно решить, выполнив сопоставление только для обычного и визуального режимов, а не для режима ожидания оператора.
- Текущее отображение не работает в визуальном режиме. то есть, если вы наберете
v;;;;
после первого ;
, редактор больше не будет в визуальном режиме (из-за :call
). Это можно решить, вызвав функцию, используя @=
вместо :call
.
Так что теперь я получаю следующее в моем .vimrc (я также сделал одну функцию для ,
и ;
):
" Remap ; and , commands so they also work after t and T
" Only do the remapping for normal and visual mode, not operator pending
" Use @= instead of :call to prevent leaving visual mode
nmap ; @=FixCommaAndSemicolon(";")<CR>
nmap , @=FixCommaAndSemicolon(",")<CR>
vmap ; @=FixCommaAndSemicolon(";")<CR>
vmap , @=FixCommaAndSemicolon(",")<CR>
function FixCommaAndSemicolon(command)
let s:pos1 = getpos(".")
execute "normal! " . a:command
let s:pos2 = getpos(".")
if s:pos1 == s:pos2
execute "normal! 2" . a:command
endif
return ""
endfunction