Поведение; повтор последней команды t беспокоит меня. Можете ли вы помочь мне сделать это лучше? - PullRequest
19 голосов
/ 06 октября 2009

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

[s]tackoverflow rocks

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

stackov[e]rflow rocks

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

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

stackoverflow[ ]rocks

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

Ответы [ 4 ]

32 голосов
/ 28 марта 2013

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

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

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

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

10 голосов
/ 08 октября 2009

Возможно, это не тот ответ, который вы ищете, но я не удержался от написания сценария 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

Хорошо, эти вещи всегда сложнее, чем я думаю. Текущее сопоставление имеет следующие проблемы:

  1. Предположим, вы выполнили поиск как tr выше. Что теперь делать d; или c;? Насколько я понимаю, они должны удалить или изменить до первого r, а не второго. Эту проблему можно решить, выполнив сопоставление только для обычного и визуального режимов, а не для режима ожидания оператора.
  2. Текущее отображение не работает в визуальном режиме. то есть, если вы наберете 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 голосов
/ 06 октября 2009

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

1 голос
/ 07 октября 2009

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

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

stackov[e]rflow rocks

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...