2012-10-18 71 views
5

考虑箭头键的使用Vim:为什么noremap无法在插入模式下工作?

noremap <Left> <NOP> 
noremap <Right> <NOP> 
noremap <Up> <NOP> 
noremap <Down> <NOP> 

这工作在正常模式下解除绑定,但它确实在插入模式工作:人们仍然可以使用箭头键导航。作为对策,必须包括

inoremap <Left> <NOP> 
inoremap <Right> <NOP> 
inoremap <Up> <NOP> 
inoremap <Down> <NOP> 

但是,这并没有真正意义的我,因为我承担mapnoremap应在所有模式下工作,而前面加上n/v/x/s/o/i/l/c指定映射只有特定的模式中工作。是否有一个原因?

回答

4

为什么没有一个包罗万象的模态地图,而不是同时发布地图和地图!

这很容易解释:在插入模式下的映射,Vim不会自动切换到正常模式(你可能想留在插入模式,虽然文本的翻译通过:iabb典型的做法,而不是通过:imap),所以这组适用的命令完全不同。例如,在正常模式下,Ctrl-U向上滚动,但在插入模式下,它将删除行中输入的字符!

<C-O>这样的前缀会暂时从插入模式切换到正常模式。事实上,一个经常具有定义命令行模式不同的前缀,也见下面的例子:

noremap <C-Tab> :<C-U>tabnext<CR> 
inoremap <C-Tab> <C-O>:tabnext<CR> 
cnoremap <C-Tab> <C-C>:tabnext<CR> 

所以定义映射时,总是考虑它们所需要的模式,以及他们是否需要重新映射( :nmap:noremap,更喜欢后者)。

+0

现在还不清楚你的blockquote“为什么没有一个全包模态地图,而不是发布地图和地图!”引用了部分[无评论](http://stackoverflow.com/questions/12953183 #评论17559832_12953259)Paul Ruane的回答。 –

+0

显然,我应该评论这个答案,而不是解决它。尽管nil的原文句子在语法上是正确的,但nil的评论引用并不正确。 ''和''不是装备;他们不一定要在一开始。 'nmap'不等于'noremap'的递归,所以可以通过将'nmap'改为'map'或者说'* map'与'* noremap''来改进。我修改了这些问题,但被拒绝了。我似乎总是被告知要么编辑得太少,要么编辑得太多;我无法赢得版主。 SE太官色了。 –

1
:help map-overview 

map(和noremap)用于正常,视觉,选择和运营商待定模式。

+0

啊!感谢无疑是有道理的。 [我已经根据我在这里的答案我的问题,但我会编辑它](http://stackoverflow.com/questions/3776117/vim-what-is-the-difference-between-the-remap-noremap- nnoremap-and-vnoremap-ma),所以没有其他人像我那样得到错误的想法。是否有一个原因,为什么*不是全包模态地图,而不是同时发布“地图”和“地图!”? –

+0

@nil:原因可能是您的禁用功能示例是极少数情况下的一种情况,其中相同的映射在所有模式下都具有相同的效果。 –

+0

我从“map-overview”一直读到子部分的末尾,这有点艰难,只是发现下一个子部分* 1.4 LISTING MAPPINGS *(':help map-listing')实际上比“map-overview”提供了更好的概览! –

0

与您所期望的相反,noremapmap实际上并不适用于所有模式。基于从:help map-listing非常有用的总结,这里是可以前缀(或后缀中的!的情况下)的字符来mapnoremapunmapmapclear列表,以及它们适用于模式一起:

  • (无) - 普通,可视,选择和操作符等待
  • n - 正常
  • v - 视觉和选择
  • x - 视觉
  • s - 选择
  • o - 操作符等待
  • ! - 插入和命令行
  • i - 插入
  • c - 命令行
  • l - “:lmap打开” 为插入映射,命令行和Lang-Arg

所以一个noremap映射在插入或命令行模式下不起任何作用,并且在没有考虑的情况下,在Visual,Select或Operator-pending模式下可能无法正常工作。

但是,映射可以适应在不同模式下工作,只需通过更改模式并返回映射即可。例如,noremap映射这个问题命令行命令,但仅在正常模式下工作,它也可用于在其它模式也作为见下面的例子:

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适用于普通,可视,选择和操作员正在等待的模式,其中:<C-U>进入命令行模式,然后在Vim插入范围的情况下清除当前行; inoremap适用于插入模式,其中<C-O>:暂时退出到正常模式,然后进入命令行模式;而cnoremap适用于命令行模式,为此<C-C>:退出并重新进入命令行模式以清除该行,但与<C-U>不同,它将其保留在命令历史记录中,以便:<Up>可以将其恢复。

这三个映射涵盖了所有六种模式。 (显然'Lang-Arg'不是一种模式。)有一些不起作用的角落案例,但是当我认为它不行时,也有一些案例起作用,不明白为什么。另外,即使映射的命令不会放弃这些东西,大多数模式也会像选择和未决操作符那样放松一些东西。例如,在插入模式下,我不明白为什么我给出的示例需要将当前编辑分解为撤销/重做历史中的单独更改(请尝试输入i123<C-O><Esc>456<Esc>u)。说实话,使用键映射来以这种方式运行命令似乎对我来说有点破绽,但我不知道另一种方式。

相关问题