Mapping

mapping 顾名思义, map a b, 当我执行 a 操作时, 它会做 b 操作会做的事.

看个例子, 在 Vim 命令行中, 输入:

:map \ dd

表示, 在 normal 模式下, 按下\, 就会删除当前光标所在的行.

mapping的设置, 跟模式有关系.

nmap : normal mode 下的 mapping, 只在 normal 模式下有效.

vmap : visual mode 下的 mapping, 只在 visual 模式下有效.

imap : insert mode 下的 mapping, 只在 insert 模式下有效.

omap : operator-pending mode 下的 mapping, 只在 operator-pending 模式下有效.

map: normal, visual, operating mode 下的 mapping, 在 normal/visual/operator-pending 模式下有效.

map 有一个大坑, 叫做 Recursion, 书中给了一个例子, 比如:

:nmap dd O<esc>jddk

normal 模式下, 按下dd, 等同于执行了O<esc>jddk , 而 O<esc>jddk 也有 dd, Vim 就会再次 mapping, 如此无穷尽….

解决方法是使用noremap, nonrecursive mapping. 修改上面那个命令:

:nnoremap dd O<esc>jddk

这样就正常了. 鉴于 noremap 能避雷, 作者给到的意见时, Always using noremap instead of map.

再看个例子:

:nnoremap <C-s>  :suspend<CR>

上述命令表示, normal 模式下, 按住 Ctrl + s, 就等同于在命令行输入了:suspend 然后回车 ,这里 <CR> 表示Enter回车键.

都说到<CR> , 不妨来看看 VimScript 中 的 一些常用的 keycodes :

<Esc> : 代表 Esc 键
<C-{key}> : Ctrl + 任意键, 通常是字母键
<S-{key}> : Shift + 任意键, 通常是字母键
<CR> : Enter键,也可以用<Enter>, <Return> 来表示
<Space> : 空格键
<Leader> : Leader 键
<Left> : 左移方向键, 类似有<Right>, <Up>, <Down>

那么, 如何知道 VimScript 中所有 key 的特殊标记? 用万能的:help 就好了, 命令行输入:

:h key-notation

可以查看所有的 key-notation.

我还记得刚入门时, 有时候看到别人的 vimrc 文件中, 有些 keycode 是全部小写的, 比如 <cr>, <esc>, 当时觉得, 有的人大写, 有的人小写, 哪种才是规范的呢? 直到看了文档, 才知道官方是首字母大写, 也算解了我的一个小困惑.

Vim 中有个特殊的 mapping, <Nop>, 表示什么也不做. 比如:

:inoremap <Esc> <Nop>

Insert 模式下, 按下 Esc 键, 什么也没有做. [慎用!!!]

现在, 我们可以用学到的知识来写个简单的禁止使用上下左右键的功能:

.vimrc 文件中, 添加如下代码:

" disable up, down, leaf, right
" normal mode
nnoremap <Up> <Nop>
nnoremap <Down> <Nop>
nnoremap <Left> <Nop>
nnoremap <Right> <Nop>

" visual mode
vnoremap <Up> <Nop>
vnoremap <Down> <Nop>
vnoremap <Left> <Nop>
vnoremap <Right> <Nop>

" insert mode
inoremap <Up> <Nop>
inoremap <Down> <Nop>
inoremap <Left> <Nop>
inoremap <Right> <Nop>

这样就只能用 hjkl 了.

好了, 除了 Operator-Pending Mappings 外, 基本算是缕清了, 整点好吃的, 犒劳下自己吧.