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 中的remapnoremapnnoremapvnoremap 映射命令有什么区别?

【问题讨论】:

注意,vnoremapvmap 在 Visual AND Select 模式下工作。要仅在可视模式下进行映射,请使用 xmapxnoremap 【参考方案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 将映射到 ggQ映射到 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:这取决于您想要实现的目标。我倾向于更频繁地使用非递归,但是如果您使用非递归定义了一个相对复杂的映射,并且另一个映射可以完成第一个映射所做的所有事情等等,那么使用包含的递归映射会更容易原始的,而不是再次重新输入整个非递归的(特别是如果您需要调整原始的)。 我曾假设noremapmap 是相反的。我的意思是删除映射的东西。感谢您的回答。它澄清了我 对于大多数用例来说并不是那么重要,但应该注意: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 的含义将被执行(即“跳转到最后一行”)。在扩展链中最多会应用一个非递归映射(这将是最后一次发生的扩展)。

Ggg 的映射仅在您按 G 时适用,但在您按 K 时不适用。无论G 是否被递归映射,此映射都不会影响按下K,因为它是第2 行导致K 的扩展停止,因此不会使用第3 行。

【讨论】:

一件事:map 仅适用于普通、可视、选择和操作员等待模式,而不适用于所有模式。【参考方案3】:

一个区别是:

:map 确实 nvo == 正常 + (visual + select) + 运算符待处理 :map! 执行 ic == 插入 + 命令行模式

help map-modes 表中所述。

所以:map 不会映射到所有模式

要映射到所有模式,您需要 :map:map!

【讨论】:

小心!! command modenormal 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 映射命令有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Vim:为啥 noremap 在插入模式下不起作用?

vim配置

教程向配置属于自己的vim

Vim映射配置

Vim 用 * 高亮一个单词而不移动光标

在 vim 中重新映射“Y”