В чем разница между командами отображения remap, noremap, nnoremap и vnoremap в Vim?

1114

В чем разница между remap, noremap, nnoremapи vnoremapкоманды отображения в Vim?

Четан
источник
1
Осторожно vnoremapи vmapработайте в режиме Visual AND Select. Для отображения только в визуальном режиме используйте xmapи xnoremap.
Бенуа

Ответы:

1628

remapэто опция, которая заставляет отображения работать рекурсивно. По умолчанию он включен, и я бы рекомендовал оставить его таким. Остальные являются командами отображения , описанными ниже:

:mapи :noremapявляются рекурсивными и нерекурсивными версиями различных команд отображения. Это означает, что если вы делаете:

:map j gg
:map Q j
:noremap W j

jбудет сопоставлен с gg. Qбудет также отображаться на gg, так как jбудет расширена для рекурсивного отображения. Wбудет отображаться j(а не gg), потому jчто не будет расширен для нерекурсивного отображения.

Теперь помните, что Vim - модальный редактор . Имеет нормальный режим, визуальный режим и другие режимы.

Для каждого из этих наборов сопоставлений есть сопоставление, которое работает в нормальном, визуальном режимах, режимах выбора и оператора ( :mapи :noremap), одно в нормальном режиме ( :nmapи :nnoremap), одно в визуальном режиме ( :vmapи :vnoremap) и так далее.

Для получения дополнительной информации об этом см .:

:help :map
:help :noremap
:help recursive_mapping
:help :map-modes
Dral
источник
8
Спасибо за Ваш ответ! Кроме того, когда используется рекурсив, а когда не рекурсивный?
Четан
14
@Chetan: Это зависит от того, чего вы хотите достичь. Я склонен чаще использовать нерекурсивное, но если вы определили относительно сложное отображение с использованием нерекурсивного и того, что другое отображение выполняет все, что делает первое и более, то проще использовать рекурсивное отображение, которое включает в себя оригинал, а не перепечатывать весь нерекурсивный снова (особенно, если вам нужно настроить оригинал).
DrAl
10
Я предполагал noremapбыть какой-то противоположностью map. Я имею в виду то, что удаляет отображение. Спасибо за ответ. Это разъяснило мне
Паван Манджунат
4
Это не так важно для большинства случаев использования, но следует отметить, что :mapи т. Д. Не работают во всех режимах, а точнее, во всех общих (в частности, обычный режим, визуальный режим, режим выбора и режим ожидания оператора). Если вы хотите, чтобы отображение работало в режиме вставки, командной строки или в режиме lang-arg, вам нужно его использовать :map!и т. Д. (Источник: vimdoc.sourceforge.net/htmldoc/map.html#map-overview )
Кен Беллоуз,
3
@whytheq noremap = нерекурсивное отображение
Дан Бешард
281

Я думаю, что документация Vim должна была объяснить смысл именования этих команд. Просто сказать вам, что они делают, не поможет вам вспомнить имена.

mapявляется «корнем» всех команд рекурсивного отображения. Корневая форма применяется к режимам «нормальный», «визуальный + выбор» и «ожидание оператора». (Я использую термин «корень», как в лингвистике .)

noremapявляется «корнем» всех нерекурсивных команд отображения. Корневая форма применяется к тем же режимам, что и map. (Думайте, что noreпрефикс означает «нерекурсивный».)

(Обратите внимание, что есть также такие !режимы, какmap! которые применяются для вставки и командной строки.)

Смотрите ниже, что означает «рекурсивный» в этом контексте.

Перед буквой режима, например, nизмените режимы, в которых работает отображение. Он может выбрать подмножество списка применимых режимов (например, только «визуальный») или выбрать другие режимы, к mapкоторым неприменимо (например, «вставить»).

Использование help map-modesпокажет вам несколько таблиц, которые объясняют, как управлять режимами, к которым применяется сопоставление.

Режим букв:

  • nтолько нормально
  • v: визуально и выберите
  • o: ожидание оператора
  • x: только визуальный
  • s: выберите только
  • i: вставить
  • c: командная строка
  • l: insert, командной строки, regexp-search (и другие. Все вместе называются псевдо-режимом «Lang-Arg»)

" Рекурсивный » означает, что отображение расширяется до результата, затем результат расширяется до другого результата и т. Д.

Расширение останавливается, когда одно из них верно:

  1. результат больше не отображается ни на что другое.
  2. было применено нерекурсивное отображение (т. е. "noremap" [или один из его подобных] является окончательным расширением).

В этот момент «значение» окончательного результата по умолчанию Vim применяется / выполняется.

« Не рекурсивный » означает, что отображение раскрывается только один раз, и этот результат применяется / выполняется.

Пример:

 nmap K H
 nnoremap H G
 nnoremap G gg

Вышеуказанные причины Kрасширяются H, затем Hрасширяются Gи останавливаются. Останавливается из-за того nnoremap, что расширяется и останавливается сразу. Значение Gбудет выполнено (то есть «перейти к последней строке»). Самое большее одно нерекурсивное отображение когда-либо будет применено в цепочке расширений (это будет последним расширением, которое произойдет).

Сопоставление Gс ggприменяется только при нажатии G, но не при нажатии K. Это отображение не влияет на нажатие Kнезависимо от того, Gбыло ли оно отображено рекурсивно или нет, поскольку именно строка 2 Kостанавливает расширение , поэтому строка 3 не будет использоваться.

кельвин
источник
4
Одно: mapприменяется только к обычному, визуальному режиму, режимам выбора и ожидания оператора, а не ко всем режимам.
Брайан МакКатчон
1
должен быть принят ответ.
Тихолиз
это лучший ответ, чем принятый.
MilMike
19

Одно из различий заключается в том, что:

  • :map делает nvo== нормальный + (визуальный + выбор) + оператор в ожидании
  • :map!делает ic == вставка + режим командной строки

как указано в help map-modesтаблицах.

Итак: mapне отображается на все режимы .

Для отображения на все режимы вам нужны оба :mapи :map!.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
источник
5
Осторожный !! command modeэто другое историческое название для normal modeViz. глава 5 ( vimdoc.sourceforge.net/htmldoc/intro.html#vim-modes-intro ). Аббревиатура «с» для «командной строки». Другими словами, по умолчанию: map! lhs rhs рекурсивно отображает lhs в rhs для режимов insert + command-LINE . Это если только remapопция по умолчанию явно не отключена с помощью set noremap[!]~ / .vimrc. В этом случае отображение не будет рекурсивным (не рекомендуется).
Cbhihe