В чем разница между командами отображения remap, noremap, nnoremap и vnoremap в Vim?
В чем разница между командами отображения remap, noremap, nnoremap и vnoremap в Vim?
Ответы
Ответ 1
remap
- это вариант, который делает рекурсивные преобразования. По умолчанию он включен, и я бы рекомендовал оставить его таким образом. Остальные команды отображения, описанные ниже:
:map
и :noremap
являются рекурсивными и нерекурсивными версиями различных команд отображения. Это означает, что если вы выполните:
:map j gg
:map Q j
:noremap W j
j
будет отображаться на gg
. Q
также будет отображаться на gg
, потому что j
будет расширен для рекурсивного отображения. W
будет отображаться на j
(а не на gg
), потому что j
не будет расширен для нерекурсивного отображения.
Теперь помните, что Vim является модальным редактором. Он имеет режим обычный, визуальный и другие режимы.
Для каждого из этих наборов отображений существует mapping, который работает в нормальном, визуальном, выборочном и операторном режимах (:map
и :noremap
), который работает в нормальном режиме (:nmap
и :nnoremap
), один в визуальном режиме (:vmap
и :vnoremap
) и т.д.
Подробнее об этом см.:
:help :map
:help :noremap
:help recursive_mapping
:help :map-modes
Ответ 2
Я думаю, что документация Vim должна была объяснить смысл именования этих команд. Просто сказать вам, что они делают, не поможет вам вспомнить имена.
map
является "корнем" всех команд рекурсивного отображения. Корневая форма применяется к режимам "обычный", "визуальный + выбор" и "ожидание оператора". (Я использую термин "корень", как в лингвистике.)
noremap
является "корнем" всех нерекурсивных команд отображения. Корневая форма применяется к тем же режимам, что и map
. (Думайте, что префикс nore
означает "нерекурсивный".)
(Обратите внимание, что есть также !
Режимы, такие как map!
, Которые применяются для вставки и командной строки.)
Смотрите ниже, что означает "рекурсивный" в этом контексте.
Перед буквой режима, например, n
измените режимы, в которых работает отображение. Он может выбрать подмножество списка применимых режимов (например, только "визуальный") или выбрать другие режимы, к которым map
не будет применяться (например, "вставить"),
Использование help map-modes
покажет вам несколько таблиц, которые объясняют, как управлять режимами, к которым применяется сопоставление.
Режим букв:
-
n
: только нормальный -
v
: визуальный и выберите -
o
: ожидание оператора -
x
: только визуальный -
s
: выбрать только -
i
: вставить -
c
: командная строка -
l
: вставка, командная строка, поиск по регулярному выражению (и другие. Все вместе называются псевдо-режимом "Lang-Arg")
" Рекурсивный " означает, что отображение расширяется до результата, затем результат расширяется до другого результата и т.д.
Расширение останавливается, когда одно из них верно:
- результат больше не отображается ни на что другое.
- было применено нерекурсивное отображение (т.е. "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 не будет использоваться.
Ответ 3
Внимание, vnoremap
и vmap
работают в режиме визуального и выбора.
Чтобы иметь отображение только в визуальном режиме, используйте xmap
и xnoremap
.
Ответ 4
Одно отличие состоит в том, что:
-
:map
выполняет nvo
== normal + (визуальный + выбор) + ожидающий оператор
-
:map!
выполняет ic
== insert + режим командной строки
как указано в таблицах help map-modes
.
Итак: map
не отображается во всех режимах.
Для отображения всех режимов вам нужны как :map
, так и :map!
.