Keyboard 维姆:为什么noremap不能在插入模式下工作?

Keyboard 维姆:为什么noremap不能在插入模式下工作?,keyboard,vim,Keyboard,Vim,考虑使用以下方法解除箭头键的绑定: noremap <Left> <NOP> noremap <Right> <NOP> noremap <Up> <NOP> noremap <Down> <NOP> noremap 诺雷马克 诺雷马克 诺雷马克 这在正常模式下工作,但在插入模式下不工作:用户仍然可以使用箭头键导航。作为对策,必须包括 inoremap <Left>

考虑使用以下方法解除箭头键的绑定:

 noremap <Left>  <NOP>
 noremap <Right> <NOP>
 noremap <Up>    <NOP>
 noremap <Down>  <NOP>
noremap
诺雷马克
诺雷马克
诺雷马克
这在正常模式下工作,但在插入模式下不工作:用户仍然可以使用箭头键导航。作为对策,必须包括

 inoremap <Left>  <NOP>
 inoremap <Right> <NOP>
 inoremap <Up>    <NOP>
 inoremap <Down>  <NOP>
inoremap
inoremap
inoremap
inoremap
但这对我来说并没有什么意义,因为我假设
map
noremap
应该在所有模式下都能工作,而prepending
n/v/x/s/o/I/l/c
指定映射只在特定模式下工作。这有什么原因吗

:help map-overview
map(和noremap)用于正常、可视、选择和操作员挂起模式

为什么没有一个包罗万象的模态映射,而不是同时发布map和map呢

这很容易解释:在插入模式映射中,Vim不会自动切换到正常模式(虽然文本翻译通常通过
:iabb
,而不是
:imap
),但您可能希望保持插入模式,因此适用的命令集是完全不同的。例如,在正常模式下,Ctrl-U向上滚动,但在插入模式下,它会删除行中输入的字符

这样的前缀临时从插入模式切换到正常模式。实际上,人们甚至还必须为命令行模式定义不同的前缀,如本例所示:

noremap <C-Tab> :<C-U>tabnext<CR>
inoremap <C-Tab> <C-O>:tabnext<CR>
cnoremap <C-Tab> <C-C>:tabnext<CR>
noremap <C-Tab> :<C-U>set list!<CR>
inoremap <C-Tab> <C-O>:set list!<CR>
cnoremap <C-Tab> <C-C>:set list!<CR>:<Up>
noremap:tabnext
inoremap:tabnext
cnoremap:tabnext

<> P>这样,在定义映射时,总是考虑它们需要哪些模式,以及它们是否需要重新映射(<代码>:NMAP < /COD> vs. <代码>:NoReMAP,请选择后者)。

< P>与您所期望的相反,<代码> NORMAP和<代码> MAP>代码>实际上不适用于所有模式。根据
:help map listing
中非常有用的摘要,这里列出了可以在
映射
noremap
取消映射
映射清除
中加前缀(或在
的情况下加后缀)的字符列表,以及它们适用的模式:

  • (无)–正常、可视、选择和操作员挂起
  • n
    –正常
  • v
    –可视并选择
  • x
    –可视
  • s
    –选择
  • o
    –操作员挂起
  • –插入和插入命令行
  • i
    –插入
  • c
    –命令行
  • l
    –:插入、命令行和语言参数的“lmap”映射
因此,
noremap
映射在Insert或命令行模式下不会产生任何效果,如果不考虑,也可能无法在视觉、选择或操作员挂起模式下正常工作

但是,映射可以调整为在不同模式下工作,只需更改模式并返回映射即可。例如,发出命令行命令但仅在正常模式下工作的
noremap
映射可以调整为也在其他模式下工作,如本例所示:

noremap <C-Tab> :<C-U>tabnext<CR>
inoremap <C-Tab> <C-O>:tabnext<CR>
cnoremap <C-Tab> <C-C>:tabnext<CR>
noremap <C-Tab> :<C-U>set list!<CR>
inoremap <C-Tab> <C-O>:set list!<CR>
cnoremap <C-Tab> <C-C>:set list!<CR>:<Up>
noremap:设置列表!
inoremap:设置列表!
cnoremap:集合列表!:
noremap
适用于正常、可视、选择和操作员挂起模式,对于这些模式,
进入命令行模式,然后在Vim插入范围时清除当前行
inoremap
应用于插入模式,
暂时退出到正常模式,然后进入命令行模式;而
cnoremap
适用于命令行模式,对于该模式,
退出并重新进入命令行模式以清除该行,但与
不同的是,将其保留在命令历史记录中,以便
可以将其恢复


这三种映射涵盖所有六种模式。(显然“Lang Arg”不是一种模式。)有些情况下,它不起作用,但也有一些情况下,它起作用时,我认为它不会,我不明白为什么。此外,大多数模式都会丢失一些小东西,比如选择和挂起的操作符,即使mapped命令不会丢失这些东西。例如,在插入模式下,我不明白为什么我给出的示例需要将当前编辑分解为撤消/重做历史记录中的单独更改(尝试键入
i123456u
)。老实说,使用键映射以这种方式运行命令对我来说似乎有点麻烦,但我不知道另一种方式。

啊!谢谢当然有道理。所以没有人会像我一样有错误的想法。为什么没有一个包罗万象的模态映射,而不是同时发布
map
map
?@nil:原因可能是您禁用功能的示例是少数几个相同映射在所有模式下都具有相同效果的情况之一。我从头到尾通读了
映射概述
,这有点难,结果发现下一小节,它是1.4列表映射(
:帮助映射列表
),实际上提供了比
映射概述
更好的概述!现在还不清楚你的区块引语“为什么没有一个包罗万象的模态图,而不是同时发布map和map!”是否引用了Paul Ruane答案中的部分内容。所以显然我应该对这个答案进行评论,而不是修复它。nil评论中的引语读起来不正确,即使nil的原语在语法上是正确的
不是前缀;他们不必在一开始
nmap
不是
noremap
的递归等价物,因此可以通过将
nmap
更改为
map
或说“
*map
*noremap
”来改进它。我在编辑中修复了这些问题,但被拒绝了。我似乎总是因为编辑太少或编辑太多而受到责备;我不能和主持人一起赢。SE太官僚主义了。