Vi 是所有 Linux 系统都自带的命令行界面文本编辑器,而 Vim (Vi IMproved) 则是它的增强版。
本节列举 Vim 的基本功能,所有内容同时适用于 Vi 和 Vim。
Vim 有三种模式:
类型 | 功能 |
---|---|
COMMAND 模式 (默认) | 移动光标,删除或复制/粘贴字符或整行字符串 |
COMMAND-LINE 模式 | 搜索/替换字符串,读取/保存文件 |
INSERT 模式 | 移动光标,输入/删除字符 |
这几种模式通过以下方式来切换:
From | To | By |
---|---|---|
COMMAND | COMMAND-LINE | 输入 :/? 中的任意一个字符 |
COMMAND | INSERT | 输入 ioar 或 IOAR 中的任意一个字符 |
INSERT | COMMAND | 按下 [Esc] 键 |
COMMAND-LINE | COMMAND | 按下 [Esc] 键 |
在 Shell 中输入
vim name
以新建或打开名为 name
的文件。也可以不带文件名,直接进入 Vim。
文件打开后,默认进入 COMMAND 模式。按下 IOARioar
中的任意一个字母,进入 INSERT 模式。此时,可以像在其他文本编辑器中一样,对文件进行编辑。
编辑过程中或完成编辑后,如果需要保存当前修改,则按下 [Esc]
键回到 COMMAND 模式。然后再按下 :
进入 COMMAND-LINE 模式,在 :
后输入 w + [Enter]
,
完成编辑后,按下 [Esc]
键回到 COMMAND 模式。然后再按下 :
进入 COMMAND-LINE 模式,在 :
后输入 q + [Enter]
,
命令 | 功能 |
---|---|
H 或 8H | 向左移动 1 或 8 个字符 |
J 或 8J | 向下移动 1 或 8 个字符 |
J 或 8K | 向上移动 1 或 8 个字符 |
L 或 8L | 向右移动 1 或 8 个字符 |
8 + [Space] | 向右移动 8 个字符 |
8 + [Enter] | 向下移动 8 行 |
[Ctrl] + F | 向下移动一页,相当于 [PageDown] |
[Ctrl] + B | 向上移动一页,相当于 [PageUp] |
0 | 跳到光标所在行首,相当于 [Home] |
$ | 跳到光标所在行尾,相当于 [End] |
H | 跳到当前页面的第一行 |
L | 跳到当前页面的最后一行 |
G | 跳到当前文件的最后一行 |
8G | 跳到当前文件的第 8 行 |
gg | 跳到当前文件的第一行,相当于 1G |
命令 | 功能 |
---|---|
/word | 向后查找 word |
?word | 向前查找 word |
n | 重复前一次查找 |
N | 反向进行前一次查找 |
命令 | 功能 |
---|---|
:1,8s/old/new/g | 在 [1,8] 行之间,将 old 替换为 new |
:1,$s/old/new/g | 在全文中,将 old 替换为 new |
:1,$s/old/new/gc | 同上,替换前要求确认 |
删除光标所在行内的字符,其中 c
表示光标所在的列(从 1 开始):
命令 | 功能 |
---|---|
x | 删除 c ,相当于 [Del] |
8x | 删除 [c, c+8) ,相当于连按 8 次 [Del] |
X | 删除 c-1 ,相当于 [Backspace] |
8X | 删除 [c-8, c) ,相当于连按 8 次 [Backspace] |
d0 | 删除 [first, c) ,first 表示光标所在行的第 1 个字符 |
d$ | 删除 [c, last) ,last 表示换行符 |
删除整行,其中 r
表示表示光标所在的行(从 1 开始):
命令 | 功能 |
---|---|
dd | 删除 r |
8dd | 删除 [r, r+8) |
dG | 删除 [r, last] |
d1G | 删除 [first, r] |
d8G | 删除 [min(r,8), max(r,8)] |
以上各删除命令中的 d
替换为 y
则为对应的复制命令。
假设已经复制了 8 个字符或行,c
表示当前光标所在字符或行。
命令 | 功能 |
---|---|
p | 粘贴在 [c+1, c+8] ,原 c+1 顺延到 c+9 |
P | 粘贴在 [c, c+8) ,原 c 顺延到 c+8 |
J | 将光标所在行尾的换行符替换为空格 |
命令 | 功能 |
---|---|
U | 撤销前一个动作 |
[Ctrl] + R | 重做被撤销的动作 |
. | 重做前一个动作 |
命令 | 功能 |
---|---|
:w | write |
:w! | 强行 write |
:q | quit |
:q! | 强行 quit |
:wq | 先 write 再 quit |
ZZ | 若没有修改过,则相当于 :q ,否则相当于 :wq |
:w name | 将当前数据写入名为 name 的文件,类似于”另存为” |
:r name | 从名为 name 的文件读取数据,插入到光标所在行的下一行 |
:1,8 w name | 将 [1,8] 行的内容写入名为 name 的文件 |
:! cmd | 暂时离开 Vim,执行名为 cmd 的 Shell 命令 |
从 COMMAND 模式进入 INSERT 模式有以下 4 种方式:
命令 | 功能 |
---|---|
i | 从光标所在字符前开始插入 |
I | 从光标所在行的第一个非空白字符前开始插入 |
a | 从光标所在字符后开始插入 |
A | 从光标所在行的最后一个字符后开始插入 |
o | 在光标所在行后面插入新的一行 |
O | 在光标所在行前面插入新的一行 |
r | 将光标所在字符替换为随后输入的一个字符,然后回到 COMMAND 模式 |
R | 将光标所在字符逐个替换为随后输入的字符,直到按下 [Esc] 回到 COMMAND 模式 |
iIaAoO
进入 INSERT 模式后,左下角会出现 -- INSERT --
。R
进入 Replace 模式后,左下角会出现 -- REPLACE --
。如果已经进入 Vim,并且需要临时修改 Vim 设置,可以利用 :set
命令。这种方式只在当前 Vim 进程中有效。例如:
命令 | 功能 |
---|---|
:set all | 查看当前设置参数 |
:set | 显示非默认参数 |
:set number | 左侧显示行号 |
:set hlsearch | 高亮搜索 |
:set autoindent | 自动缩进 |
:set backup | 自动备份 |
:set ruler | 右下角显示光标位置 |
:set showmode | 左下角显示模式信息 |
:set backspace=0/1/2 | 2 表示可以删除任意字符,否则只能删除最近输入的字符 |
:set bg=dark/light | 暗色/亮色背景 |
:syntax on/off | 开启/关闭语法高亮 |
完整列表可以在 Vim 中通过以下命令查到:
:help option-list
Vim 的设置文件包括:
/etc/vimrc
。~/.vimrc
,优先级高于前者。具体语法与 COMMAND-LINE 模式中的命令一样。每一行代表一条命令,并且行首的 :
可以省略,行尾可以用双引号 "
开启注释。
如果有以下文件:
192.168.1.1 host1.school.edu
192.168.1.2 host2.school.edu
192.168.1.3 host3.school.edu
现在要将 host1
,host2
,host3
复制并粘贴到各行最后,即改为以下形式:
192.168.1.1 host1.school.edu host1
192.168.1.2 host2.school.edu host2
192.168.1.3 host3.school.edu host3
这种需求在 Vim 中可以很容易地实现。在 COMMAND 模式下:
命令 | 功能 |
---|---|
v | 选择字符,光标扫过的字符反色 |
V | 选择整行,光标扫过的整行反色 |
[Ctrl] + v | 选择区块,光标扫过的矩形区块反色 |
y | copy 选中的反色区域 |
d | delete 选中的反色区域 |
p | paste 选中的反色区域 |
在 Shell 中输入以下命令,可以打开多个文件:
vim file1 file2
用以下命令可以查看或切换 Vim 打开的文件:
命令 | 功能 |
---|---|
:files | 列出当前 Vim 打开的所有文件 |
:n | 编辑下一个文件 |
:N | 编辑上一个文件 |
典型的操作是:从 file1.txt
中复制一些内容,然后切换到 file2.txt
,将复制的内容粘贴到 file2.txt
中。
:q
或 :wq
命令的作用是退出当前 Vim 进程。因此,如果 Vim 打开了多个文件,那么所有文件都将被退出。
前面的多文件模式只会显示一个文件的内容,而这里的多窗口模式则会将窗口分割 (split) 为多块,用以同时显示一个或多个文件的内容。
命令 | 功能 |
---|---|
:sp | 在分出的窗口中打开当前文件 |
:sp filename | 在分出的窗口中新建或打开指定文件 |
先按住 [Ctrl]
,再按住 W
,再按第三个键,可以在不同窗口间切换:
组合键 | 功能 |
---|---|
[Ctrl] + W + J | 光标移到下一个窗口 |
[Ctrl] + W + K | 光标移到上一个窗口 |
[Ctrl] + W + Q | 关闭当前窗口 |
以上组合键可能会与其他快捷键冲突。
在 INSERT 模式中,按以下组合键执行搜索:
组合键 | 补全依据 |
---|---|
[Ctrl] + P | 向前 (Previous) 搜索 |
[Ctrl] + N | 向后 (Next) 搜索 |
如果只有一个匹配项,则自动执行补全; 如果有多个匹配项,则弹出候选列表,可以用方向键进行选择。
选项 | 功能 |
---|---|
:set ignorecase | 搜索时忽略大小写 |
:set infercase | 搜索时忽略大小写,提示时推测大小写 |
Vim 根据以下设置来确定关键词搜索范围:
:set complete=key,key,key
其中 key
可以为下表中的一个或多个(相互之间用 ,
隔开)选项:
选项 | 功能 |
---|---|
. | 当前文件 |
d | 当前文件及被其#include 的文件 |
i | 被当前文件#include 的文件 |
b | 被载入 buffer 中的文件 |
u | 未被载入 buffer 的文件 |
kfile | 名为file 的文件 |
k | 被dictionary 选项定义的文件 |
t | tags 文件 |
w | 其他窗口中的文件 |
其中#include
指定的搜索路径由 Vim 的path
选项决定。
如果有一些常用词需要经常输入,可以定义一组字典文件 /path/math.txt
,/path/physics.txt
,这样[Ctrl] + P/N
会在指定的字典文件中进行搜索。字典文件可以通过如下方式设定:
:set dictionary=/path/math.txt,/path/physics.txt
:set complete=k/path/math.txt,k/path/physics.txt
若要进行更为精细的搜索,则需要先按下组合键 [Ctrl] + X
,然后再按下下表中任意一个组合键:
组合键 | 搜索对象 |
---|---|
[Ctrl] + D | 当前文件及被其 #include 的文件中由 #define 定义的宏 |
[Ctrl] + F | 当前目录中的文件名 |
[Ctrl] + K | 字典文件中的词 |
[Ctrl] + I | 当前文件及被其 #include 的文件中的词 |
[Ctrl] + L | 整行 |
在 [Ctrl] + X
模式下,[Ctrl] + P/N
的功能类似于方向键。
一个标签 (tag) 代表一个 C 函数 原型 (prototype)。利用程序 ctags 可以生成一个标签列表,并保存到标签文件 tags
中。例如:
ctags *.c *.h
默认情况下,Vim 只显示函数名称。通过以下设置:
:set showfulltag
可以改为显示完整的函数原型。