与您的预期相反,noremap
实际上map
并不适用于所有模式。基于来自 的非常有用的摘要:help map-listing
,这里列出了可以作为前缀(或在 的情况下为后缀!
)到map
、noremap
、unmap
和的字符mapclear
,以及它们适用的模式:
- (无)– 正常、可视、选择和等待操作员
n
- 普通的
v
- 视觉和选择
x
- 视觉的
s
- 选择
o
– 运营商待定
!
- 插入和命令行
i
- 插入
c
- 命令行
l
– 用于插入、命令行和 Lang-Arg 的 ":lmap" 映射
因此,noremap
映射在“插入”或“命令行”模式下无效,并且不加考虑,在“可视化”、“选择”或“运算符挂起”模式下也可能无法按预期工作。
然而,映射可以适应在不同的模式下工作,只需更改模式并返回映射即可。例如,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
适用于 Normal、Visual、Select 和 Operator-pending 模式,:<C-U>
如果 Vim 插入范围,则进入命令行模式然后清除当前行;inoremap
适用于插入模式,<C-O>:
暂时退出普通模式,然后进入命令行模式;并cnoremap
适用于命令行模式,<C-C>:
退出并重新进入命令行模式以清除行,但与 不同<C-U>
的是,将其保留在命令历史记录中以便:<Up>
可以将其恢复。
These three mappings cover all six modes. (Apparently ‘Lang-Arg’ isn't a mode.) There are some corner-cases where it doesn't work, but then there are also some cases it works when I'd have thought it wouldn't, and I don't understand why. Also, most of the modes will loose little things like selections and pending operators, even if the mapped command wouldn't otherwise loose these things. For instance, when in Insert mode, I don't see why the example I've given would need to break the current edit into separate changes in the undo/redo history (try typing i123<C-O><Esc>456<Esc>u
). To be honest using key mappings to run commands in this way seems like a bit of a hack to me, but I don't know another way.