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

Che*_*tan 1045 mapping vim command

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

DrA*_*rAl 1523

remap是一个使映射以递归方式工作的选项.默认情况下它已打开,我建议你保持这种状态.其余的是映射命令,如下所述:

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

:map j gg
:map Q j
:noremap W j
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

  • 一个写得很好的答案,我希望关于这些的ViM文档是清楚的!:-) (112认同)
  • @Chetan:这取决于你想要达到的目标.我倾向于更频繁地使用非递归,但如果您使用非递归定义了相对复杂的映射,并且使用第一个映射执行的所有操作的另一个映射以及更多,则可以更容易地使用包含以下内容的递归映射原始的,而不是再次重新输入整个非递归的(特别是如果你需要调整原始的那个). (13认同)
  • 感谢您的回答!此外,何时使用递归,何时使用非递归? (8认同)
  • 我假设`noremap`与`map`相反.我的意思是删除映射的东西.谢谢你的回答.它澄清了我 (6认同)
  • 对于大多数用例来说并不重要,但应该注意`:map`等不能在*all*模式下工作,确切地说,只是所有常见的模式(特别是普通模式,视觉模式)模式,选择模式和操作员挂起模式).如果您希望映射在insert,command-line或lang-arg模式下工作,则需要使用`:map!`等(来源:http://vimdoc.sourceforge.net/htmldoc/map.html #地图概述) (4认同)
  • 这应该位于VIM帮助文件的顶部 (3认同)
  • `nore`代表`[no] [re] map`? (2认同)
  • @whytheq noremap =非递归映射 (2认同)
  • 如果我使用`noremap j gg`然后`map Q j`正在按Q去调用gg?我理解相反的情况不会. (2认同)

Kel*_*vin 248

我认为Vim文档应该解释这些命令命名背后的含义.告诉你他们做了什么并不能帮助你记住这些名字.

map是所有递归映射命令的"根".根表单适用于"正常","视觉+选择"和"操作员待定"模式.(我在语言学中使用术语"root" .)

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
Run Code Online (Sandbox Code Playgroud)

以上原因K扩展到H,然后H扩展到G并停止.它会停止,因为nnoremap它会立即扩展和停止.G将执行的含义(即"跳到最后一行").最多只有一个非递归映射将应用于扩展链(这将是最后一次扩展).

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

  • 一件事:`map`仅适用于普通,视觉,选择和操作员待定模式,而不适用于所有模式. (4认同)

Mah*_*oud 37

我将简单解释一下映射命令。

首先,我们有两个通用映射命令:

  • map-在正常可视选择操作员挂起模式下递归工作。
  • map!-在插入命令行模式下递归工作。

这些命令的非递归变体是:

  • noremap-在正常可视选择操作员挂起模式下递归工作。
  • noremap!-在插入命令行模式下以非递归方式工作。

您可以将其视为no[remap] {lhs} {rhs}将键序列映射{lhs}到的意思{rhs},但不要重新 映射任何命令{rhs}以避免嵌套和递归映射。

然后,我们有特定于模式的命令:

  • nmap-在正常模式下递归工作。
  • imap-在插入模式下递归工作。
  • vmap-在视觉选择模式下递归工作。
  • xmap-在视觉模式下递归工作。
  • smap-在选择模式下递归工作。
  • cmap-在命令行模式下递归工作。
  • omap-在运算符挂起模式下递归工作。

以及它们的非递归变体:

  • nnoremap-在正常模式下非递归工作。
  • inoremap-在插入模式下非递归工作。
  • vnoremap-在视觉选择模式下以非递归方式工作。
  • xnoremap-在视觉模式下非递归工作。
  • snoremap-在选择模式下非递归工作。
  • cnoremap-在命令行模式下以非递归方式工作。
  • onoremap-在运算符挂起模式下以非递归方式工作。

最后,remap是一个布尔选项,允许映射递归工作。值得一提的是,您应该始终将此选项保留为默认值on

  • @Mahmoud,如果您可以将前面的评论添加到您的答案中,也许就在有关“noremap”和“noremap!”的部分之后,那就太好了。我想知道和贾纳克·米娜完全相同的事情。(我想我可能有能力进行编辑,但我不想在别人的答案中添加新的内容。) (7认同)
  • 您可以将其视为“no[remap] {lhs} {rhs}”,表示将按键序列“{lhs}”映射到“{rhs}”,但不重新映射“{rhs}”中的任何命令` 以避免嵌套和递归映射。 (5认同)
  • 这是一个很好的解释。但是,我明白什么是递归,但我不明白它在这种情况下意味着什么。“非递归”工作是什么意思? (4认同)

Cir*_*四事件 19

一个区别是:

  • :mapnvo==正常+(视觉+选择)+运算未决
  • :map!ic ==插入+命令行模式

help map-modes表中所述.

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

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

  • 小心!! `command mode`是`normal mode`的另一个历史名称.第5章http://vimdoc.sourceforge.net/htmldoc/intro.html#vim-modes-intro).**缩写'c'代表'命令行'.**换句话说,默认情况下:`map!lhs rhs` _recursively_将lhs映射到rhs,用于**insert + command-LINE**模式.除非使用〜/ .vimrc中的`set noremap [!]`明确禁用`remap`默认选项.在那种情况下,映射不会是递归的(不可取). (2认同)
  • 这个答案缺乏上下文,没有回答问题。它可能更适合作为评论。 (2认同)