前言
本文内容侧重于为习惯在现代IDE环境中开发的程序员提供vim操作模式入门和提高的学习路线。笔者认为,现代IDE已经足够先进和便捷,而众所周知vim难度高学习曲线非常陡,使用纯粹的vim编辑器并不是vim新手的最佳学习途径,新手容易在一大堆零散命令以及操作技巧中受到打击。
对于vim新手来说,依托IDE的vim插件,在比较轻松的环境下练习肌肉记忆以及vim思维方式,不失为一种合适的选择。而且,在IDE的vim插件中练就的操作,几乎全部都是适用于纯粹的vim编辑器的,不必担忧这是错误路线,因此如果你还有20%
的意愿选择想学习vim,请跟随本文设计的路线进入练习,笔者保证在经过少数的练习时间后,得到的回报是200%
的。既可以在IDE中使用vim模式优雅修改代码,也可以得心应手地在远程服务器等cmd环境中使用vim编辑器。
Tips: vim起源于Unix下的vi和ed编辑器,它们比鼠标以及所有可点击界面出现的都要早,因此,“不用点击” “纯键盘操作”等基因被延续了下来。vim就像学习弹钢琴一样,经过陌生到熟悉的阵痛期,将会体验到vim那句口号“以思维的速度去编辑代码”的成就感。
环境准备
本文使用的IDE是Android Studio,插件是Intellij IDE平台通用的IdeaVim
,插件版本1.9.2。
安装完重启后,IDE右下角即有一个绿色渐变的图标V
表示已启用了vim模式,如果是灰色V则表示关闭了vim模式,点击即可以打开插件菜单。这里有一项比较重要的,Enabled
启用和关闭vim模式,当遇到目前积累的vim知识不足以实现手头比较紧急的修改任务时,暂时点击关闭。
菜单Open ~/.ideavimrc
打开配置文件,可以修改vim的默认行为,增加一些帮助提高效率的插件等,vim是高度可定制化的,IdeaVim插件的自定义配置保存在系统用户目录(Mac示例:/Users/youzi)下的.ideavimrc
文件中,该目录下可能还有另一个文件叫.vimrc
,没错它是系统中的vim编辑器的配置文件。
现在先进行一项重要的配置:与系统共享剪贴板。相信如果之前用过vim可能会遇到一个情况,在浏览器中<⌘+c>
别人的一段代码,使用粘贴操作却无法粘贴到vim(使用<⌘+v>
更不可以呀),同样的在vim中使用复制操作复制的文本,也没法在浏览器软件中<⌘+v>
出来,非常影响效率,这是因为vim有独立的一套剪贴板,在vim中称为寄存器(古老吧,就当作剪贴板看待),话不多说,增加一项配置:
set clipboard^=unnamed,unnamedplus
使配置生效可以重启IDE,但如果是通过菜单Open ~/.ideavimrc
在IDE中打开配置文件,编辑区右上角会有一个悬浮按钮可以快速应用新的配置。
为了保持纯粹,这里不再做过多配置,行文中会再次安利一些其他vim配置,酌情添加。
---- 下面正文开始 ----
第一阶段
认识几种模式
vim与可点击编辑器不同的是区分了几种模式,因此与其他编辑器不同,开始使用vim之前不是尝试去敲键盘看效果,而是要先看说明书,这里借用笔者的vim编辑器启蒙博客的一段经典的开始:
- 刚启用IDE vim插件时,vim处于Normal模式下
- 按下按键
i
,此时进入了可编辑状态,也就是Insert模式 - 现在可以输入文本进行编辑文件了
- 按
Esc
,返回了Normal模式 - 按下按键
v
,此时发现光标所在的字符底色是选中的蓝色,也就是可视选择状态,类似于按住了鼠标左键 - 使用键盘
↑←↓→
即可控制选中的范围 - 按
Esc
,返回了Normal模式 - 键盘输入冒号
:
,此时处于命令模式,编辑区的底部会有一条命令输入栏,输入的字符都会作用在这里,在命令模式可以输入一些控制指令 - 再输入
w
,回车,这个在vim编辑器中表示write写入文件,也就是保存指令,在IDE中没有多大意义(IDE会自动保存修改),这里只是展示一下命令模式,输入命令回车后,会回到Normal模式 - 处于命令模式时,可以直接按
Esc
返回Normal模式,而放弃输入命令
在IDE中,可以通过光标的形状判断当前处于Normal还是Insert模式,矩形光标表示正处于Normal,常规的竖线光标表示正处于可编辑状态的Insert模式。
Esc
是救命键,如果不知道自己正处于什么模式,多按几次Esc
就回到了Normal模式。对比其他文本编辑器,Vim设计的几个模式咋看起来很奇怪甚至可能会觉得多余,这里打个比方,就像一个画家在画画,Insert模式时画家在画板上挥毫勾勒作品,但画家每画几笔,也要停下来思考构图,画家在思考时可能会想刚刚画下的那笔需要移个位置、刚刚那笔应该使用朱砂着色,思考相当于Normal模式,而vim比画板高级,它可以在思考模式下把刚刚写的代码移动位置、全局替换单词等许多功能。对于程序员来说,绝大多少时间并不是在输入代码,而是在思考和阅读代码,在代码中穿梭跳转,即使涉及到修改,也不一定非要在Insert模式,Normal模式下复制、替换、移动或是删除代码也是更加常见的场景。
本小节的目标是认识vim当前所处的状态,以及各个模式之间的切换,领会之后可以进入下以小节。
Tips:如果在vim编辑器环境而非IDE练习,除了知道切换模式,还需要知道怎么退出。多按Esc
确保在Normal模式,输入:q!
回车;冒号进入命令模式,q表示quit退出,!叹号表示放弃所有更改。
认识基础常用的操作符与动作命令
这一小节的名称可以先不必理解,需要注意的是练习以下每个操作符与命令的前提,都是先把编辑器Esc
到Normal模式。
vim风格的移动命令
前面介绍按v
进入可视选择状态时,移动光标使用的是键盘的方向键,其实vim也有自己的方向键,右手键区的h j k l
分别代表的就是← ↓ ↑ →
,记忆方式可以想象j
是向下的箭头。使用h j k l
还是← ↓ ↑ →
都可以,这只是个习惯问题。现在可以在编辑器Normal模式(或者按v
在可视选择状态)中体会一下h j k l
精确移动光标。
除了逐字符移动光标,还可以按w
移动到下一单词开始处、或者e
移动到下一单词结尾处(注意e
的行为跟光标当前是否在单词结尾相关)。现在可以在编辑器Normal模式(或者按v
在可视选择状态)中体会vim对单词的定义,单个或连续的符号被当作一个“单词”。
以上动作命令可以结合数字,实现更快的移动:例如想注释(或移动)当前光标所在行和往下5行,则可以按如下操作
- 按
v
进入可视选择 - 按
5j
使光标向下移动5行 - 按
<⌘+/>
注释代码(或使用IDE的移动代码功能Shift+Option+上下方向键
移动这6行代码)
这里再配上几个移动命令,偶尔会派上用场:
0
-> 数字0表示移动光标到行首^
-> 移动到行首第一个非空字符(空字符就是blank字符:空格、回车换行、tab)$
-> 到行尾g_
-> 到行尾最后一个非空字符- 实际的代码编辑场景下,其实
$
比g_
更常用和方便输入
练习以上的移动命令,在小范围精确移动光标的场景下多练习,加深印象。
到这里为止,可能你还不能丢开触控板,还是习惯滑动和点击到特定的代码位置才会开始vim相关操作,这没有关系,在讲完下一小节的常规复制、粘贴、剪切(删除)后,再继续学习更符合人类思维习惯更快速的移动命令。
Tips: IDE本身支持显示代码行号,可是在使用数字加
j k
上下移动时,难道要口算加减法吗?显然有点费力。点击右下角图标V
->Open ~/.ideavimrc
打开配置文件增加一行:set clipboard^=unnamed,unnamedplus "我是vimrc的注释,新增下面这行,注意没有逗号 set number relativenumber
最后记得应用vimrc的更改。解释一下,
number
让编辑界面展示绝对行号,再结合使用relativenumber
,最终把非光标所在行的行号改为 1 2 3 4 5...
vim的复制粘贴
这里的复制粘贴,依然是在Normal模式下讨论的。
首先停下敲键盘,眼熟一遍按键:y
表示复制;p
表示粘贴;d
表示剪切(删除);u
表示撤销一次操作(这里介绍它是方便重复练习使用~)。因为接下来输入的很多操作会需要2个及以上的按键输入组合才能实现,现在有必要先介绍一下IDE的右下角状态栏有一个显示已经输入命令的位置:
如图所示,当前笔者输入了y2
。这个有助于知道是不是已经有已输入但没结束的指令(换个说法 是不是误触键盘,导致在Normal模式输入了一些乱七八糟的“指令”),如果这里存在不想要的输入,按Esc
即可清除。
现在先结合可视选择来使用y p d
操作,这对于原本习惯鼠标操作的程序员是比较友好的。下面以复制粘贴操作讲解,d
剪切与y
复制类似,剪切的内容同样到了vim的剪贴板,不再赘述。
在Normal模式下,光标定位到期望复制的开始处,按v
进入可视选择,再按移动命令选中想要的,如$
选中到行尾,或者按N次hjkl
控制光标移动去选中,接着按y
即完成复制,同时退出了可视选择回到了Normal模式。再移动光标到期望粘贴的地方,按小写p
粘贴到光标所在字符之后,按大写P
粘贴到光标所在字符之前。
接着放弃可视选择的帮助,直接去执行复制和剪切指定的代码段,这需要使用组合命令了。
在Normal模式下,光标定位到期望复制的开始处,按y
,表示打算复制内容,接着输入移动命令即完成了复制。举一些例子:ye
从光标位置复制到单词结尾、y$
从光标位置复制到行尾,y3e
从光标位置复制到第三处单词结尾,^y2e
定位光标到行首接着复制前两个单词。可以发现,没有可视选择的支持,控制光标移动都是一步到位,不能再输入N次移动命令选好再y
复制这样玩了。到现在为止,可以看出 越熟练控制光标移动,操作vim的效率会越高。
练习<移动光标><操作><移动光标>
的组合命令,虽然到目前还是不能做到媲美触控板的效率,但是已经实现变强的第一步了~~
如果还记得前面我们设置过vim与系统共享剪贴板,那现在可以试一下在vim之外复制粘贴啦。
回到标题,现在可以来厘清操作符和动作命令了。移动光标的是动作命令,而刚刚学习的复制粘贴剪切即是操作符。vim强大的根源,很大部分就是体现在操作符 + 动作命令 = 操作
这个语法规则中。
这个语法规则也有一些例外,这里举一些常用的操作:
yy
复制当前行3yy
复制包括当前行的三行dd
剪切(删除)当前行3dd
剪切(删除)包括当前行的三行>>
当前行增加缩进3>>
包括当前行的三行增加缩进<<
当前行减少缩进
第二阶段
再谈模式切换
前面从Normal模式进入Insert模式只介绍了按键i
,这显然是不够的,IDE的<Shift+↵>
新起一行等操作在代码编辑中特别常用,下面介绍从Normal模式进入Insert模式的更多常用命令。
插入模式命令不多,并且都是成对出现的,很方便记忆:
i
Insert,在光标前插入a
Append,在光标后插入I
在当前行首的非空字符前插入A
在当前行末插入o
在当前行的下面插入空行O
在当前行的上面插入空行
可以总结一下vim命令的一个规律,向后和向下等方向是方便输入的小写字母,向前和向上是对应的大写字母。
以上这些是纯粹的插入指令,vim还有一种更加常用的指令c
,在Normal模式下删除所选范围的代码再进入Insert模式,换个说法就是替换
,它的用法与y
复制d
剪切类似,搭配移动光标的组合命令实现快速删除并进入Insert。
下面的示例演示指令c
的用法:
cw
替换当前光标位置到单词结尾的内容c$
替换当前光标位置到行尾的内容(只输入大写C
也是同样效果,但是,不建议初学记忆太多)cc
替换当前行3cc
替换三行v
3j
c
可视选择这个老朋友在这里也是可用的
说完Normal转Insert,也许读者已经注意到,vim命令都要在Normal下使用,那在编辑模式中突然想执行命令可不可以呢?像平时写代码,写着写着<⌘+v>
粘贴个代码不是非常常见吗,Insert切换到Normal粘贴了再切换回Insert很显然就不舒服了。vim提供了Insert模式临时输入命令的切换手段,这就是Insert-Normal模式,这名字取的就跟没取一样,要从Insert模式切换到Insert-Normal模式,输入<⌘+o>
,接着就可以输入命令了例如p
粘贴一下代码,命令执行完,会自动回到Insert模式。
现在可以更加符合期望地切换到Insert去继续修改代码啦~ 即使还不能丢开触控板,但是相信已经对vim少了许多的畏惧和抵触。
重复
日常写代码中实际上是存在许许多多的重复性操作的,例如为一个HashMap添加一堆埋点的key-value,在IDE中我们会使用<⌘+d>
复制多行put(key, value)再做修改。vim对重复的处理除了上面演示的数字组合命令,如yy5p
复制当前行并粘贴5次,还有vim中的.
命令,它可以让我们非常方便地重复上次的修改,这个“上次的修改”可以很简单,也可以很复杂,一次修改的单位可能是字符,一个单词,一整行甚至整个文件。
可以尝试在输完一次操作后,按.
,看下vim会如何重复上一次的操作,这里先留给读者探索感受,后文会对.
命令这个vim的多面手再做深入介绍。
更快地移动光标
以查找代替移动
对于上面的基础移动操作,在实际使用IDE浏览代码的过程中肯定是效率很低的,相信在IDE中常常是<⌘+f>
查找来移动目光到想要的位置,这一小节就来讲讲vim的查找。
首先介绍在光标所在行内的查找,键入fa
表示从当前光标位置开始,向后查找当前行的第一个字符a
,如果找到了光标会移过去字符a
的位置,如果没有则光标不会改变位置,类似的三个查找命令还有:
Fa
向前查找第一个字符a
ta
向后查找当前行的第一个字符a
,如果找到了光标会移过去字符a
的前一个字符位置Ta
向前查找当前行的第一个字符a
,如果找到了光标会移过去字符a
的后一个字符位置 还可以结合数字实现查找第x个:2fa
向后查找当前行的第2个字符a
别忘了结合y
d
和c
等操作的练习,举个例子,要复制if (event.code == Option.isSuccess())
中if的条件内容,当前光标在=
处,目前可以这样操作:T(
y
2t)
接下来看对标IDE的<⌘+f>
查找的vim实现。键入/
,此时编辑器底部出现了命令模式的命令输入栏,接着键入想搜索的内容,回车即可将光标定位到搜索结果的第一个,按n
跳转到下一个结果,按N
则跳转上一个结果。到这里也许会问,命令模式怎么粘贴啊,就算搜索的是一个单词,纯手打又慢又容易出错。
想要在命令模式下粘贴内容到命令输入栏,就要用到vim寄存器的概念了,假设现在已经复制了想要搜索的内容,键入/
,接着按<⌘+r>
,再按数字0
,即可粘贴vim的0号寄存器的内容到命令输入栏了,更多关于寄存器的概念这里先不了解。
依赖代码结构的光标移动
有时候我们可以不必用到上面的查找指令来达到类似的效果,像代码中的变量名、方法名等独立的单词(指前后有空格的一整块),当光标在单词上时,按*
即可跳转到该单词下一个出现的位置,按#
即可跳转到该单词上一个出现的位置,这在查变量或者方法使用时可以很快捷地跳转。
vim提供了%
命令,可以在一组开、闭括号间跳转,默认情况下,%
可作用于()
[]
{}
,如果想要复制、替换的是代码块,现在可以很方便选中啦,即使是地狱嵌套的代码,也不用睁大眼睛看辅助线和IDE高亮去匹配括号了~
区域选择
前面介绍了这么多光标移动操作,无非就是在践行<移动光标><操作><移动光标>
这条组合命令,但vim能做的不仅仅是这些,对于选中想要的代码这件事,除了通过前后光标的位置来确定,还有另一种更优雅的方式。
vim有一个文本对象(text-objects)
的概念,文档解释是基于结构定义的文本区域,听起来有点迷茫,大概的意思可以近似理解为“被引号、括号、空格括起来的文本区域”。由于此功能先讲容易糊涂 一看便清楚,先上例子:
Normal模式,下面这句代码,当前光标在 Util 的 U 处
mViewModel.timeStr.set("CreateTime: ${TimeFormatUtil.format(date.time)}")
1. 想选中set方法内的整个字符串,可以键入 vi) 或者 va"
2. 想选中TimeFormatUtil,可以键入 viw,接着还想进一步选中{}内的内容,可以键入 i}
3. 想替换{}内的内容,可以键入 ci{ 或者 ci}
聪明的小朋友可能已经看出来是什么情况了,接下来看看区域选择的语法格式:
<action>i<object>
<action>a<object>
这里的<action>
表示想要对文本区域执行的操作,它可以是v
选择、y
复制、c
替换并进入编辑、d
删除;i
或者a
表示选取的范围是否包含选区边界;<object>
表示某种结构,可以是w
表示一个单词、括号的左或右、t
表示xml标签。i
或a
加上<object>
,就是所谓的文本对象了。
区域选择也是可以结合数字使用的,再贴个例子理解一下:
如果小朋友还是很迷茫,不知道区域选择快在哪,这里可以演示一个简单的例子:yiw
复制当前光标的单词,然后光标定位到另一个单词,viwp
就粘贴替换掉另一个单词啦。相比通过移动光标去控制选取,区域选择是不是更舒服了呢~ 先用着常见的<object>
,只要熟练度上来了,了解更多的<object>
只是看一眼就会的事。
浏览:滑动与跳转
触控板与鼠标滚轮的滑动是我们习以为常的操作,IDE还准备了<⌘+g>
跳转到指定行数,这些在vim模式下依然都可用,不过既然现在要提高效率,手不用在键盘和触控板来回切换,还是有必要学习一下vim中可以怎么实现滑动的。
首先是三个比较简单少用的
812G
跳转到第812行gg
跳转到文件第一行G
跳转到文件最后一行 笔者比较常用的代替触控板的操作是下面几个命令的组合运用:<⌘+d>
down,向下翻半屏<⌘+u>
up,向上翻半屏zz
让光标所在行在编辑区居中显示zt
top,让光标所在行大概位于编辑区顶(够看就行,好像不会位于最上一行) 以上的翻页足够用于浏览代码了,差不多看到目标代码后再加上zz
或zt
,即可准备开始修改操作了。
因为我们是基于IDE vim模式进行的操作,或许你已经看到过这个提示:
在vim模式下,首次使用vim与IDE都定义过的组合键时,会弹出这个提示说该快捷键现在用于vim命令啦,这也是在IDE的vim模式操作比较尴尬的点,因为可能会面临两难的选择:到底我该把组合键给IDE用还是给vim用🤣 举个例子:<⌘+b>
在IDE中是快速跳转到光标所在的变量或方法的定义位置或使用位置,在vim中也有类似的命令gd
或gD
,但用了就会发现跟IDE的<⌘+b>
没法比啊,所以把<⌘+b>
留给IDE用吧~ vim中的<⌘+b>
和<⌘+f>
是一对,表示backward向下滑动一整屏 forword向上滑动一整屏,留一个或都不留都是没啥问题的,根据自己的喜好来选择即可。
点击右下角图标V
-> Settings...
打开IDE的设置,如下图所示,在这里可以自由设置组合键该给谁使用。
到这里已经学会了笔者日常使用中90%的vim功能啦,为了不增加记忆负担,行文中只挑特别紧要的命令讲解,勤加练习比死记硬背更有效~
下一部分会讲解命令模式的部分实用场景,以及补全前面埋下的一些需要重点讲解的操作,不用着急进入下一阶段,练习上面的知识才是最有效的提高方式。
第三阶段
查找并替换
前面练习区域选择的时候举了一个例子:yiw
复制一个单词,viwp
替换掉另一个单词,那如果再执行viwp
还奏效吗?你会发现执行了一次viwp
后vim的默认剪贴板已经变了,那如果要替换多处要怎么做呢,这里介绍vim的substitute命令(记住名字中里一个s就行了)。
在IDE中智能修改变量名可以使用组合键<Shift+F6>
,现在我们来舍近求远,用另一种方式给当前文件的某变量改一下名。
光标定位到变量名,yiw
复制一下,键入:
进入命令模式,接着输入%s/
,接着<⌘+r>
再按数字0粘贴刚刚复制的变量名到这里,接着输入/新的变量名/gc
,回车,此时编辑区会选中待修改的位置,命令输入栏会提示询问是否使用新的变量名替换这个位置,这里我们按y
同意此位置修改n
跳过此位置修改,完整选项含义后文再列出。
看一下整体输入的命令:
:%s/old/new/gc
手动控制将文件中的old
替换为new
:%s/old/new/g
不询问直接将文件中的old
替换为new
,比较危险,因为hold
也会中招
单词old
的位置是支持正则匹配的,写一些常规的正则匹配感觉应用场景不多,写精确的匹配式又复杂了,还不如想点别的办法完成操作,因此这里不做介绍了。
y
替换此处匹配n
跳过此处匹配q
退出匹配l
last,替换此处匹配后就退出a
all,替换此处以及之后的全部匹配
隔空复制、移动
我们要复制或改动某处代码,下意识的操作是把光标移过去,从前是触控板,现在是vim移动命令,但是如果我们能用目光焦点去移动代码块,不费力气去想怎么移动光标,是不是编辑效率就能更接近大脑的思考速度了呢,vim在命令模式下提供了移动m
和复制t
的指令,两个指令的记忆方式:move
移动、copy To
复制到某处。
语法:
:[range]m{position}
:[range]t{position}
可以看到两个指令使用上是完全一致的。[range]
是需要移动或者复制的行号或行号范围,可选,缺省是当前光标所在行;{position}
是目标行号,可以用.
表示当前行。这里对[range]
说明一下,行号既可以是绝对行号,也可以是相对行号,因此不管前面有没有设置vimrc显示相对行号,都不会影响使用。
举几个例子:
:12t.
把第12行(绝对行号)的内容复制到当前行:t12
把当前行内容复制到第12行:8,12t.
把第8到12行的内容复制到当前行:8,12t96
把第8到12行的内容复制到第96行:t.
等价于yyp
,复制并粘贴当前行
上面是绝对行号的例子,相对行号需要配合+-号来表示:
:-10,-2t+2
把往上第10到往上第2行的内容复制到往下第2行
现在,无需考虑怎么移动光标以及怎么选中,即可完成内容的复制和移动啦~ 如果觉得输入指令比较累,键入:
后是可以使用↑↓
方向键调出历史指令的,修改一下旧指令即可。
标记跳转
IDE有Bookmarks功能,vim也有类似给代码某个字符位置添加标记的功能,并且在vim中允许我们通过命令快速跳转到标记。
Normal模式下键入m
和一个用于标记的字母(区分大小写),标记成功后,使用`
和标记的字母即可跳转回标记的位置。用于标记的字母,a-z
是文件范围内的标记,A-Z
是全局可跳转的标记,纯粹的vim编辑器没有支持将标记处特别显示,在IDE中,如果使用了A-Z
的全局标记,效果是和Bookmarks一样的,会在行首显示标记字母。vim还会自动为我们标记好上次修改的位置,使用`.
可以方便的跳转到上次修改的地方。
有关vim的其他跳转技巧,笔者认为IDE的Double Shift更加灵活方便,这里就略过不提。
高效率的重复
前面介绍了.
命令,它可以重复上次的修改,想要最大效率地利用这个重复,则需要比较巧妙的规划好"一次修改",理想的状态下,我们希望是一键可以移动到下一处修改位置,然后用.一键完成修改,再一键移动到下一处。
因为移动命令会切割"一次修改",所以目前想要提高.的效率,可以从减少不必要的移动开始着手,思考自己的操作是否是符合以上的一键移动一键修改这个期望。
举个例子,现在期望在光标所在行以及往下的2行末尾增加分号,如果使用以下操作步骤:
$
到行尾a
光标后插入,输入分号,<Esc>
j
移动到下一行- 重复步骤1、2
可以发现,这里1和3都是在移动光标,我们可以使用上面学过的A来把1 2合成一步,这样就减少了移动的操作,变成了下面的样子:
A
行尾插入,输入分号,<Esc>
j
移动到下一行.
命令重复j
移动到下一行,.
命令重复 当把不必要移动收进一次修改中之后,再结合j或10j等一次移动去重复修改,.命令才能发挥更大的优势。
结语
以上是学习路线的全部内容,完结撒花✿✿ 本文是为女朋友梳理一条切实可行的vim入门路线,对于个别操作的介绍没有面面俱到,如果你跟随本文掌握了全部的使用技巧,问接下来该做什么,笔者的建议是命令模式:help
多看看vim的文档。祝变得更强!
参考文献
[1] 陈皓.简明VIM练级攻略[EB/OL].(2011.09.07).[2022.03.30].https://www.coolshell.cn/articles/5426.html
[2] Drew Neil.Practical Vim[M], 2012