Подтвердить что ты не робот

Поведение; повторять последнюю команду t беспокоит меня. Можете ли вы помочь мне сделать это лучше?

Хорошо, предположим, что у нас есть строка текста:

[s]tackoverflow rocks

где скобки показывают местоположение курсора в обычном режиме. После нажатия tr вы получите:

stackov[e]rflow rocks

Теперь для забавной части. Что произойдет, если вы нажмете ;, чтобы повторить команду? Ничего! Vim находит следующий "r" (сразу справа от курсора) и позиционирует себя слева от него (где он уже был).

Я бы предпочел, чтобы ; переместил курсор в эту позицию:

stackoverflow[ ]rocks

Это может быть достигнуто с помощью l для перемещения одного символа до нажатия ;, но дополнительный шаг раздражает. Аналогичная проблема существует с T, но не с f и f. Есть ли способ сделать ; вести себя так, как я хочу, с помощью T и T?

4b9b3361

Ответ 1

Возможно, это не тот ответ, который вы ищете, но я не мог удержаться от написания VIM script для этого. Я положил его в свой .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; будет (если есть совпадение). script поддерживает ; после любого из tTfF. Самый простой способ реализовать команду , - написать для нее аналогичную функцию.

ИЗМЕНИТЬ Изменено script после прекрасного предложения Люка

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 

Ответ 2

В версии Vim 7.3.235 эта досада была изменена. Теперь по умолчанию это поведение, которое вы ожидали в первую очередь: ; заставляет курсор прыгать вправо до второго "r".

Это было объявление патча:

Патч 7.3.235
Проблема: ";" застрял на команде "t", это не полезно.
Решение: добавьте ';' флаг в 'cpo'. (Кристиан Брабанд)

Старое поведение было понижено до уровня совместимости. Вы можете вернуть его с помощью :set cpo+=;. См. :h cpo-;.

Ответ 3

2 комментария один: можете ли вы отобразить; к команде lt_, которую вы ищете? 2: Почему бы не использовать 2tr или /r, а вместо этого вместо n?

Ответ 4

Похоже, ваша проблема больше связана с поведением t, а не ;.

В вашем примере, скажем, вы начинаете с 'e':

stackov[e]rflow rocks

Я предполагаю, что вы (разумно) ожидаете, что tr перескочит на [ ]rocks вместо того, чтобы оставаться на месте.

Если это так, вы должны оставить ; как есть и, возможно, переназначить t на lt или что-то еще.