Как установить регулярное выражение на клавиши «w», «e» и «b» в Vim?

#vim

#vim

Вопрос:

Есть ли способ определить, что vim должен распознавать как слово? Я хочу назначить w regex для всех движений клавиш word, таких как «w», «e», «b»… Я могу сделать это для обычного режима следующим образом:

 nnoremap <silent> w :call search('w ')<CR>
  

но это не работает для визуального режима и режимов ожидания оператора. Было бы здорово, если бы для этого была настройка.

Ответ №1:

Из того, что я понял из вашего вопроса и обсуждения ответа Kaz, я думаю, что вы ищете плагин smartword от Kana: http://www.vim.org/scripts/script.php?script_id=2470 .

Вам нужно будет проверить документацию с :help smartword помощью , но короткая версия, если вы установите плагин и сопоставите встроенные сопоставления word с подключаемыми…

 map w  <Plug>(smartword-w)
map b  <Plug>(smartword-b)
map e  <Plug>(smartword-e)
map ge  <Plug>(smartword-ge)
  

… затем встроенные модули будут пропускать любые символы, не являющиеся словами. Я использую это уже много-много лет, и я вполне доволен тем, как оно себя ведет.

Комментарии:

1. Это именно то, что я искал. Обычный, визуальный и ожидающий оператора режимы работают нормально. Спасибо.

Ответ №2:

Для движений в нижнем регистре, таких как wи e, определение «слова» контролируется :iskeyword опцией; см. :help iskeyword Об этом. В основном он состоит из списка символов, заданных в виде отдельных символов или диапазонов, разделенных запятыми. Я думаю, что различные синтаксические файлы настраивают это для разных языков, чтобы эти команды перемещались по идентификаторам. Не похоже, что вы можете указать регулярное выражение для этого.

Движения в верхнем регистре похожи Wи Eне выглядят так, как будто их можно перепрограммировать. Их определение «СЛОВА» — это непустые символы, разделенные пробелами, плюс каждая пустая строка считается «СЛОВОМ».

Однако, к сожалению, похоже, что действует поведение, при котором iskeyword символы просто разделяют входные данные на последовательности iskeyword символов, не iskeyword символов и пробелов. Когда wиспользуются связанные команды и, они пропускают пробелы, но посещают как iskeyword токены, так и не- iskeyword токены.

Переназначение с использованием :map только / ? последовательности нажатий клавиш или работает как в визуальном, так и в командном режиме:

 :map w /<w/^M
:map b ?</w^M
:map e /w>^M
  

Это работает в обоих, потому / ? что поиск и работает в обоих режимах. Конечно, это уродливое решение, потому что оно искажает текущий шаблон поиска, и если у вас :set hls включен ( highlightsearch ), кончики / хвосты слов выделяются.

Приведенные выше поиски не очень удовлетворительны из-за того, как ведут себя операторы привязки. Например, я не могу заставить их «приземляться» a на что-то вроде {abc или (abc .

Следующие сопоставления работают лучше. Каждый запускает несколько поисковых запросов. Поиск /. и ?. используется как уловка для перехода к следующему или предыдущему символу, так что, если мы находимся на последнем символе строки, мы переходим к первому символу в следующей строке и наоборот.

 :map b ?w^M?W^M/.^M
:map w /W^M/w^M
:map e /w^M/W^M?.^M
  

Все еще есть некоторые причуды. Например, список таких слов, как:

 abc
def
ghi
  

не содержит совпадений для класса, отличного от word W . Сопоставление должно включать окончания строк. Продвигаясь вперед, улучшением wв этом отношении является добавление совпадения для строки, заканчивающейся следующим образом:

 :map w /(W\|$)^M/w^M
  

Обратите внимание на двойную обратную косую черту перед каналом! Крайняя правая обратная косая черта экранирует канал, поэтому обработка :map команды не рассматривает ее как разделитель команд. Тогда у нас остается | оператор регулярного выражения для ветвления. Аналогичным образом можно улучшить два других сопоставления; я оставляю это как упражнение.

Комментарии:

1. Ну, я изменил этот параметр на «48-57,65-90,97-122,_», и ничего не произошло. Возможно, я был неточен в своем вопросе. Я хочу пропустить все символы, такие как $, = или -> и что-нибудь подобное, когда я перемещаюсь с помощью клавиши «w». au BufEnter * setlocal iskeyword=48-57,65-90,97-122,_

2. К сожалению, похоже, что Vim также обрабатывает символы за пределами набора как слова, отличные от пробелов. Итак, если мы определяем iskeyword , скажем, только строчные буквы от а доя, и у нас есть курсор на a in abc$def , тогда w мы посетим the $ , а затем the def . По сути, текст разделяется на слова, разделенные не словами, но затем w посещает их оба!

3. Похоже, что повторная привязка ключей для выполнения пользовательского поиска, вероятно, единственный путь. Например :map w /<w^M ( ^M вводится как Ctrl-V Enter). К сожалению, это нарушает текущий шаблон поиска.

4. Спасибо за ваше внимание, но, как вы сказали, это приведет к блокировке текущего поиска (не критично) и выделит все вхождения (это критично). Я знал, что могу вызвать функцию в визуальном режиме, но это слишком сложная настройка. Я подумал, что есть лучший способ, например, установить параметр. Если других сообщений не будет, я отмечу ваше как ответ.

5. Обычно у меня есть ключ, сопоставленный с переключением hls , потому hls что это может раздражать в различных обстоятельствах, даже если поиск не заблокирован.