第 12 章 VIM 编辑器实战
Part 3 · 文本与编辑
引子
你在终端里需要改一个配置文件。也许是改一行 IP 地址,也许是改一行编译选项。
你输入 vim config.txt,屏幕上出现了一片内容——然后你按方向键,屏幕上开始输出字母;你按退格键,什么都没删掉;你试着输入文字,终端滴一声报错。
这是无数人的 Vim 初体验:进去了,出不来了。
Vim 的设计哲学和现代编辑器完全相反——它不追求「打开就能用」,它追求「熟练之后效率碾压一切」。
从「进不去出不来」到「不想再用别的编辑器」,中间有一条路。这章带你走完它。
背景与动机
有一件事你可能还没遇到过,但迟早会:你通过 SSH 远程连接到一块嵌入式开发板,板子上没有图形界面,没有桌面,连鼠标都不存在。这时候你需要改一行启动参数,或者编辑一个网络配置文件。
你能用什么?
Gedit?没有桌面环境。Notepad++?那是 Windows 的。VSCode?开发板的内存连它的启动画面都加载不了。
你需要的是一个能在纯终端里工作的编辑器。
Linux 世界里,能完成这个任务的主流选择有三个:nano、vim 和 emacs。nano 最简单,打开就能用,但功能有限——处理几百行的配置文件时,没有语法高亮和快速跳转会让你非常难受。emacs 功能最强大,但学习曲线甚至比 Vim 还陡。而 vim——几乎所有 Linux 发行版都预装它(或者至少预装它的精简版 vi),从 Ubuntu 桌面到最小的嵌入式 BusyBox 环境,你总能在某个角落找到它。
学会 Vim 不是为了炫技。它是你在没有图形界面的环境里,唯一可靠的文本操作手段。
一个现实场景:在 imx-forge 项目中,你会频繁通过串口或 SSH 连接到 i.MX 开发板,修改 U-Boot 环境变量、编辑设备树源文件、调整内核启动参数——这些全在终端里完成。到时候,Vim 就是你唯一的武器。
概念层
模式:Vim 的灵魂
这一节表面上在讲「怎么用 Vim」,但真正的问题是:为什么 Vim 的按键逻辑和所有现代编辑器都不一样?
答案是一个词:模式(mode)。
在记事本或 VSCode 里,你按 a,屏幕上就出现字母 a。输入即所见。Vim 不是这样。在 Vim 里,同一个按键在不同时刻有完全不同的含义——取决于你当前处于哪种模式。
类比 1/3 —— 赛车的挡位
你可以把 Vim 想象成一辆手动挡赛车。同一脚油门踩下去,挂一挡和挂五挡,效果完全不同。不是油门变了,而是挡位决定了油门的含义。
Vim 的模式就是挡位:
- 普通模式(Normal mode):空挡滑行。你踩油门(敲键盘)不会让车加速(不会输入文字),但你可以打方向、调后视镜、观察路况——在 Vim 里,这些操作叫移动光标、删除行、复制粘贴。
- 插入模式(Insert mode):挂挡踩油门。你按
a,屏幕上出现字母a。这才是真正「打字」的地方。- 命令行模式(Command-line mode):设置导航。你停下车,在导航仪上输入目的地——在 Vim 里,这是保存文件、退出、搜索替换等全局操作。
Vim 启动后默认进入普通模式。这就解释了引子里那一幕:你打开文件,开始打字——但 Vim 认为你在下达命令,不是在输入文字。所以按键变成了乱七八糟的操作,终端还会对无效操作发出警告音。
三种模式之间的切换路径:
普通模式 ──(i / a / o 等)──► 插入模式
普通模式 ◄──(ESC)──────────── 插入模式
普通模式 ──(: / ?)──────► 命令行模式
普通模式 ◄──(ESC / 回车)──── 命令行模式所有切换都经过普通模式。普通模式是枢纽,插入模式和命令行模式是分支——你不会直接从插入模式跳到命令行模式,必须先回普通模式再转。
类比 2/3 —— 揭示距离
赛车的类比到这里需要修正。手动挡换挡是为了适应不同速度——一挡起步,五挡巡航。但 Vim 切换模式不是为了「快慢」,而是为了分离操作类型。
真实的 Vim 设计逻辑是:你编辑文件时,大部分时间不应该花在打字上——你花更多时间在阅读、导航、调整结构。所以默认模式不是「输入」,而是「操作」。只有当你真正要打字时,才切换到插入模式。
这个反直觉的设计决策,正是 Vim 高效的根源。新手觉得 Vim 麻烦——「打个字都要先按
i?」;老手觉得其他编辑器才麻烦——「我只想删一行,为什么要点三下鼠标?」。这个认知反转,就是理解 Vim 的关键门槛。
关于模式的数量,有一个需要澄清的细节:Vim 官方定义了七种基本模式(Normal、Visual、Select、Insert、Command-line、Ex、Terminal-Job)和七种附加模式。这些模式里,Ex 模式几乎不会用到,Terminal-Job 模式只在终端窗口内使用。日常开发中,掌握普通模式、插入模式、命令行模式这三种就能覆盖 95% 的操作。Visual 模式(用于选择文本块)我们会在实践层中补充。
实践层
4.1 安装与第一次点火
Ubuntu 22.04/24.04 默认预装了 vim.tiny——一个精简版 Vim。它能用,但很多功能被裁掉了(语法高亮、撤销历史、插件支持等)。先用完整版学习:
$ sudo apt install vim
# 安装完成后验证版本
$ vim --version | head -3
# 预期输出(版本号可能略有不同)
VIM - Vi IMproved 9.1 (2024 Jan 02, compiled Jun 02 2026 22:00:15)
Included patches: 1-16, 647, 678, 697
Modified by team+vim@tracker.debian.org装好之后,创建一个练习目录和测试文件:
$ mkdir -p ~/vim-lab
$ cd ~/vim-lab
$ vim hello.txt回车之后你看到的界面:一个几乎全空的屏幕,光标在左上角闪烁,左侧有波浪线 ~ 标记空行,底部有一行状态信息。
现在——不要动。观察一下你面前的屏幕。
这就是普通模式。Vim 在等你下达命令,不是等你打字。
4.2 第一次打字与保存退出
在普通模式下按 i 键。
看屏幕底部——如果出现了 -- INSERT -- 或 -- 插入 --,恭喜,你已经切换到插入模式了。
现在你可以正常打字:
Hello, Vim!
This is my first file edited with Vim.
Vim is powerful.打完之后,按 ESC 键。底部的 -- INSERT -- 消失。你回到了普通模式。
保存并退出——在普通模式下,输入 :wq 然后按回车:
:wq
# Vim 保存文件并退出,你回到终端提示符:wq 是三个东西拼在一起的:: 进入命令行模式,w 代表写入(write),q 代表退出(quit)。
验证文件内容:
$ cat hello.txt
# 预期输出
Hello, Vim!
This is my first file edited with Vim.
Vim is powerful.如果你把文件改得一塌糊涂想重来,可以用 :q!——强制退出不保存。这个命令是新手的好朋友,记下来:
:q! # 强制退出,丢弃所有修改
:wq # 保存并退出
:w # 只保存,不退出⚠️ 踩坑预警:Ctrl+S 综合征
你可能习惯性地想按
Ctrl+S保存。千万别按。 在 Linux 终端里,Ctrl+S不是保存,而是发送 XOFF 信号——它会冻结你的终端。一旦按下,终端看起来像死了一样,什么按键都没反应。解冻方法:按
Ctrl+Q(发送 XON 信号),终端立刻恢复。这件事坑了我无数次。后来我养成了一个习惯:在 Vim 里保存永远用
:w,不用任何快捷键。
4.3 普通模式——导航与手术刀
普通模式是 Vim 的主战场。你在这里做两件事:移动光标和操作文本。
重新打开刚才的文件:
$ vim hello.txt基本移动——用 h j k l:
| 按键 | 方向 | 记忆方式 |
|---|---|---|
h | ← | 最左边的键 → 左移 |
j | ↓ | j 的尾巴朝下 → 下移 |
k | ↑ | k 的竖笔朝上 → 上移 |
l | → | 最右边的键 → 右移 |
现代 Vim 也支持方向键,但 hjkl 的意义在于:你的右手不需要离开主键盘区。当你编辑几百行的配置文件时,这种效率差距是实实在在的。
进阶移动:
# 行内跳转
0 # 跳到行首(数字零)
$ # 跳到行尾
^ # 跳到行首第一个非空字符
# 文件级跳转
gg # 跳到文件第一行
G # 跳到文件最后一行
5G # 跳到第 5 行
# 翻页
Ctrl+f # 向下翻一页(Forward)
Ctrl+b # 向上翻一页(Backward)这里有一个重要的认知模型:Vim 把文本操作设计成了「动词 + 名词」的结构。你告诉 Vim 做什么(动词),以及对什么范围做(名词)。这不是随意的快捷键堆砌——它是一套语言。
删除操作:
x # 删除光标处的单个字符
dd # 删除(剪切)整行
3dd # 删除从当前行开始的 3 行
dw # 删除从光标到下一个单词开头的部分
d$ # 删除从光标到行尾的内容dd 不是真的「删除」——它是「剪切」。被 dd 掉的内容存在 Vim 的寄存器(register)里,可以随时用 p 粘贴回来。
复制与粘贴:
yy # 复制(yank)整行
3yy # 复制从当前行开始的 3 行
p # 在光标后粘贴
P # 在光标前粘贴(大写 P)撤销与重做:
u # 撤销上一步操作
Ctrl+r # 重做(redo,撤销的撤销)来实战一下。打开 hello.txt,光标移到第三行:
$ vim hello.txt
# 1. 按 dd —— 第三行消失了
# 2. 按 p —— 它又出现在了当前行之后
# 3. 按 u —— 撤销,文件恢复原样这三步让你体验了 Vim 最核心的操作循环:操作 → 粘贴 → 撤销。一旦这个循环刻进肌肉记忆,你会发现编辑文本的速度有了质的提升。
类比 3/3 —— 回到那辆赛车
现在你应该明白了:普通模式不是「什么都不能做的空挡」——它是你可以操纵整辆车的驾驶舱。
dd是方向盘一样干脆利落的操控,yy是抄起一份地图揣兜里,p是把地图摊开在面前。插入模式?那只是你偶尔停下车来装货的地方。老司机大部分时间都在驾驶舱里,而不是货厢。
4.4 搜索与替换
搜索——在普通模式下按 /:
/Vim
# 按回车,光标跳到第一个匹配处
# 按 n 跳到下一个匹配
# 按 N 跳到上一个匹配Vim 会高亮所有匹配的文本。如果高亮太刺眼,按 :noh(no highlight)可以临时关闭。
替换——在命令行模式下使用 :s(substitute):
# 替换当前行第一个匹配
:s/old/new/
# 替换当前行所有匹配
:s/old/new/g
# 替换整个文件所有匹配
:%s/old/new/g
# 替换整个文件所有匹配,逐个确认
:%s/old/new/gc
# Vim 会逐个高亮匹配,问你 y(替换)/ n(跳过)/ q(退出)实战——把 hello.txt 里的 Vim 全部替换成 VIM:
$ vim hello.txt
# 进入普通模式后输入:
:%s/Vim/VIM/g
# 预期:所有 "Vim" 被替换为 "VIM"
# 底部显示替换数量,例如:3 substitutions on 2 lines搜索和替换在处理配置文件时极为常用。比如你接手一块开发板,需要把所有旧 IP 地址 192.168.1.100 改成新的 192.168.1.200——一条 :%s 命令就搞定了。
4.5 可视模式——选择文本块
之前所有操作都是「告诉 Vim 范围,Vim 自己选中」。但有时候你想自己选一块文本再操作——这就是可视模式(Visual mode)。
v # 字符可视模式(按字符选择)
V # 行可视模式(按行选择)
Ctrl+v # 块可视模式(按矩形列选择)进入可视模式后,用 hjkl 或方向键移动光标,选中的文本会高亮。然后你可以对选中内容执行操作:d 删除、y 复制、: 进入命令行模式执行替换等。
块可视模式(Ctrl+v)在批量注释代码时特别实用:选中一列,按 I(大写 i)输入注释符,然后按两次 ESC,选中的每一行都会被加上注释。
4.6 你的第一个 .vimrc
每次打开 Vim 都要手动配置?Vim 有一个启动配置文件:~/.vimrc。在这个文件里写的每一行,Vim 启动时都会自动执行。
先创建配置文件:
$ vim ~/.vimrc按 i 进入插入模式,输入以下内容:
" 显示行号
set number
" 开启语法高亮
syntax on
" 设置缩进为 4 个空格
set tabstop=4
set shiftwidth=4
set expandtab
" 搜索时忽略大小写
set ignorecase
" 但如果搜索词包含大写字母,则区分大小写(智能大小写)
set smartcase
" 搜索时实时高亮匹配
set hlsearch
" 增量搜索——边输入边匹配
set incsearch
" 高亮当前光标所在行
set cursorline
" 开启鼠标支持(可选——在终端里可以用鼠标滚轮翻页)
set mouse=a按 ESC 回到普通模式,:wq 保存退出。
然后用 Vim 打开任意文件试试。行号出来了,语法高亮有了,搜索也能实时匹配了——这些小小的配置会让你的 Vim 体验提升一个档次。
进阶提示:如果你日常在桌面环境下工作,VSCode 配合 Vim 插件(如 VSCodeVim)可以兼顾图形界面的舒适和 Vim 的键位效率。但记住,在 SSH 连接开发板的时候,你面对的只有裸 Vim——所以基本功不能丢。
练习题
走到这里,模式切换应该已经刻进肌肉记忆了——或者还没有,那就更需要练。
下面几道题难度递进,建议先不看提示独立做,卡住了再翻。
练习 12.1 ⭐(理解)
用 Vim 打开一个文件,不输入任何文字,直接退出。有哪些方法?如果文件被修改了但没有保存,直接 :q 会发生什么?
练习 12.2 ⭐⭐(应用)
创建一个文件 shopping.txt,输入 10 行任意内容。然后用 Vim 完成以下操作:
- 删除第 3 到第 5 行(共 3 行)
- 把删除的内容粘贴到文件末尾
- 把所有空格替换为下划线
_
提示:先跳到第 3 行(
3G),然后3dd删除 3 行,再跳到末尾(G)按p粘贴。替换用:%s/ /_/g。
练习 12.3 ⭐⭐⭐(思考)
为什么 Vim 的默认模式是普通模式而不是插入模式?这背后反映了一种什么样的编辑哲学?假设你来设计一个终端编辑器,你会采用同样的设计吗?为什么?
本章回响
这一章真正在建立的东西只有一个:模式这个概念。
它看起来只是 Vim 的操作方式——按 i 打字,按 ESC 停下来,按 :wq 走人。但「模式」背后是对编辑行为的重新分类:浏览和操作是两种完全不同的任务,不应该用同一套按键同时处理。这个分类让每个按键在最常用的模式下拥有了最优映射——普通模式下 dd 删一行,比任何 GUI 编辑器的「选中→右键→删除」都快,正是因为普通模式不需要顾虑「这个键是不是要输入字符」。
还记得开头那个场景吗——你打开 Vim,按方向键出现乱码,按退格没反应,终端滴一声报错,进去了出不来?现在你知道了:Vim 把你扔进普通模式,是因为它认为你会花更多时间在导航和操作上——而你的手指还停在记事本的思维模式里。这不是 Vim 的设计「反人类」,而是它做了一个诚实的假设:编辑不只是打字。理解了这一点,那些看似怪异的按键设计就都说得通了。
下一章我们会进入文本处理的领域——用 sed、awk、sort 等工具批量处理日志和配置文件。到时候你会发现,Vim 处理的是「手动编辑」,而那些工具处理的是「自动化编辑」。两者共享同一片土壤:文本。