Vim中的remap,noremap,nnoremap和vnoremap映射命令有什么区别?


1112

是什么之间的区别remapnoremapnnoremapvnoremap在Vim的映射命令?


1
注意,vnoremapvmap在“视觉和选择”模式下工作。要仅在可视模式下进行映射,请使用xmapxnoremap
Benoit

Answers:


1624

remap是使映射递归工作的选项。默认情况下它处于打开状态,我建议您采用这种方式。其余为映射命令,如下所述:

:map并且:noremap是各种映射命令的递归非递归版本。这意味着如果您这样做:

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

j将映射到ggQ被映射到gg,因为j会为递归映射扩大。W将被映射到j(而不是gg),因为j不会为非递归映射扩展。

现在请记住,Vim是模式编辑器。它具有普通模式,可视模式和其他模式。

对于这些映射集中的每组,都有一种映射在正常,可视,选择和运算符模式(:map:noremap)下工作,在正常模式(:nmap:nnoremap)下工作,在可视模式(:vmap:vnoremap)下工作。

有关此的更多指导,请参阅:

:help :map
:help :noremap
:help recursive_mapping
:help :map-modes

8
感谢您的回答!另外,什么时候使用递归,什么时候使用非递归?
Chetan

14
@Chetan:这取决于您要实现的目标。我倾向于更频繁地使用非递归,但是如果您使用非递归定义了一个相对复杂的映射,并且另一个映射完成了第一个映射的所有工作,并且使用了另一个映射,则使用包含以下内容的递归映射会更容易而不是重新键入整个非递归代码(特别是如果您随后需要调整原始代码)的话。
DrAl 2010年

10
我曾假设noremap与的相反map。我的意思是删除映射的东西。感谢您的回答。它使我
明白

4
对于大多数用例而言,它并不是那么重要,但是应注意:map,等等并不是在所有模式下都可以工作,确切地说,并不是在所有常见模式下都可以工作(特别是正常模式,可视模式,选择模式和操作员待定模式)。如果要使映射以插入,命令行或lang-arg模式工作,则需要使用:map!等。(来源:vimdoc.sourceforge.net/htmldoc/map.html#map-overview
Ken Bellows

3
@whytheq noremap =非递归映射
Dan

281

我认为Vim文档应该已经解释了这些命令命名的含义。仅仅告诉您他们所做的事情并不能帮助您记住名字。

map是所有递归映射命令的“根”。根格式适用于“普通”,“可视+选择”和“操作员待定”模式。(我在语言学中使用“根”一词。)

noremap是所有非递归映射命令的“根”。根格式适用于与相同的模式map。(认为nore前缀表示“非递归”。)

(请注意,还有一些!类似的模式map!适用于插入和命令行。)

在此上下文中,“递归”的含义请参见下文。

在模式字母前添加类似n修改映射所使用的模式的模式字母。它可以选择适用模式列表的子集(例如,仅“可视”),或者选择其他map不适用于的模式(例如,“插入”)。

使用help map-modes将显示一些表格,这些表格解释如何控制映射应用于哪些模式。

模式字母:

  • n:仅正常
  • v:视觉并选择
  • o:待处理运算符
  • x:仅视觉
  • s:仅选择
  • i: 插
  • c: 命令行
  • l:插入,命令行,正则表达式搜索(及其他。统称为“ Lang-Arg”伪模式)

递归 ”表示将映射扩展为一个结果,然后将该结果扩展为另一个结果,依此类推。

当满足以下条件之一时,扩展停止:

  1. 结果不再映射到其他任何内容。
  2. 应用了非递归映射(即“ noremap” [或其同类之一]是最终的扩展)。

此时,将应用/执行Vim最终结果的默认“含义”。

非递归 ”表示映射仅扩展一次,并且结果被应用/执行。

例:

 nmap K H
 nnoremap H G
 nnoremap G gg

以上原因K扩展到H,然后H扩展到G并停止。由于停止nnoremap,它会立即扩展并停止。G将执行的含义(即“跳至最后一行”)。在扩展链中最多将应用一个非递归映射(这将是最后一次发生的扩展)。

映射Ggg如果按只适用G,但如果您按下KK无论是否G以递归方式映射,此映射都不会影响按,因为第2行导致K停止扩展,因此不会使用第3行。


4
一件事:map仅适用于普通,可视,选择和操作员待定模式,不适用于所有模式。
Brian McCutchon 2014年

1
应该被接受的答案。
Tycholiz

这是比公认的更好的答案。
MilMike

19

一个区别是:

  • :map 是否nvo==正常+(可视+选择)+运算符待处理
  • :map!是否ic ==插入+命令行模式

help map-modes表中所述。

因此:map并非映射到所有模式

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


5
小心! command modenormal modeviz的另一个历史名称。第5 章vimdoc.sourceforge.net/htmldoc/intro.html#vim-modes-intro)。缩写“ c”代表“命令行”。换句话说,默认情况下:对于insert +命令行模式, lhs map! lhs rhs 递归映射到rhs 。除非在〜/ .vimrc中明确禁用了默认选项。在那种情况下,映射将不是递归的(不建议)。remapset noremap[!]
Cbhihe 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.