后知后觉发现虽然用 Vim 多年,不过一直都处于 vi “模式”,真正的功能很少去深入研究,遇到一些问题解决后也随即放脑后。所以这次希望能够持续的学习和记录,而不仅仅是使用。
移动
在 Vim 的帮助手册中移动操作是按方向区分的,但个人习惯主要以移动对象做区分。
方向
与众不同的方向键应该是 Vi 之中最标志性的动作,一提起 hjkl
只要对编辑器稍微有过兴趣的都知道这便是 Vim 中的上下左右:
- 向左移动:h
- 向下移动:j
- 向上移动:k
- 向右移动:l
文本
词
在 Vi 中是以空格区分词的,但在中文环境下,对词的的区分不是很准确,主要是以标点符号为分隔符,所以常常一跳就是半句话(标点符号也是一个“词”)
- 上一个单词:b
- 下一个单词:w
- 上一个单词的词末:ge
- 下一个单词的词末:e
需要注意的是,如果光标没在对应的位置,上述操作将会先跳到单词的词首或词尾,再次按下时才会跳到预期中的位置。此外,除了上面的四个动作,还有另外四个相应的,区别在于后者移动时会跳过 / 跳到符号:
- 上一个单词(含标点):B
- 下一个单词(含标点):W
- 上一个单词的词末(含标点):gE
- 下一个单词的词末(含标点):E
后者可以简单理解为把符号作为单词的一部分。
行
行相对来说容易理解一些:
- 行首:0(数字 0)
- 行尾:$
- 上一行行首:-(Enter 键同样效果)
- 下一行行首:+
- 行中间:gm
如果文章有缩进的话,想跳到第一个字符上,可以用 ^
,效果同 0
类似,但会跳到非空白字符。另一个需要说明的是 gm
,它的作用是跳到有字符的行中间,而不是编辑器宽度的中间。
句
句子很简单:
- 句首:(
- 句尾:)
句子是以空行为分隔单位的,只要连续的行都视为一句。
段
段和句类似,不过包含句子前后的空行。
- 段首:{
- 段尾:}
文本
这在 Vimium 中最常用了,直接跳到页首或页尾,自然在 Vi 中作用也是一样:
- 首行:gg
- 尾行:G
注意是首行,不是行首,这两个动作直接回到编辑文本的第一行或最后一行。有意思的是如果在这两个操作前加上数字,两者的功能是一样的,比如说无论当前在什么位置 42gg 会跳到文本的第 42 行,而 42G 的作用也同样是跳到第 42 行。
屏幕
上面的移动都是以字、词、句等为单位,而这里是以当前屏幕显示的内容为范围。
屏内
屏内的移动是以当前编辑器显示的为准:
- 屏幕首行:H(g0 同)
- 屏幕中间:M
- 屏幕尾行:L(g$ 同)
滚屏
滚屏严格来说不能算移动操作,毕竟光标位置是保持不变的,不过暂且先放这里吧。
- 行
- 上滚一行:Ctrl + y
- 下滚一行:Ctrl + e
- 半屏
- 上滚半屏:Ctrl + u
- 下滚半屏:Ctrl + d
- 整屏
- 上滚整屏:Ctrl + b
- 下滚整屏:Ctrl + f
搜索
搜索是一种更精细的操作,不是以固定的块为对象,而是以当前光标为指定字符之间的文本为对象。和搜索相关的动作有六个,分别是:
- 向右搜索:f
- 向左搜索:F
这两个很好理解,f
加上想要搜索的单个字符便可,另外两个功能类似,区别在于是停留在搜索结果的前一个字符上 t
和 T
。可能这就是大家觉的学习 Vi 曲线高的其中一个原因,相似动作太多了,多到完全可以就如何移动来写一本书(虽然大部分都是组合型的 😏)。
不过用的比较多的也就 f,而且写文章基本用不到,原因也很简单,看你能不能猜到。
最后两个动作和搜索动作的缺点有关,它只能移动到第一个匹配的字符。大家知道英文就 26 字母,一行之中相同的字母自然很多,这时候就需要我们的 ,
和 ;
出场了,他们的作用是重复上一次的搜索。嗯,分向前和向后重复。
也就是说,当前用 fx
向前搜索的时候,这时候如果按 ;
便成了向前搜索。(你它喵的不是玩我么)
你以为这样就结束了吗。不,还没有,还有最后三个动作。(不是说好就 6 个动作吗)
分别是:
- 匹配括号跳转:%
- 匹配光标下字符跳转:#(向左)*(向右)
这应该很好理解了,如果想动手试试的话,记得要在英文文本环境下测试,上面三个字符对中文是无效的。
编辑
花了一小时,终于把动作这块写完了,还好不需要全部列完,不然得写到明年(开玩笑)。下面从简单(并不)的开始,也是用 vi 必须要会的。
插入
插入的姿势,额不对,这句划掉(插入的姿势)。插入的方式有很多种,具体有多少我也没数过,我尽量少说一点,就六个吧,可能会在补充一个。
- 光标前:i
- 光标后:a
- 行首:gl
- 行尾:A
- 向上插入一行:o(小写 o)
- 向下插入一行:O(大写 O)
怎么样,很简单吧。像移动中的跳到行首非空白字符上一样,插入也有一个插入命令对应 I
,大写的 i,作用是在行首非空白字符插入。
呀,名额已经用完了,怎么办。那只能把前面讲过的移动命令拿来复习一下,比如说 w
和 a
配合可以在下一个单词插入,e
和 a
配合可以在下一个单词词尾插入,自然 fxa
是在搜索结果后插入咯。
替换
文章写完后,如果发现了一个错误怎么办,难道也要进入编辑模式,然后改完再退出吗?No,No,年轻人,终究还是年轻人,伟大的 Vi 已经为你想好了一切:
- 替换光标下的字符:r
只要一个动作,里面可以把帐改成账,陆改成录。什么,想一次改多个,你做……。伟大的 vi 怎么会没考虑到这个简单的需求:
- 进入替换模式:R
进入替换模式之后,直到手痒按下 ESC 键才会退出,不然一直处于替换模式。
多说一点,两种替换模式对中文都是有效的,先按下 r
或 R
键,然后切换输入法输入就可以了。
合并
和并并来很简单的,一般就用一个动作,但这次复习时不但学到一个新动作,还领悟(明明也是学的)到一个骚操作。先来说说最常用的:
- 合并下一行:J
J
的作用是把下一行合并到当前这一样,两行之间会有一个空格。如果不想这个空格呢,就要用到这次新学的动作了:
- 合并下一行(不留空):gJ
效果同 J
一样,适合中文句子之间合并,两行之间不留空格。虽然解决了两行之间多出一个空格的问题,但是如果被合并的那一行(也就是第二行)行首自带空格也会保留下来。不过呢,现在写文章谁还在空两格啊。
好了,说完了这两个,下面讲讲领悟到偷学的骚操作:
- 合并段:gwip
这个操作会合并所有相邻的行,直到遇到空行。
粘贴
粘贴就简单了,就两个命令,小 p 和大 p:
- 粘贴在当前行下一行:p
- 粘贴在当前行上一行:P
除了这两个,其实还有另外两个类似的,不过一般很少用就不说了(主要是电脑快没电了)。
更改、复制、删除
之所以把这三个放一起说,因为你懂的原因之外,另外就他们的动作是一样的,只是操作符不同:
- 更改:c
- 复制:y
- 删除:d
有没有发现三个缩写连起来特别像某个词语的拼音简写。不扯,回来说,在操作符后面跟着移动动作,就回执行对应的操作,比如说,d
是删除,w
是移动一个单词,连起来就是 dw
删除一个单词,其他的也类似。有一点需要说明的是,当操作符重复时,会作用与整行:
- 更改行:cc
- 复制行:yy
- 删除行:dd
此外,更改操作符会自动进入编辑模式。
做个补充,删除单个字符有个更简单的动作 x
,按下即可删除光标下的字符。
最后
虽然已经限定了普通模式下的命令,但还有许多没写或是没写全,比如像缩进啦、大小在啦,还有撤销之类等等。什么,撤销,糟了。
- 撤销上一命令:u
- 撤销对当前行的所有操作:U
这两个命令混着用时千万要小心(最好不要),具体就不多说了,真没电了,明天得好好检查电脑具体原因。
最后的最后
写完后,感觉这篇笔记完全不是我以往的风格,也不知读起来如何。不准备更改了(除了错别字)等过一段时间回头看看(可能到时候会想删除)。
vi 的命令列举是没有止境的,不过我会把一些常用的命令放在我的 Life of Py 中,可以在参考中看到链接。
文章 Mate 显示的时间是 18 年的 8 月份,距现在已过去一年多,想到草稿中还躺着一篇年代更为久远的,有些伤感。
参考
- Vim Help
- Life of Py
- 图书
- 《学习 vi 和 Vim 编辑器》
- 《Vim 实用技巧》