Vim 中的 remap、noremap、nnoremap 和 vnoremap 映射命令有啥区别?
Posted
技术标签:
【中文标题】Vim 中的 remap、noremap、nnoremap 和 vnoremap 映射命令有啥区别?【英文标题】:What is the difference between the remap, noremap, nnoremap and vnoremap mapping commands in Vim?Vim 中的 remap、noremap、nnoremap 和 vnoremap 映射命令有什么区别? 【发布时间】:2011-04-16 02:56:45 【问题描述】:Vim 中的remap
、noremap
、nnoremap
和vnoremap
映射命令有什么区别?
【问题讨论】:
注意,vnoremap
和 vmap
在 Visual AND Select 模式下工作。要仅在可视模式下进行映射,请使用 xmap
和 xnoremap
。
【参考方案1】:
remap
是一个选项,它使映射以递归方式工作。默认情况下它是打开的,我建议你保持这种状态。其余的是映射命令,如下所述:
:map
和 :noremap
是各种映射命令的递归和非递归版本。例如,如果我们运行:
:map j gg (moves cursor to first line)
:map Q j (moves cursor to first line)
:noremap W j (moves cursor down one line)
然后:
j
将映射到 gg
。
Q
将也映射到 gg
,因为 j
将被扩展为递归映射。
W
将映射到 j
(而不是 gg
),因为 j
不会针对非递归映射进行扩展。
现在请记住,Vim 是一个模态编辑器。它有普通模式、视觉模式和其他模式。
对于这些映射组中的每一个,都有一个mapping 在正常、可视、选择和操作模式下工作(:map
和 :noremap
),一个在正常模式下工作(:nmap
和 @ 987654339@),一个在可视模式下(:vmap
和:vnoremap
)等等。
有关这方面的更多指导,请参阅:
:help :map
:help :noremap
:help recursive_mapping
:help :map-modes
【讨论】:
感谢您的回答!还有,什么时候用递归,什么时候用非递归? @Chetan:这取决于您想要实现的目标。我倾向于更频繁地使用非递归,但是如果您使用非递归定义了一个相对复杂的映射,并且另一个映射可以完成第一个映射所做的所有事情等等,那么使用包含的递归映射会更容易原始的,而不是再次重新输入整个非递归的(特别是如果您需要调整原始的)。 我曾假设noremap
与map
是相反的。我的意思是删除映射的东西。感谢您的回答。它澄清了我
对于大多数用例来说并不是那么重要,但应该注意:map
等在all模式下不工作,确切地说,只是所有常见的模式(特别是正常模式、可视模式、选择模式和操作员挂起模式)。如果希望映射在插入、命令行或 lang-arg 模式下工作,则需要使用 :map!
等。(来源:vimdoc.sourceforge.net/htmldoc/map.html#map-overview)
@whytheq noremap = 非递归映射【参考方案2】:
我认为 Vim 文档应该已经解释了这些命令命名背后的含义。仅仅告诉你他们做了什么并不能帮助你记住这些名字。
map
是所有递归映射命令的“根”。根形式适用于“正常”、“视觉+选择”和“操作员挂起”模式。 (我在linguistics 中使用术语“root”。)
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
时不适用。无论G
是否被递归映射,此映射都不会影响按下K
,因为它是第2 行导致K
的扩展停止,因此不会使用第3 行。
【讨论】:
一件事:map
仅适用于普通、可视、选择和操作员等待模式,而不适用于所有模式。【参考方案3】:
一个区别是:
:map
确实 nvo
== 正常 + (visual + select) + 运算符待处理
:map!
执行 ic
== 插入 + 命令行模式
如help map-modes
表中所述。
所以:map
不会映射到所有模式。
要映射到所有模式,您需要 :map
和 :map!
。
【讨论】:
小心!!command mode
是 normal mode
的另一个历史名称,即。第 5 章vimdoc.sourceforge.net/htmldoc/intro.html#vim-modes-intro)。 缩写“c”代表“命令行”。 换句话说,默认情况下:map! lhs rhs
递归地 将 lhs 映射到 rhs 用于 insert + command- LINE 模式。除非 remap
默认选项在 ~/.vimrc 中被 set noremap[!]
明确禁用。在这种情况下,映射将不是递归的(不建议)。以上是关于Vim 中的 remap、noremap、nnoremap 和 vnoremap 映射命令有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章