Vim 简明教程
“Vim 是一个历史悠久的,具有很多命令的功能非常强大的文本编辑器,被称为
编辑器之神
。”
简介
Vim 是从 vi 发展出来的一个文本编辑器。其代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。和 Emacs 并列成为类 Unix 系统用户最喜欢的编辑器。两派使用者经常发起 “XXX 才是最好的编辑器” 之争。
Vim 的几种模式
Vim 最常用的有四个模式,分别是:
normal 模式
:在普通模式中,用户可以执行一般的编辑器命令,比如移动光标,删除文本等等。这也是 Vim 启动后的默认模式。insert 模式
:在这个模式中,大多数按键都会向文本缓冲中插入文本。大多数新用户希望文本编辑器编辑过程中一直保持这个模式。在插入模式中,可以按 ESC 键回到普通模式。visual 模式
:这个模式与普通模式比较相似。但是移动命令会扩大高亮的文本区域。高亮区域可以是字符、行或者是一块文本。当执行一个非移动命令时,命令会被执行到这块高亮的区域上。Vim 的 “文本对象” 也能和移动命令一样用在这个模式中。command 模式
:在命令行模式中可以输入会被解释成并执行的文本。例如执行命令(:
键),搜索(/
和 ?
键)或者过滤命令(!
键)。在命令执行之后,Vim 返回到命令行模式之前的模式,通常是普通模式。
此外还有一些衍生模式,包括:
操作符等待模式
:这个派生模式指普通模式中,执行一个操作符命令后 Vim 等待一个 “动作” 来完成这个命令。如 dw
中的 d
即为操作符插入普通模式
:这个模式是在插入模式下按下 Ctrl-o
键的时候进入。这个时候暂时进入普通模式,执行完一个命令之后,Vim 返回插入模式替换模式
:这是一个特殊的插入模式,在这个模式中可以做和插入模式一样的操作,但是每个输入的字符都会覆盖文本缓冲中已经存在的字符。在普通模式下按 R
键进入。
入门
Vim 自带一个交互式的基本教程,里面包括了最常用的命令和你应该学了解的最基础的知识,安装 vim 之后,只需要在终端输入:
1 | vimtutor |
运行命令后,会出现操作系统对应语言的教程文档,首先要做的就是要对这个基础文档中的所有命令进行练习,直到形成肌肉记忆,下面简单总结一下教程中使用到的命令。
进入和退出 Vim
输入命令 vim filename
,即为使用 vim 打开文件。由于这是一个新建文件,你会得到一个空的窗口。屏幕看起来会像下面这样:
+---------------------------------------+
|# |
|~ |
|~ |
|~ |
|~ |
|"file.txt" [New file] |
+---------------------------------------+
('#" 是当前光标的位置)
以波纹线 (~
) 开头的行表示该行在文件中不存在。换句话说,如果 Vim 打开的文件不能充满这个显示的屏幕,它就会显示以波纹线开头的行。在屏幕的底部,有一个消息行指示文件名为 file.txt 并且说明这是一个新建的文件。这行信息是临时的,新的信息可以覆盖它。
处于 normal
模式时 (按 :q
,即可退出 vim 编辑器,如果不想保存修改而退出,使用 :q!
命令。
处于 normal
模式时,输入命令 :wq
可以保存文件并退出 vim 编辑器,其中 :w
命令表示保存文件,也可以按下 ZZ
保存并退出文件。
移动光标
Vim 使用 hjkl
来控制光标的移动。
1 | h 的键位位于四个字母的最左边,每次按下光标就会向左移动 |
按下 G
键可以跳转到文件末尾,按下 gg
可以跳转到文件开头,也可以通过 : 行号
或者 行号 G
命令快速跳转到行号处。
| first line of a file ^
| text text text text |
| text text text text | gg
7G / :7 | text text text text |
| text text text text
| text text text text
V text text text text |
text text text text | G
text text text text |
last line of a file V
按下 ^
可以跳转到本行第一个不为空白字符处,按下 0
可以返回行首。按下 $
可以跳转到行尾。
^
<------------
.....This is a line with example text
<----------------- --------------->
0 $
(这里 "....." 表示空白字符)
按下 w
可以跳转到下一个单词词首, 3w
表示跳转 3 个单词。
This is a line with example text
--->-->->----------------->
w w w 3w
按下 b
可以跳转到上一个单词词首
This is a line with example text
<----<--<-<---------<---
b b b 2b b
按下 e
可以跳转到下一个单词词尾,按下 ge
可以跳转到上一个单词词尾。
This is a line with example text
<- <--- -----> ---->
ge ge e e
上面的 w, b, e, ge
会将标点符号也认为是一个单词,如果使用 W, B, E, gE
会以空白字符作为分隔符进行单词跳转,如下:
ge b w e
<- <- ---> --->
This is-a line, with special/separated/words (and some more).
<----- <----- --------------------> ----->
gE B W E
ge b w e
使用操作符 f
可以向后移动到一个指定的字符处,如 fx
向后查找到本行中的字符 x
。
例如,假定你在下行行首,而想移动到单词 human
的 h
那里。执行命令 fh
即可:
To err is human. To really foul up you need a computer.
---------->--------------->
fh fy
这个例子里同时演示 fy
命令移动到了 really
的词尾。
你可以在这个命令前面加计数前缀,所以,你可以用 3fl
命令移动到光标后第三个 l
处,即 foul
的 l
:
To err is human. To really foul up you need a computer.
--------------------->
3fl
F
命令用于向左查找:
To err is human. To really foul up you need a computer.
<---------------------
Fh
tx
命令与 fx
相似,但它会把光标移动到目标字符的前一个字符上。提示: t
表示 To
(到达)。这个命令的反向版本是 Tx
。
To err is human. To really foul up you need a computer.
<------------ ------------->
Th tn
移动光标的命令是 Vim 中最为基础的命令,但是他和我们平常使用的上下左右键有较大的区别,所以需要进行大量的练习让他成为你理所当然的操作习惯。
推荐一款游戏用来练习 Vim 的基础命令:
PacVim
通过这个游戏,可以快速的上手和熟练 vim 的基本操作,值得一试。
相对屏幕移动
通过 Ctrl-f
向下翻页,Ctrl-b
向上翻页, Ctrl-u
向下滚动半屏(即把当前行上半屏的行置于当前行), Ctrl-d
向上滚动半屏(即把当前行下半屏的行置于当前行), Ctrl-e
逐行下滚,Ctrl-y
逐行上滚。这在几乎所有 Unix 软件中都是可以使用的,比如 man 和 less。
+----------------+
| some text |
| some text |
原文本 | some text |
+---------------+ | some text |
| some text | CTRL-U --> | |
| | | 123456 |
| 123456 | +----------------+
| 7890 |
| | +----------------+
| example | CTRL-D --> | 7890 |
+---------------+ | |
| example |
| example |
| example |
| example |
+----------------+
H
可以移动到屏幕的首行,L
到屏幕尾行,M
到屏幕中间。
+---------------------------+
H --> | text sample text |
| sample text |
| text sample text |
| sample text |
M --> | text sample text |
| sample text |
| text sample text |
| sample text |
L --> | text sample text |
+---------------------------+
zt
可以置顶当前行,通常用来查看完整的下文,比如函数、类的定义。 zz
将当前行移到屏幕中部,zb
移到底部。
+------------------+ +------------------+
| some text | zt --> | line with cursor |
| some text | | some text |
| some text | | some text |
| some text | | some text |
| some text | | some text |
| some text | | some text |
| line with cursor | | some text |
| some text | | some text |
+------------------+ +------------------+
+------------------+ +------------------+
| some text | | some text |
| some text | | some text |
| some text | | some text |
| some text | zz --> | line with cursor |
| some text | | some text |
| some text | | some text |
| line with cursor | | some text |
| some text | | some text |
+------------------+ +------------------+
+------------------+ +------------------+
| some text | | some text |
| some text | | some text |
| some text | | some text |
| some text | | some text |
| some text | | some text |
| some text | | some text |
| line with cursor | | some text |
| some text | zb --> | line with cursor |
+------------------+ +------------------+
文本编辑
插入文本
在 normal 模式下,按下 i
键可以在光标所在处进入 insert 模式,按下 I
键会直接在行首进入 insert 模式。
在 normal 模式下,按下 a
键可以在光标所在处之后进入 insert 模式,按下 A
键会直接在行尾进入 insert 模式。
在 normal 模式下,按下 o
键可以在光标所在行之后插入空行,按下 O
键则是在光标所在行之前插入空行,两个命令都会进入 insert 模式。
如果进入了 insert 模式,Vim 会在窗口的底部显示 --INSERT--
(中文模式显示的是 -- 插入 --
),这表示你在插入模式。
+---------------------------------------+
|A very intelligent turtle |
|Found programming UNIX a hurdle |
|~ |
|~ |
|-- INSERT -- |
+---------------------------------------+
删除文本
在 normal 模式下,可以使用 x
键删除光标坐在位置的字符。
在 normal 模式下,可以使用 dw
命令删除至一个单词的末尾,其中 d
是一个 操作符
,可以和其他 动作
命令进行组合,使用删除操作符 d
的命令格式如下:
1 | d motion |
如 dd
是删除一行,db
是往前删除至单词开头,d$
是删除至行末等。
替换文本
在 normal 模式下,按下 r
键可以进入替换状态,可以输入任意字符替换光标所在的字符,替换后即会退出替换状态,如果想保持替换状态,可以使用 R
命令,即可进入替换模式,你输入的字符会依次替换光标所在的字符,直到你按
+---------------------------------------+
|A very intelligent turtle |
|Found programming UNIX a hurdle |
|~ |
|~ |
|-- REPLACE -- |
+---------------------------------------+
更改文本
使用操作符 c
可以实现更改文本,实现的功能相当于删除并进入 insert 模式,例如 cw
命令表示删除一个单词并进入 insert 模式,c$
命令表示删除至行尾并进入 insert 模式, cc
表示修改一整行,但是会保留这一行的缩进。
To err is human
------->
c2w
To human
复制和粘贴文本
使用操作符 y
可以复制文本,例如 yy
可以复制一行的文本,yw
可以复制一个单词,使用 visual 模式选中文本后按 y
可以复制选中文本。
除了复制的文本外,Vim 的删除操作也会将删除的文本存入一个寄存器中,使用 p
命令可以在光标之后插入寄存器中的内容,使用 P
命令可以在光标之前插入寄存器中的内容。
let sqr = LongVariable *
-------------->
y2w
let sqr = LongVariable *
p
let sqr = LongVariable * LongVariable
保存文件
之前说到使用 :w
命令可以保存文件,默认存储的文件名为打开文件的文件名,如果需要另存为的话,只需要在命令后加上另存为的文件名即可,如 :w filename
便可将文件另存为为 filename
。
除了保存整个文件之外,vim 还支持部分文本的保存,按下 v
进入 visual 模式,移动光标选中想要部分保存的内容,输入 :
字符,可以看到屏幕底部会出现 :'<,'>
,输入命令 w filename
,命令变为 :'<,'>w filename
即可把选中的内容保存到 filename
文件中。
提取和合并文件
和 :w
命令相对应的,:r
命令是从文件中读取文本,输入命令 :r filename
,将会读取文件 filename
中的所有内容,并将其插入到光标所在位置处。
使用计数指定动作
在 normal 模式下,输入 4h
使光标向前移动 4 个位置,输入 2w
使光标向后移动两个单词。
在 normal 模式下,输入 d2w
向后删除两个单词,输入 2dw
先后删除两个单词,这两个命令的区别是,前者是执行一次删除两个单词的命令,后者是执行两次删除一个单词的命令。
撤销类命令
在 normal 模式下,输入 u
可以撤销上一条命令,输入 U
可以恢复一行的原始状态,输入 Ctrl-r
可以重做撤销的命令。
定位文件状态
在 normal 模式下,按下 Ctrl-g
会显示当前编辑文件中当前光标所在行位置以及文件的状态信息。
搜索类命令
在 normal 模式下,输入 /
加上搜索字符串可以在当前文件中查找该字符串,查找后,按下 n
键可以跳转到下一个搜索字符处,按下 N
可以跳转到上一个搜索字符处。如果想使用逆向查找命令,可以使用 ?
和搜索字符串进行查找。
要回到之前的位置,可以按下 Ctrl-o
,重复按可以回到更多步,而按下 Ctrl-i
可以跳到更新的位置。
当光标处于 {[()]}
任意一个括号字符上时,按下 %
可以快速查找并跳转到匹配的括号位置。
%
<----->
if (a == (b * c) / d)
<---------------->
%
当光标不在一个括号字符上,%
会先正向查找找到一个。比如当光标停留在上例中的行首时,%
会正向查找到第一个 )
。再按一次会移动到它的匹配处。
if (a == (b * c) / d)
-------------------->
%
替换类命令
在 normal 模式下,输入命令 :s/old/new/g
,可以将文件中所有的 old
字符串替换为 new
。
只替换单行的字符串可以使用命令 :s/old/new
。
要替换多行字符串可以使用命令 :#,#s/old/new/g
,其中 #
表示行号,如 :4,8s/old/new/g
表示将 4 到 8 行的 old
替换为 new
。
如果要进行有提示的替换,可以使用命令 :s/old/new/gc
,每次替换都会进行是否替换的询问。
执行外部命令
在编辑过程中,同样可以执行 shell 命令,只需要输入 :! command
即可运行外部的 shell 命令,命令执行后会回到 vim 中。
** 上面的所有命令都是使用 vim 需要学习的基础命令,只有把基础命令都联系到滚瓜烂熟,肌肉记忆的程度,才能够真正的感受到使用 vim 的便捷之处,加油!**
进阶
选项配置
Vim 可以进行预先配置启动项,从而增加插件以增强 Vim 的功能, 要配置 Vim,需要使用 vimrc
文件。
vimrc 文件
如果已经有 vimrc
文件了,可以直接在 vim 中输入命令 :edit $MYVIMRC
来进行编辑。
如果还没有 vimrc
文件,可以在用户目录创建该文件,即 ~/.vimrc
,如果想 vim 启动时显示行号,可以在 vimrc
文件中加上:
1 | set number |
重启 vim 后即可生效。
下面简单介绍一些常用设置:
1 | syntax on " 设置语法高亮 |
更多配置可以使用这个 Vim 配置工具 来模拟。
也可以参考多人推荐的 spf13-vim 来学习他人的配置。
添加插件
Vim 可以通过插件增强功能,把插件放入 Vim 的 plugin
目录中即可使插件生效。
如果没有 plugin
目录,可以使用命令 mkdir -p ~/.vim/plugin
创建。
Vim 中共有两种插件:
- 全局插件: 用于所有类型的文件
- 文件类型插件:仅用于特定类型的文件
当然,这种拷贝插件的方式比较麻烦,所以插件管理器也应运而生,最常用的是 Vundle 管理器。
网上关于插件安装的文章数不胜数,就不在此赘述了。
在 VimAwesome 可以找到大家常用的插件。
编辑多个文件
编辑另一个文件
输入命令 :edit foo.txt
可以关闭当前文件并打开 foo.txt
,如果当前文件未保存,则会提示错误信息。或者可以使用 :edit! foo.txt
命令放弃当前文件的修改并打开 foo.txt
文件。
文件列表
可以在启动 vim 时指定打开多个文件。例如:
1 | vim test test1 test2 |
这样会打开三个文件,可以使用命令在这三个文件中进行跳转:
1 | # 跳转到下一个文件 |
上面的两条命令默认也会保存当前文件,然后进行跳转。
但是这样的方式不利于我们对多个编辑的文件进行管理,所以使用标签的方法打开多个文件是一个更好的方式,将在后面进行相应的讲解。
分割窗口
水平分割
分割新窗口最简单的命令如下:
1 | # 水平分割窗口 |
这个命令把屏幕分解成两个窗口并把光标置于上面的窗口中:
+----------------------------------+
|/* file one */ |
|~ |
|~ |
one===============================
|/* file one */ |
|~ |
one===============================
| |
+----------------------------------+
这两个窗口允许你同时显示一个文件的两个部分。例如,你可以让上面的窗口显示变量定义而下面的窗口显示使用这些变量的代码。
Ctrl-w w
命令可以用于在窗口间跳转。如果你在上面的窗口,它会跳转到下面的窗口,如果你在下面的窗口,它会跳转到上面的窗口。(Ctrl-w Ctrl-w
可以完成相同的功能,是为了避免你有时按第二次的时候没有松开 Ctrl
按键。) 类似的,也可以使用 Ctrl-w j
跳转到下面窗口,使用 Ctrl-k
跳转到上面窗口。
使用 :close
或 :clo
命令可以关闭光标所在的窗口,并且只剩一个窗口的时候不会退出 vim。
当然,还可以利用分割窗口打开新的文件:
1 | :split two |
如果你正在编辑文件 one,则命令执行的结果为:
+----------------------------------+
|/* file two */ |
|~ |
|~ |
two===============================
|/* file one */ |
|~ |
one===============================
| |
+----------------------------------+
如果想新建一个窗口用于编辑一个新文件,可以使用 :new
命令。
调整窗口大小
在分割了窗口之后,可以发现默认是所有窗口平分屏幕,即分割三个窗口,则每个窗口是屏幕的三分之一大小。对于已经打开的窗口,我们可以使用命令来控制窗口的大小:
1 | Ctrl-w + |
不过这几种方法按键较多,可能并不能快速达到想要的窗口大小,在这种情况下,直接使用鼠标进行拖动可以更快的调整窗口大小。具体方法是使用鼠标点按住状态条进行拖动。
垂直分割
类似水平分割,垂直分割的命令为:
1 | :vsplit 或 :vsp |
这个命令可以做到垂直分割窗口,效果如下:
+--------------------------------------+
|/* file two */ |/* file one */ |
|~ |~ |
|~ |~ |
|~ |~ |
two ===============one =============
| |
+--------------------------------------+
如果既水平分割了窗口,又垂直分割了窗口,我们便需要在各个窗口之间进行移动,之前提到过的 Ctrl-w w
命令只能够向下一个窗口进行移动,不够方便高效。 Vim 提供了一下几种命令在窗口之间进行跳转:
1 | Ctrl-w h # 跳转到左边的窗口 |
标签页
经过上面的联系,我们可以发现,无论分割窗口多少次,各个窗口之间都是相互独立的,不会发生重叠,这样会导致窗口过多时,屏幕空间不足以显示文件内容。为了解决这个问题,我们可以使用标签页。
假如正在编辑文件 thisfile
,使用以下命令可以创建一个新的标签页:
1 | thatfile |
命令运行效果如下:
+----------------------------------+
| thisfile | /thatfile/ __________X| (thatfile 用加粗字体出现或高亮选中)
|/* thatfile */ |
|that |
|that |
|~ |
|~ |
|~ |
| |
+----------------------------------+
窗口顶端的横向文件名表示了已经打开的标签页和其中的文件名。
想要在标签之间进行切换,可以使用以下命令:
1 | :gt # 切换到下一个标签页 |
本文仅仅是对 Vim 这一款强大软件的基本介绍,想要真正的发挥 Vim 的强大之处,还需要不断地学习和不断地练习,希望大家都能够成为 Vim 大神。
参考
1、newjueqi,Vim 的几种模式介绍
2、vimtutor
3、yianwillis,Vim 中文文档计划