ChatGPT解决这个技术问题 Extra ChatGPT

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

Vim 中的 remapnoremapnnoremapvnoremap 映射命令有什么区别?

注意,vnoremapvmap 在 Visual AND Select 模式下工作。要仅在可视模式下进行映射,请使用 xmapxnoremap

M
Mateen Ulhaq

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 将被扩展为递归映射。

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

现在记住 Vim 是一个模态编辑器。它有普通模式、视觉模式和其他模式。

对于这些映射组中的每一个,都有一个在正常、可视、选择和运算符模式(:map:noremap)下工作的 mapping,在正常模式下工作的一个 :nmap:nnoremap ,一个处于可视模式(: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 = 非递归映射
P
Peter Mortensen

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

map 是所有递归映射命令的“根”。根形式适用于“正常”、“视觉+选择”和“操作员挂起”模式。 (我在 linguistics 中使用术语“根”。)

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

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

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

附加一个模式字母(如 n)修改映射工作的模式。它可以选择适用模式列表的子集(例如,仅“视觉”),或选择 map 不适用的其他模式(例如“插入”)。

使用 help map-modes 将向您展示一些表格,说明如何控制映射适用于哪些模式。

模式字母:

n:仅正常

v:视觉和选择

o:运营商待定

x:仅视觉

s:仅选择

我:插入

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 仅适用于正常、视觉、选择和操作员挂起模式,而不适用于所有模式。
C
Ciro Santilli Путлер Капут 六四事

一个区别是:

:map 没有 nvo == 正常 + (visual + select) + operator 挂起

:地图! ic == 插入 + 命令行模式

help map-modes 表所述。

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

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


小心!! command modenormal mode 的另一个历史名称,即。第 5 章vimdoc.sourceforge.net/htmldoc/intro.html#vim-modes-intro)。 缩写 'c' 代表 'command-line'。 换句话说,默认情况下:map! lhs rhs 递归地 将 lhs 映射到 rhs 用于 insert + command- LINE 模式。除非在 ~/.vimrc 中使用 set noremap[!] 明确禁用 remap 默认选项。在这种情况下,映射将不是递归的(不建议)。
M
Mahmoud

我将简单地解释映射命令。

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

map - 在正常、可视、选择和操作符挂起模式下递归工作。

地图! - 在插入和命令行模式下递归工作。

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

noremap - 在正常、可视、选择和操作员挂起模式下以非递归方式工作。

地图! - 在插入和命令行模式下以非递归方式工作。

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

nmap - 在正常模式下递归工作。

imap - 在插入模式下递归工作。

vmap - 在视觉和选择模式下递归工作。

xmap - 在可视模式下递归工作。

smap - 在选择模式下递归工作。

cmap - 在命令行模式下递归工作。

omap - 在运算符挂起模式下递归工作。

以及它们的非递归变体:

nnoremap - 在正常模式下以非递归方式工作。

inoremap - 在插入模式下以非递归方式工作。

vnoremap - 在视觉和选择模式下以非递归方式工作。

xnoremap - 在可视模式下以非递归方式工作。

snoremap - 在选择模式下以非递归方式工作。

cnoremap - 在命令行模式下以非递归方式工作。

onoremap - 在运算符挂起模式下以非递归方式工作。

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


这是一个很好的解释。但是,我了解递归是什么,但我不明白在这种情况下它意味着什么。非递归工作意味着什么?
你可以把它想象成no[remap] {lhs} {rhs},这意味着将键序列{lhs}映射到{rhs},但不要重新映射{rhs}中的任何命令,以避免嵌套和递归映射。
@Mahmoud 如果您可以将前面的评论添加到您的答案中,那将是一件好事,也许就在关于 noremapnoremap! 的部分之后。我想知道和 Janac Meena 完全一样的事情。 (我想我可能有能力进行编辑,但我不想在别人的答案中添加新内容。)