Contents
今天说一个古老的话题,VIM作为一个编辑器,香么?
初见
Stack Overflow上有两个问题常年高居热门榜,那就是"我要怎么在VIM内编辑"、"我要怎么才能退出VIM"。
这也是我初次使用VIM的感受,linux无UI的黑框框对新手小白已经很不友好了,这破玩意儿编辑器用起来也这么反人类,是闹哪样的?就不能好好的,开箱即用,打开就能编辑,最多加一个保存,一个撤销复用功能,然后用exit或者ctrl+c退出,不就完了么?
“吾不笑别人,单笑乌班图无谋,红帽少智……”(狗头)
最诡异的莫过于,你嗤之以鼻的东西,网上冲浪见到的大佬们都觉得香。错的是我,还是世界?
认识VIM
话不多说,接入正题,如何正确的使用VIM?这部分就是想从一个VIM中级使用者的角度,缓缓揭开VIM的使用真相。
1. 历史与基本原则
理解了VIM的使用原则,是使用的第一步,之后遇到新的快捷键,也会很快上手。
首先明确一点,VIM的使用前提是全键盘操作,上古时代,没有视窗操作系统,操作全凭手打,这是VIM诞生的背景,使用者能盲打是提升VIM使用效率的第一步。对于个人而言,如果不适应无鼠标的工作,那么VIM的存在会很膈应,使用哲学上就是和个人习惯相悖的。
要认识现在,先了解过去,一起看看VIM和它的祖爷爷们的历史:
- 1966年,QED(Quick EDitor)编辑器诞生,那个时候没有显示屏作为显示终端,所谓的终端就是把一行信息打印到纸上的打印机,所以QED诞生的时候,就是一个行编辑器,操作时,需要手动指定更新内容和范围;
- 1969年,当时大名鼎鼎的AT&T内诞生了基于QED的ED编辑器,
- 1976年,em(Editor for Mortals)诞生;
- 同年,加州大学伯克利分校的研发人员在em基础上开发出了ex(Extended);EX是最后一代行编辑器,
- 再后一年,VI(visual interface)诞生,vi最大的变化就是可视化的编辑,摒弃了过去的行编辑模式,人们终于可以在终端上看到整个文本了,
- 这之后,编辑器届的发展一度很喧嚣,针对VI的改进版本层出不穷,直到1991年,VIM的第一个版本才正式发布,VIM的取名源自Vi IMproved。目前VIM已经发布到第八个正式版本,也就是VIM 8。
我们今天使用的一些命令,都可以看到它祖辈们的影子,比如hjkl
用来移动光标,比如ex
目前都还是内置的行编辑命令,命令行模式也被叫做ex模式,不经意间透露出“忆往昔峥嵘岁月稠”的沧桑,那是计算机萌芽期留下来的活化石。也从侧面反映,今天VIM的样子,是经历过数十年码农的悉心调教后,长成的模样,每一个使用细节的背后,必然有其设计的理由,试图理解这里面的逻辑,也会别有洞天。可以记住这句话:VIM能以与思考同步的速度编辑文本。
除了上面列的几点,祖辈们给VIM留下的最大的特点是:编辑器的模式。
所有新手小白对于VIM的愤怒,都来自于对模式的不了解。 ——鲁迅
打开文件,默认是普通模式,我们只能读文件,不能插入新内容,要直接写文件,需要切换模式,分离读写操作,是一个好习惯,任何层次上都是。这个模式下,我们要学会的是如何更好的移动光标(w,b,z,g,f,F,/,?,$,^,%
),不过不代表普通模式下不能改变文件,我们有x,d,p
等命令来完成删除、复制等操作。
我们惯常使用的编辑模式,对应到VIM上,叫插入模式,普通模式下a,i,c,s
等按键,可以达到切换到插入模式的效果,插入模式只能进行简单的编辑操作。这个模式下,按键是用来处理输入的,也没有太多快捷键,但是某些场景下可以与其它模式进行联动,加快输入的速度。
再接下来,是可视模式,视窗操作系统下,我们要选取一块区域的时候,可以滑动鼠标进行,在VIM上,可视模式,就是用来做这个事情的,将选取的部分高亮,为下一步的处理做准备。通常按v
可以进入,或者shift+v
进入行选择模式,ctrl-v
进入多列选择模式。可视模式下,普通模式的快捷键大多有效,比如选中以后y
一下,就可以复制选中内容,按下esc
,然后p
一下,就可以快速复制,又或者我们可以通过w,b,$,^,e
等光标移动命令,调整选中区。
最后是命令行模式,也就是前面提到的ex模式,我们在普通模式下输入冒号就可以进入,之前stack overflow上对于怎么退出的问题,就是要在命令行模式下操作的,在这个模式下,常见的可以进行文件、窗口操作,甚至可以运行系统命令行。
展示一张网上找来的VIM快捷键键位图:
要学习所有快捷键是需要花时间在实践种掌握的,这里就不赘述了。建议看一些VIM相关的文档和书籍,再慢慢摸索。
2. 一些技巧
VIM作为历史悠久的编辑工具,在使用上,是有一些准则和窍门的。
技巧1 不要自我重复
.
命令在VIM中表示,重复之前的一次编辑操作,在这个命令的基础上,利用移动+重放的模式可以为我们节省很多重复操作。
举一个例子:
有html文件如下,我们现在要把所有括号内的内容置空,可以怎么做?
(text1),(text2),(text3)
常规操作:
按a
进入插入模式,然后找到内容,一个个删除;
重读操作多次,麻烦。如果有鼠标的话,可能会双击选中,然后删除,然后重复三次,其实效率也不高。
推荐操作:
- 首先
f+(
,表示在行内查找左括号; - 然后回车,找到第一个,按
d+i+(
,d
表示删除,i
表示include,(
表示括号,组合在一起表示:把括号内的内容删除; - 按’;’寻找下一个左括号;
- 然后按’.’,重复之前的编辑操作,这时,第二个括号内的内容就会删除,
- 重复3,4步骤,即可快速重复之前的编辑操作;
可以发现,第二种方式里,我们把移动光标、编辑两个操作分离了,移动光标可以通过查找逻辑来完成,编辑操作只需要执行一次,然后后续只要执行重放逻辑就好了。你甚至不需要切换到插入模式。这样的效率比之前要高很多。
可以再来一个例子,例如,把之前括号内的内容都替换为"good job",步骤如下:
f+t
,查找字母t;c+w
,删除单词并进入插入模式,- 输入“good job”
- 按
esc
退出插入模式 - 按
;
查找下一个 - 按’.’实现重放
- 重复5,6,直到全部改完
这种模式可以总结为:用一个键移动,用另一个键执行。或者可以叫术语“.”范式。
技巧2 选择最优的修改方式
我们在编辑文本的时候,要达到同样的效果,可以有很多种方式,从结果上看,他们都是等价的,这种时候,要如何选择呢?
评估某种修改方式是不是最优,首先可以比较按键次数,按键次数越少,效率越高,然而平局时,怎么选择呢?
举个例子,如下所示文本,假设光标停留在最后一个h上,而我们想要删除的单词是nigh
:
The end is nigh
方式1:db
反向删除,剩下一个字母h
,再用x
删除
方式2:正向删除,b
回到单词开头,然后dw
删除单词
方式3: 删除整个单词daw
,这个命令组合可以理解成delete a word
三种方式的按键次数都是三次,效果都是删除一个单词,那么哪种更优呢?
这个时候我们可以看修改命令的可重复性,可重复性好的命令,有机会和.
范式结合,大幅提高效率;细心的会注意到,第三种方式操作完以后,不光删除了整个单词,同时也连带着删除了单词前面的空格,光标停留在了s
上,而前两种方式光标则停留在了空格上。试想一下,我们在操作完以后想要继续删除is
,只有第三种方式可以无缝复用起来。
所以,评判修改方式的优劣,一看效率,二看可复用性。可以养成选择可复用性好的编辑操作的习惯。
技巧3 认识文本对象
文本对象(text object)是VIM里面非常有用的概念,文本对象的操作可以针对单词、句子、段落这种大范围的文本内容显著提高执行效率。
通常,VIM的命令执行模式如下:
[number]<command>[text object or motion]
其中number
表示作用的文本对象数量,command
表示执行的具体命令,比如d
、p
(删除、复制),之后跟的表示具体的文本对象,比如单词、句子、段落。
我们使用文本对象的时候,通常是一个限定词+一个范围词结合使用。
- 限定词有
a
、i
两种,分别表示一个
和`之内 - 范围词有很多,比如下表所示
字母 | w | s | p | t | <或者> |
---|---|---|---|---|---|
含义 | 单词 | 句子 | 段落 | 标签 | 一组尖括号包围的文本 |
还有很多,比如{
、[
、(
等等,都可以以此类推。限定词和范围词组合起来,比如aw
就是一个单词,i{
表示一组大括号内部的文本。
这个有什么用处呢?
我们可以看下下面这个html,我们想要删除span
这个tag内的文字:
<span>this is a span</span>
可以通过dit
来完成,如果删除后,想立刻进入插入模式,则可以使用cit
又比如,我们要删除函数内的大段内容,如下所示,可以通过a{
、i{
来实现:
技巧4 寄存器
我们在复制内容的时候,有时候想要保留多一些复制栈,但是系统的剪贴板的深度只有1,第二次复制的时候,会把前一次复制的内容覆盖掉。
VIM通过寄存器,解决了这个问题,默认寄存器每次会被覆盖,但是其他寄存器不会被轻易更改。
普通模式下,输入:reg
然后回车,可以看到当前的寄存器变量:
通常,我们删除、复制(d\c\x\y
)执行操作后,受影响的文本会进入默认寄存器""
,我们复制的时候,可以通过命令行模式指定复制到或者剪贴到特定的寄存器上。
各个模式下,如何调用寄存器的值:
- 普通模式:
"{register name}
- 命令模式:
<ctrl+r> + "寄存器名称
- 插入模式:
<ctrl+r> + 寄存器名称
VIM内,内置了以下几种寄存器:
- 无名寄存器,也是默认寄存器,引用方式:
""
- 字母寄存器,引用方式:
"a - "z 或"A - "Z
- 数字寄存器,引用方式:
"0 (数字0)- "9
- 复制专用寄存器,引用方式:
"0 (数字0)
- 黑洞寄存器,引用方式:
"_
- 系统寄存器,引用方式:
"+
、"*
- 表达式寄存器,引用方式:
"=
,所有寄存器里最特殊的一个,用于计算表达式。 - 其他,"% 当前文件名,包含文件路径。"/ 上次查找的内容。". 上次插入的内容。
3. 插件
VIM如果没有插件,完成度只有百分之50,结合各种插件,才能发挥全部的能力。篇幅有限,这里就不多介绍了。
常见比较好用的插件有ycm
、ctags
、nerdTree
等。
争议终结
选择IDE还是VIM?
我个人觉得这种问题没有太大意思,考虑自己的开发环境来匹配最优解即可,现代IDE已经进化的很智能,和作为编辑器的VIM相比,不是一个维度的东西,是无法进行比较的。VIM的优势在于编辑的速度,思考、手、编辑指令之间高度同步,在你高度专注的时候,相比时不时的切换到鼠标上来进行选择和点击,你会更钟情于无鼠标办公,一秒钟的切换成本都是无法忍受的,体验过就理解这么说一点都不夸张。VIM在编辑这件事情上很纯粹。不过做项目不仅仅等于编辑代码,我们还有很多其他的工作,这是IDE擅长的领域。
而对于Linux重度使用者来说,VI/VIM通常是系统自带的编辑工具,这类人群使用VIM是刚需,即使现代IDE很多已支持远程编辑,但是如果能用VIM解决,何必再舍近求远、脱裤子放屁呢?
作为一个工具控,我现在觉得VIM很香。
VIM进阶使用
1. 如何在vim中标记
:marks
命令和:reg
的使用类似,我们可以借助此命令,查看当前vim保存的书签信息。
默认会有0-9
个标签,敲入ex命令:'0
可以跳转到对应的标签位置。
此外我们还可以自定义标签。
:mark Q
表示当前位置添加书签,且书签的名字是Q,
:'Q
可以跳转到书签Q的位置
:delmarks Q
可以删除书签Q
:delmarks!
可以删除所有自定义书签。
2. 不退出vim使用shell命令
两种方式:
:!ls
直接执行
或者
:shell
进入到shell界面,执行完再退出
发表回复
要发表评论,您必须先登录。