2. vi/vim 编辑器

vi 是 Unix/Linux 系统中基于终端的最经典的文本编辑器,诞生于 1976 年(由 Bill Joy 开发)。

Vim(Vi IMproved)是 vi 的增强版, 于 1991 年发布(由 Bram Moolenaar 开发)。

Vim 完全兼容 vi 编辑器,在 vi 的基础上扩充了功能。

特点:

Ubuntu 24.04 没有预装 Vim 编辑器,需要使用 apt 命令安装,安装命令如下:

sudo apt install vim

vi/Vim 启动命令:

vi [文件名]
vim [文件名]

如:

weimingze@mzstudio:~$ vim hello.py

vi 编辑器界面如下:

vi 编辑器界面

左下角的 "hello.py" 是正在编辑的文件的名字。

文件名后的 2L,23B 是指你正在编辑的这个文件共 2 行,共 23 字节。

后面的 2,0-1 是指示当然光标所在的位置,

右下角的 全部 指当前向内容已经全部显示。

vi/Vim 编辑器的三种模式

刚进入 vi 时是在 命令模式 下,如图:

vi 编辑器的模式

命令模式 下,你的任何按键都是命令,不能输入内容。

我们先来学习如何退出 vi/Vim。

在命令模式下输入英文的冒号(:),这个冒号会出现在左下角的最后一行,此时进入末行模式:

print("hello world!")

~
~
~
:

此时输入 :q!回车 则不保存退出 vi。输入 :wq回车 则保存后退出 vi,如果在末行模式下 按下 ESC 键则回到命令模式。

重新进入 vi,我们再来说一下 编辑模式。在 命令模式 下,输入 iao中的任意一个按键则进入 编辑模式,在编辑模式下,你输入的任何按键都是文档的内容,当你编辑完成后需要按 ESC 键返回到 命令模式 才能进行保存退出。

尝试一下吧!至此你已经学会了 vi/Vim 的基本用法。

下面我们来学习他的高级用法。

进入编辑模式的命令

命令
说明
i
在当前光标处进入插入状态
I
将光标移动到当前行的行首,并进入插入状态
a
在当前光标后进入插入状态
A
将光标移动到当前行的行末,并进入插入状态
o
在当前行的下面插入新行,光标移动到新行的行首,进入插入状态
O
在当前行的上面插入新行,光标移动到新行的行首,进入插入状态
cw
删除当前光标到所在单词尾部的字符,并进入插入状态
c$
删除当前光标到行尾的字符,并进入插入状态
c^
命令删除当前光标之前(不包括光标上的字符)到行首的字符,并进入插入状态

进入插入状态后,左下角会显示 -- INSERT -- 提示,如:

print("hello world!")

~
~
-- INSERT --              1,22          All

在编辑模式下编辑 C 语言程序时,使用快捷键 Control + n 可以调出自动补全功能。这个是我用了很多年的功能,咱们可以试试。

我常用的末行命令

在命令模式下,输入英文的冒号就进入末行模式了。末行模式需要用回车键进行确认。按 ESC 则取消末行模式,返回到命令模式。以下是我用过的末行模式。

命令
说明
:w
保存当前编辑。
:w 文件路径名
另存为新文件。
:wq
保存修改后退出。
:q
退出vi(如果文档没有修改)。
:q!
不保存修改,强制退出。
:e 其他文件路径名
在当前编辑器打开其他文件。
:e! 其他文件路径名
在当前编辑器打开其他文件,放弃之前的修改。
:e#
回到上次打开的文件。
:r 其他文件路径名
读取文件内容到当前vi编辑器中。
:! 命令
执行命令并显示结果。回车键返回到 vi。
:r! 命令
执行命令并将结果添加到当前vi编辑器中。
:set nu
显示行号。
:set nonu
取消显示行号。
:数字
光标跳转到指定的行,如 :20 跳转到第 20 行。
:sp:sp 其他文件路径名
水平分割当前窗口,在命令模式下使用 Control + w + w 可以在窗口内切换光标。
:vs:vs 其他文件路径名
垂直分割当前窗口,同上,可以使用 Control + w + w 切换光标。

:sp:vs 可以将窗口无限细分,如果你的电脑屏幕足够大,那真是太爽了。

我就想起这么多,以后想起来的再补充。

下面我来说一下命令模式下的命令。

在任何模式下,只要按下 ESC 键就会回到命令模式。

命令模式下常用的命令

命令模式下光标相关的命令:

命令
说明
h左方向键(←)
向左移动光标
l右方向键(→)
向右移动光标
k上方向键(↑)
向上移动光标
j下方向键(↓)
向下移动光标
Control + fPage Up
向前翻整页
Control + bPage Down
向后翻整页
Control + u
向前翻半页
Control + d
向后翻半页
^Home
快速定位光标到行首
$End
快速定位光标到行尾
w
将光标快速跳转到当前光标所在位置的后一个单词的首字母
b
将光标快速跳转到当前光标所在位置的前一个单词的首字母
e
将光标快速跳转到当前光标所在位置的后一个单词的尾字母
gg1G
跳转到文件的首行
G
跳转到文件的末尾行

命令模式下删除、复制、粘贴相关的命令:

命令
说明
x
删除光标处的单个字符。
dd
删除光标所在行。
dw
删除当前字符到单词尾(包括空格)的所有字符。
de
删除当前字符到单词尾(不包括单词尾部的空格)的所有字符。
d$
删除当前字符到行尾的所有字符。
d^
删除当前字符到行首的所有字符。
J
删除光标所在行行尾的换行符,相当于合并当前行和下一行的内容。
yy
复制当前行整行的内容到vi缓冲区。
yw
复制当前光标到单词尾字符的内容到vi缓冲区。
y$
复制当前光标到行尾的内容到vi缓冲区。
y^
复制当前光标到行首的内容到vi缓冲区。
p
读取vi缓冲区中的内容,并粘贴到光标当前的位置(不覆盖文件已有的内容)。

删除命令删除的内容都会进入vi缓冲区,可以使用 p 命令进行粘贴。

命令模式下撤销/重做操作

命令
说明
u
取消最近一次的操作,并恢复操作结果可以多次使用u命令恢复已进行的多步操作。
U
取消对当前行进行的所有操作。
Control + r
对使用u命令撤销的操作进行恢复。

字符串查找操作

在命令模式下用 /? 进入末行模式进行查找。

命令
说明
/查找字符串
从上而下在文件中查找字符串"查找字符串"。
?查找字符串
从下而上在文件中查找字符串"查找字符串"。
n
定位下一个匹配的被查找字符串。
N
定位上一个匹配的被查找字符串。

字符串替换操作

在命令模式下用 : 进入末行模式进行查找。

命令
说明
:%s/old/new/gc
在整个文件范围内替换所有的字符串"old"为"new",提示:(y/n/a/q/l/^E/^Y)?y替换当前,n不替换(跳过),a替换所有,q退出替换。l替换当前匹配后退出,^E(Control+E)向下滚动屏幕,^Y(Control+Y)向上滚动屏幕。
以下供了解
我不常用
:s/old/new
将当前行中查找到的第一个字符"old" 串替换为"new"。
:s/old/new/g
将当前行中查找到的所有字符串"old" 替换为"new"。
:#,#s/old/new/g
在行号"#,#"范围内替换所有的字符串"old"为"new"。
:%s/old/new/g
在整个文件范围内替换所有的字符串"old"为"new"。
:s/old/new/c
在替换命令末尾加入c命令,将对每个替换动作提示用户进行确认。

块操作

Vim 在命令模式下使用 ^V(Control + V) 可以进行块操作。下面介绍一个我常用的块操作。在 Python 或 Shell 中都没有多行注释,我们要在每一行的行首插入井号(#)我们可以使用块操作组合键实现上述功能,方法是 Control + v 再用j/k上下移动方向键,在输入大写的I(shift + i),然后输入一个井号(#),再按下 ESC 结束输入回到命令模式。此时所有块光标前都多了一个井号。

使用 Control + V 进入块模式还可以剪切、复制和粘贴,挺方便的。

关于 vi/Vim 的操作远不止这些。如果你想了解更多,请使用 末行命令 :help 查看帮助。

关于 vi/Vim 编辑器的笔记我先记下到这里,虽然有很多常用的命令要记住,但他确实很强大,如何你是码农,你会爱上他。当使用 vi/Vim 时,你会发现你的手根本不用离开主键盘就可以快速完成一切任务,简直是码农必备之神器。

如果你想玩点 Linux/UNIX 下更高级的编辑器,请尝试 emacs。

练习:

#include <iostream>

using namespace std;

int main(int argc, char * argv[]) {
    cout << "hello world!" << endl;
    return 0;
}