转载自:https://www.jianshu.com/p/f1fc65a245e2,由于思否的表格看起来有点怪,大家可到原文地址查看此文章。
- 此文章虽然不是什么重要成果,但也是笔者的心血,如有转载,要有声明。
- 由于时间和水平有限,难免有错漏。如果发现问题,请及时联系笔者。
这里就不多介绍 vim 的强大了,直接开始。
工作流
下面我们以编辑文件,尤其是代码,通常会遇到的工作需求来介绍 vim 的使用,以及它是如何方便我们完成我们的编辑工作的。
1. 首先,打开文件
vim 打开文件只要在命令行输入
vim filename
就可以编辑文件啦。当然,如果文件不存在,会自动创建文件。
2. 输入
我们刚打开文件进入的界面是不能直接编辑文件的,因为我们处于 normal 模式下,而要输入的话,需要进入 insert 模式,才能进行编辑了。摁下 i
键,进入 insert 模式而当我们编辑完之后,摁下 esc
键,就可以回到 normal 模式了。
在这我们介绍一下 vim 的模式,主要有 3 种,normal mode/insert mode/visual mode。normal 模式是我们默认处在的模式,主要是我们输入命令,对文本进行操作的。而 insert 模式,这是像我们一般的编辑器一样,输入。
而且当我们进入 insert 模式后,做完一些操作,最好键入
esc
命令,回到 normal 模式,至于原因,我们后面会看到的
还有其他的命令,这里不多言了。
命令 | 作用 |
---|---|
o | 在下方新开一行,并进入 insert 模式 |
O | 在下方新开一行,并进入 insert 模式 |
a | 在光标后一个字符开始编辑 |
A | 在光标所在行行尾开始编辑 |
I | 在光标所在行开头开始编辑 |
3. 移动
vim 是不能用鼠标操作的(此处说的是原生版本),我们要移动光标的话,似乎只能用方向键了。但是方向键经常比较难摸到,就比较麻烦了。
所以,我们下面介绍一些更好的 vim 移动方式。
注意:移动部分的命令都是在 normal 模式输入。
-
j、k、h、l
命令 | 作用 |
---|---|
j | 光标向下移动一行 |
k | 光标向上移动一行 |
h | 光标向左移动一行 |
l | 光标向右移动一行 |
而且这几个键在我们右手的键位上,很方便就可以摁到。但是,h
和 l
不建议常用,因为移动效率太低了,每摁一下就移动一格。我们下面介绍更便捷的移动操作。
-
w、e、b
命令 | 作用 |
---|---|
w | 向后移动一个单词,从词头到词头 |
e | 向后移动一个单词,从词尾到词尾 |
b | 向前移动一个单词,从词头到词头 |
这种以单词为单位的移动,要比 hl 那种以一格为单位的移动快很多,而且有效率。而且 h / l 是无法跨行的,也就是当我们用摁 h 键,移动光标到行首时,光标是无法移动到上一行尾的,而 b 键可以。
-
Ctrl+d、Ctrl+u
上面讲的是单词的移动,但是如果在我们看文章或代码时,用的更多的是翻页,j
和 k
键每次只能移动一行,是无法满足我们的需求的。下面就讲到翻页了。
命令 | 作用 |
---|---|
Ctrl+d | 向下翻半页 |
Ctrl+u | 向上翻半页 |
而且是每次翻半页,不用担心一翻页,就不用担心找不到之前看到哪了。
-
gg、G
上下翻页固然很方便,但是我们经常看文档或写文档时,会想要跳回文章的开始部分。这个时候,如果文章很长,那么用翻页回去就太累了。vim 这么可以这么不方便呢,hhhh。所以,我们是有一个回到顶部按钮的,那就是gg
。而跳到文章尾部,则是G
。
4. 查找
把查找放在这里也许有点突兀,但查找也算另一种移动了。
查找分为行内查找和全文查找、项目级查找,其中项目级查找由于涉及到 vimscript 和 vim 插件,我们放到在下一篇教程来介绍。
行内查找
这里就要说到我们前面说到的 h
、l
键不能常用的原因。因为这样真的很影响效率。但是 w
、e
、b
键只能在单词两端移动,当我们们想要操作单词内部的字母时,就要用到 h
、l
,但是如果单词很长,就 ….. 很累。且如果句子比较长,那么我们的移动也是效率不高。
这里我们要介绍一个行内查找的命令 f{char}
,它的意思是,键入 f 后,紧接你要找的字母,它会在当前光标位置与当前行行尾之间查找指定的字符,找到之后,光标就会跳到那个字符上,如果没有找到,就不动。这意味着,我们我们近乎可以在一行之内,飞檐走壁,驰骋无阻。所以,f{char}
是 vim 中移动最快的方式之一。
但有些时候,一行中会有很多相同的字母,而当我要查找的字符在他们的行列中,那么可能在我们想要去到的地方之前就有一个相同的字符,那么光标就会在那停下。不过,Vim 会记录 上次执行过的 f{char}
命令,随后用 ;
命令就可以重复该命令,一直到我们想要到的地方。如果不小心,跳过头了,用 ,
命令就可以再跳回来。
只是吧,跳那么多次,累啊。所以,我们要尽量在行中挑出不常出现的字符。先跳到一个离我们想要去的地方最近的不常出现的字符,再以此为跳板,跳到目的地。
全文查找
我们经常会要在文章中或代码中查找某个字段。而一般的代码编辑器,是 Ctrl+F,而 vim 中则更为简单。当我们摁下“/”,会在 vim 底部出现一个“/”,然后我们直接键入我们想要找到的字段,如我们要找“const” , 我们直接在 normal 模式下,键入“/const”
那么,vim 就会把所有的“const”高亮,并把光标聚焦到离光标下方最近的“const”字段那里,方便我们进行操作。
然后我们要找下一个“const” 怎么办?摁下 n
就可以跳转到下一个,反过来 N
则是跳转到上一个。
还有,把光标移动到我们想要查找的单词上,输入 *
就可以全文查找了。
5. 复制粘贴
在这里我们先介绍一下 vim 的文本对象,这个很强大很强大的玩意。
好,看表(不要被它吓到,我们只是用来找找规律,不用记的,嘻嘻)
命令 | 意义 |
---|---|
iw | 当前单词 |
aw | 当前单词及一个空格 |
i) 或 ib | 圆括号 (parentheses) 内部 |
a) 或 ab | 一对圆括号(parentheses) |
i} 或 iB | 花括号 {braces} 内部 |
a} 或 aB | 一对花括号{braces}i} |
i] | 方括号 [brackets] 内部 |
a] | 一对方括号 [brackets] |
i> | 尖括号 <angle brackets> 内部 |
a> | 一对尖括号 <angle brackets> |
i’ | 单引号 ‘single quotes’ 内部 |
a’ | 一对单引号 ‘single quotes’ |
i” | 双引号 “double quotes” 内部 |
a” | 一对双引号 “double quotes” |
i` | 反引号 backticks 内部 |
a` | 一对反引号 backticks
|
it | XML 标签内部 |
at | 一对 XML 标签 <xml>tags</xml> |
好,大家发现了没有,i
就是选择内部,a
就是连带结对符(此处先把单词两旁的空格也当成结对符吧)。而我们要做的,就是 把光标移动到结对符或者其内部 ,想选哪个结对符包含的文本对象,就输入i
/a
+ 指定结对符。当 xml 标签是用t
代替了的,这个要记一下。
那我们选中文本对象当然是要对其进行操作,而且细心的同学就会发现,i
/a
命令不是进入 insert 模式的么?
所以,我们要在选文本之前,指定对文本对象进行的操作。也就是 {action}+i
/a
+ 指定结对符,记住这个就好啦。
下面介绍几种 action 命令。
命令 | 意义 |
---|---|
c | 替换 |
d | 删除 |
y | 复制 |
v | 选择高亮 |
这几个命令除了 v
因为是切换 normal /visual 模式(连续按 2 次只是从 normal 到 visual 又回到 normal,这个待会再讲)之外。其它的命令连续按 2 次(如 dd
),就是直接对光标所在行进行操作,而不用再选择文本对象了。
然后,我们通常会对多个单词进行操作,所以可以用 {action}+ 数量 +w
,对多个单词进行操作。那如果只对一个单词进行操作的话,就直接{action}+w
就可以了,相当于一种缩写吧。至于其它的文本对象,大家就先不要想缩写了,记住{action}+i
/a
+ 指定结对符,就好。
还有一些不接文本对象,但会配合上面的命令的命令
命令 | 意义 |
---|---|
x | 删除光标所在字符 |
s | 替换光标所在字符 |
p | 粘贴 |
u | 撤销操作 |
Ctrl+r | 重做 |
-
visual 模式
我们在平常用的编辑器中,复制或删除,一般是用鼠标选中指定的文本,然后操作。其实我们在 vim 中也是可以选中文本的,而且,我们将会看到,vim 提供的支持更加强大。
-
v
当我们在 normal 模式摁下v
,进入了 visual 模式,当我们开始移动光标时,会看到一些字符被阴影覆盖,这代表了我们选中的文本。此时我们就可以对我们选中的文本进行复制(y
)、删除(d
)、替换(c
)、粘贴操作(p
)。这个通常是我们通过文本对象难以选中我们想要操作的文本时用到的。
但是当我们在一行中的中间,摁下 v
,开始选择文本,当我开始移动光标,移动了一段距离之后,我忽然像要把开头的那个词前面的也选了,可是这时我的光标已经移动到别的地方了,噢,my god,怎么办?难道要取消选择么?
没事,输入 o
命令就可切换高亮选区的活动端。
这里我们注意到在 normal 模式下
o
命令是新建一行,并进入 insert 模式。而 visual 模式下,o
命令则是切换高亮选区的活动端
-
V
有些时候我们希望直接对行进行操作,那么用 V
来进入行选择模式。此时我们就可以行为单位进行选择。
-
ctrl+v
vim 更令人惊艳的是它可以对列进行操作。当我们把光标移动到我们想要选择列中,摁下Ctrl
+v
, 将光标上下左右移动,就可以选择列,进行操作。
6. 寄存器
好,vim 的复制相当的方便,但是它好像不能把文本复制到系统的粘贴板,让我们把一些东西从 vim 复制到浏览器。这样感觉好不方便啊。
但是,少年,这是错觉,其实 vim 是支持粘贴到系统的粘贴板的,只是这个涉及到 vim 的寄存器的选择。
不了解寄存器是什么的小伙伴可以把寄存器当成一个抽屉,就是可以装点东西,方便拿。
好,vim 有很多寄存器,一些是用来保存我们复制的内容的。
寄存器 | 简介 |
---|---|
“ | 无名寄存器,默认的粘贴板 |
“+ | X11 剪贴板,用剪切、复制与粘贴命令操作 |
所以我们要在复制和粘贴的时候,指定我们要用的寄存器,就可以实现我们的需求了。
复制时:”+y
粘贴时:”+p
注意:”+“号并不是代表前后两个键组合,而是本身我们要按下的键。
7. 重复操作的简化
减少重复操作是提升效率的关键。而 vim 就是提升效率的神器啊。让我们来看看它是怎么减少重复操作的。
“.”键:重复上一次的操作
操作的定义:通常而言,从 normal 模式到 insert 模式再到 normal 模式中,包含的动作为一次操作。
这个键非常重要,因为它可以帮我们实现很多东西。
比如, 我们要把光标上的 array 以及其他所有的 array 改为 a,我们就可以先输入 *
, 全文搜索 array 这个字符串,cw
替换当前词,并进入 insert 模式,然后,输入 a,再摁下 esc
回到 normal 模式。接下来就是不断地输入 n.
。n
转到下一个搜索结果,.
则是重复上次操作。
所以大家一定要养成习惯,尽量保持 vim 处于 normal 模式,要进行操作再进入其他模式。这个跟我们以前用的编辑器有所不同。但这个是值得的,这样不仅有利于进行重复操作,而且,其他模式基本上从 normal 模式进入的。
8. 宏
.
键虽然可以重复之前的操作,但是,它还是有限制的,比如我们只能用它重复一次从 normal 模式到 insert 模式再到 normal 模式中包含的动作,也就是一次操作。也就是说,它不能记录我们的移动操作(移动都是在 normal 模式下进行的),那么当我们想要记录伴随多次移动的操作的话,.
符号无能为力了。其次,如果我们要记录不同的操作,一遍交叉以不同的顺序复现的话,而 .
只能记录一个操作。
但是我们这里要介绍的 宏
,一种及其强大的命令,就可以实现我们上面的需求。
你可以把宏当成一个命令序列,我们把想要重复的命令操作录制下来,成为一个宏,放到一个寄存器中,后面再复现。
不了解寄存器是什么的小伙伴可以把寄存器当成一个抽屉,就是可以装点东西,方便拿。
q
键既是“录制”按钮,也是“停止”按钮。为了录制我们的按键操作,一开始 需要按 q{register}
,从而指定一个用于保存宏的寄存器(如 a)。当状态栏中出现“记录中”时,表示录制已经开始。此后,我们执行的每一条命令都将被宏捕获。当我们录制完成,按下 q
键停下。
用 @{register}
命令执行指定寄存器的内容,也可以用 @@
来重复最近调用过的宏,而且可以在前面加上数值代表重复的次数,如 22@@
。这样的话我们就不用像之前用.
命令一样,重复的时候由于 .
命令的限制,只能不断输入 n.
。但是.
操作的好处就是方便,不用特地录制宏。所以,我们平常一般用 .
来重复。而当重复的次数太多,或者 .
命令无法实现的重复操作的时候,才祭出 宏
这个大杀器。
9. 目录树
当我们已经打开了一个文件编辑窗口之后,又想要打开另一个文件,这是我们经擦会有的需求,尤其是写或者阅读项目代码时,文件跳转是常有的事情。
虽然 vim 有一些打开文件的方式,但是要么涉及到 vimscript,要么不方便。所以这里只介绍一个 vim 的内置插件,netrw。
它可以让我们像用其他的一些 IDE 一样,可以显示目录树。
执行 : edit .
或 : Explore
命令,就会在当前窗口显示目录树。你可以把这个目录树也当成是一个文件。之前我们所介绍的移动操作在这也适用。通常是用 k
、j
上下移动,选择我们想要的文件或者文件夹,摁下 Enter
键后,如果选中的是目录,则进入目录,是文件,则在当前窗口打开文件。
大家会注意到目录树和文件都是当前窗口打开的。在《practical vim》中,作者有一个有趣的比喻:我们可以把一个 vim 窗口当成一张牌,而文件和目录树是牌的正反面。我们之前所做的打开目录树和打开文件,只是在把牌翻过来,又翻回去。
只是我通常想要从牌堆中拿一张新的牌,与我原来的牌上下或水平排列。
这时我们只要执行 : Vexplore
和:Sexplore
命令就可以在当前窗口右方或下方新增一个窗口,并打开目录树。这是我们就可以很方便地打开新文件了
tips: 输入
: Vexplore
和:Sexplore
命令时,可以直接: V<Tab>
和: S<Tab>
我这里用新增窗口说的可能不太贴切,《practical vim》里是切分窗口。但是对于使用上而言,影响不大。
10. 命令行
vim 内也是可以调用 shell 的命令的。
比如输入 : !ls
,就可以看到在当前目录的文件及文件夹了。
其中重点在于 !
,它代表后面的命令,是 shell 命令,不是 vim 的命令,要用 shell 来运行。
其中,%
代表本文件,所以,当我在 vim 写完一个 python 程序,想要运行的时候就可以输入 :!python3 %
来运行我们的程序了,而不用先退出 vim,或新开一个终端窗口。
11. 退出
输入 :wq
即可退出。如果提示没有文件名,则输入 :wq filename
。w
代表保存文件,q
代表退出。所以,当你如果进入 vim 时,没有指定文件名时,vim 会在你退出保存时提示你加上一个文件名(上面那个 filename 只是代表文件名)。或者可以不保存,输入 :q!
强制退出。
后续
我们这里只介绍了一些基本使用,但这些以经可以让你正常的在 vim 里工作了。但是我们还有很多需求并没有解决。如
- 项目级查找
- 代码自动补全
- netrw 无法删除非空目录(这个大家可以尝试一下)
- 快速编辑结对符(或者说结对符自动补全)
- vim 中英文输入法流畅转换
- 代码折叠
- 环境恢复
- vim 中写 markdown
- vim 中写 LaTeX
- 语法高亮等美化
而这些将会在下一篇教程讲到哦,敬请期待,hhhh。