0%

VIM键值映射规则

map模式

有五种映射存在:

  1. Normal mode: 普通模式, 输入命令时
  2. Visual mode: 可视模式: 可视区域高亮并输入命令时
  3. Select mode: 选择模式: 与可视模式区别是会替换选择文本
  4. Operator-pending mode: 操作符等待模式: 操作符等待中 (“d”,”y”,”c” 等等之后)。 见下: |omap-info|。
  5. Insert mode: 插入模式: 也用于替换模式。
  6. Command-line mode: 命令行模式: 输入 “:” 或 “/“ 命令时。

快捷键映射

快捷键映射分两种: map 和 noremap

递归映射 (map)

如果键 b 映射为键 a,然后键 c 映射为键 b,那么当按键 c 时会产生按键 a 的效果。

:map b a
:map c b

相当于

:map c a

非递归映射 (noremap)

:noremap b a
:noremap c b

非递归映射则不会产生递归映射一样的效果。

不同模式下的快捷键映射

映射模式

在 map 与 noremap 前分别可以加 ‘n’, ‘v’, ‘x’, ‘s’, ‘o’, ‘i’, ‘l’, ‘c’ 以及 ‘map!’ 和 ‘noremap!’:

  • Normal, Visual, Select and Operator-pending
  • n Normal
  • v Visual and Select
  • s Select (在可视模式下Ctrl+G进入)
  • x Visual
  • o Operator-pending
  • ! Insert and Command-line
  • i Insert
  • l “:lmap” mappings for Insert, Command-line and Lang-Arg
  • c Command-line

常用参数:

  • {lhs} 表示左手边 *{lhs}*
  • {rhs} 表示右手边 *{rhs}*

普通模式的映射命令

可以随时:help map一下,查看相关命令具体信息。

map

:map {lhs} {rhs} 
:map {lhs} {rhs} |mapmode-nvo| *:map* 

作用模式: n、v、o (普通、可视和选择、操作符等待)。
在:map作用的模式中把键系列 {lhs} 映射为 {rhs},{rhs}可进行映射扫描,也就是可递归映射。

举例:

:map td :tabnew .<cr> 

在其作用模式(普通、可视、操作符)下,输入td等价于输入 :tabnew .
而普通模式下输入:tabnew . 就是打开当前目录,
如果再定义绑定:

:map ts td

就是指在其作用模式下输入ts等价于td,也就是打开当前目录。不过如果没有特殊需要,一般不建议递归映射。

noremap

:moremap和:map命令相对,作用模式和命令格式都相同,
只不过不允许再对{rhs}进行映射扫描,也就是{lhs}定义后的映射就是{rhs}的键序列,不会再对{rhs}键序列重新解释扫描。
它一般用于重定义一个命令,当然如果:map不需要递归映射的话,建议使用:noremap,比如:

:noremap ts td 

它的意思是在其作用模式下,输入ts就是输入td,但是和:map不同的是,此时td再不会做进一步扫描解释。
虽然之前已经定义了td,但是不会对td再做扫描

unmap

:unmap是对应取消:map绑定的{lhs},作用模式相同,命令格式

:unmap {lhs}

例如:

:unmap td 

就是取消在其作用模式中td的绑定,比如之前td被绑定为:tabnew .,此时此绑定消失。

mapclear

:mapclear时对应取消所有:map绑定的,慎用!

nmap

:nmap是:map的普通模式板,也就是说其绑定的键只作用于普通模式。例如:

:nmap td :tabnew .<cr> 

在普通模式下等效

:map td :tabnew .<cr> 

nnoremap

:nnorempa和:nmap的关系和:noremap和:map的关系一样,只是:nmap的非递归版

nunmap

:nunmap和:nmap的关系和:unmap和:map的关系一样,取消:nmap的绑定。

nmapclear

:nmapclear是对应取消所有:map绑定的,慎用!

可以发现一个规律,前4个是一组,后4个时一组,后一组比前一组多一个n就是指只作用于普通模式。
其中每组内*nore*是其对应的非递归版、*un*是取消绑定某个<lhs>绑定、clear后缀是取消所有绑定。
发现了这个规律,再翻到前面的模式代号表,
大体可以猜到vmap、xmap、smap、omap是什么意思,以及相对应的nore版本、un版本、clear版本。

另外,{rhs} 之前可能显示一个特殊字符:

  • * 表示它不可重映射
  • & 表示仅脚本的局部映射可以被重映射
  • @ 表示缓冲区的局部映射

键表|key-notation|

  • <k0> - <k9> 小键盘 0 到 9 *keypad-0* *keypad-9*
  • <S-…> Shift+键 *shift* *<S-*
  • <C-…> Control+键 *control* *ctrl* *<C-*
  • <M-…> Alt+键 或 meta+键 *meta* *alt* *<M-*
  • <A-…> 同 <m-…> *<A-*
  • <t_xx> termcap 里的 “xx” 入口键

特殊参数

  • <buffer>
  • <nowait>
  • <silent>
  • <special>
  • <script>
  • <expr>
  • <unique>

可以按任意顺序使用。它们必须紧跟在命令的后边,而在其它任何参数的前边。

<buffer>

如果这些映射命令的第一个参数是<buffer>,映射将只局限于当前缓冲区(也就是你此时正编辑的文件)内。比如:

:map <buffer> ,w /a<CR> 

它的意思时在当前缓冲区里定义键绑定,“,w”将在当前缓冲区里查找字符a。同样你可以在其他缓冲区里定义:

:map <buffer> ,w /b<CR> 

其作用域也只在各自的标签里。同样要清除这些缓冲区的键绑定也要加上<buffer>参数,比如:

:unmap <buffer> ,w 
:mapclear <buffer> 

<nowait>

定义局部于缓冲区的映射 “,” 时,可能有另一个全局映射也以 “,” 开始。
这时你需要键入另一个字符,Vim 才能知道是用 “,” 映射还是更长的那个。
要避免这个问题,加入 参数。
这样映射一旦匹配就会被使用,Vim 不会等待更多字符的输入。但如果那些字符已经输入了,还是会使用的。

<silent>

执行键绑定时不在命令行上回显,比如:

:map <silent> ,w /abcd<CR> 

输入,w查找abcd时,命令行上不会显示/abcd,如果没有<silent>参数就会显示出来

<special>

一般用于定义特殊键怕有副作用的场合。比如:

:map <special> <F12> /Header<CR> 

<unique>

一般用于定义新的键映射或者缩写命令的同时检查是否该键已经被映射,如果该映射或者缩写已经存在,则该命令会失败

:map <unique> ,w  /[#&!]<CR>

这个例子将失败:

:map ,w  /[#&!]<CR>
:map <buffer> <unique> ,w  /[.,;]<CR>

<expr>

如果定义新映射的第一个参数是<expr>,那么参数会作为表达式来进行计算,结果使用实际使用的<rhs>,例如:

:inoremap <expr\> . InsertDot() 

这可以用来检查光标之前的文本并在一定条件下启动全能 (omni) 补全。

这里是插入递增的列表编号的例子:

let counter = 0 
inoremap <expr> <C-L> ListItem() 
inoremap <expr> <C-R> ListReset() 

func ListItem() 
    let g:counter += 1 
    return g:counter . '. ' 
endfunc 

func ListReset() 
    let g:counter = 0 
    return '' 
endfunc 

CTRL-L 插入下一个数值,CTRL-R 复位计数且返回空字符串,这样就不会插入任何内容。

<Leader>mapleader

要定义一个使用 “mapleader” 变量的映射,可以使用特殊字串 ““。
它会被 “mapleader” 的字串值所替换。如果 “mapleader” 未设置或为空,则用反斜杠代替,例如:

:map <Leader>A  oanother line<Esc>

和下面一样:

:map \A  oanother line<Esc>

但是当:

:let mapleader = ","

又相当于:

:map ,A  oanother line<Esc>

注意 “mapleader” 的值仅当定义映射时被使用。后来改变的 “mapleader” 不会影响已定义的映射。

  1. VIM 参考手册-MAP