作为一个和 Vim 打了十多年交道的老用户,每次看到新手在终端里按了半天方向键光标纹丝不动、然后绝望地打出 :q! 的画面,我都觉得特别真实。因为我自己当年也是这样过来的——第一次打开 Vim,不知道要怎么保存,按什么都没反应,最后实在没辙,直接关掉了终端。Vim 不是一个“反人类”的编辑器,它只是把编辑流程拆成了普通人一开始不太适应的模态。Vim 源自上世纪 70 年代的 vi,到 1991 年加入可编程能力后演化为今天的 Vim,如今在云服务器、Git 提交信息、远程开发环境里,它依然是不可替代的主力工具。
这篇文章我不想写成命令大全式的手册,而是把从入门到熟练路上最关键的几道坎拆开讲清楚:先理解模态编辑到底在解决什么问题,再把高频命令练成肌肉记忆,接着掌握“动词 + 范围 + 对象”的组合打法,然后针对一次注释多行、全选复制、数字递增这类大家反复搜索的真实痛点,给出可以直接照抄的方案。适合刚打开 Vim 被劝退的纯新手,也适合已经会用基本命令但总觉得效率提不上来的进阶用户。
1. 先搞懂设计思想:模态编辑到底快在哪
1.1 新手的第一道坎:模式与键位
很多人第一次打开 Vim 后,第一反应是“怎么输入文字”,第二反应是“怎么退出”。这两个问题背后其实是同一个核心概念:Vim 不是一个所见即所得的输入框,它是一个“有状态”的编辑器。
Vim 里最常用到的模式有四类:
- 普通模式(Normal):启动后的默认状态,所有按键被解释为操作指令,比如
j是向下移动一行,x是删除光标下的字符。这个模式下你不是在输入文字,而是在编辑文字。 - 插入模式(Insert):输入文字的状态。按下
i、a、o等命令可以进入,此时 Vim 退化为一个普通输入框。 - 可视模式(Visual):选中文本的状态。
v是按字符选,V是按行选,Ctrl+v是按列选(可视块)。 - 命令行模式(Command-line):输入
:进入,用于保存、退出、搜索替换等操作。
理解这个状态机是入门的关键。传统记事本编辑器里,键盘的每一个按键要么是输入文字,要么是触发菜单,没有“中间态”。而 Vim 的设计哲学是:手指不离开键盘就能完成“移动、选中、修改、重复”的全部流程。
我自己带新人的时候,经常用一个遥控器类比:普通模式是遥控器的“待机状态”,此时数字键代表频道,方向键代表换台;插入模式是“打字机状态”,所有按键都变成输入内容。如果你一直按遥控器的数字键却停在待机状态,自然会觉得“怎么没反应”——不是编辑器坏了,是它正等着接收你的指令。
1.2 最难的是建立“退出条件反射”
新手高频问题永远是:怎么退出 Vim。
这里直接给出保存退出的对照表:
| 操作 | 按键/命令 | 说明 |
|---|---|---|
| 保存 | :w |
写入文件,不退出 |
| 退出 | :q |
没改过文件时直接退出 |
| 保存并退出 | :wq 或 ZZ |
ZZ 适合保存后直接关闭 |
| 强制退出 | :q! |
放弃所有修改,不保存退出 |
| 强制保存退出 | :wq! |
对只读文件也强制写入 |
这几个命令我在文章后面还会展开讲一次,因为仅靠列出来,你还是记不住。真正的入门标志不是“看完知道有这些命令”,而是它们变成肌肉记忆,手指比脑子快。
我自己早期的训练方法特别笨,但非常有效:每天开一个临时文件,反复执行“输入文字 — 按 Esc — :wq — 再打开 — 再修改 — 再退出”,练到闭着眼都不会把 :q! 和 :w 搞混为止。这个过程只需要大概一个下午,但能帮你省掉之后无数次误操作。
还有一个小细节:如果在终端里按 Esc 感觉没反应,十有八九是当前处于中文输入法状态。Vim 对模式切换非常敏锐,但中文输入法的全角/半角状态会影响按键识别,所以我在终端下常常把系统输入法默认锁定为英文,养成一个“进终端前先切换输入法”的习惯。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 高频命令:先背这二十条就够用了
2.1 移动是效率的地基
Vim 效率高的前提是“移动速度快”。如果你还是习惯用方向键一格一格挪,Vim 和普通编辑器的差别就打不出来。
第一优先级是用 hjkl 替代方向键,h 左移,j 下移,k 上移,l 右移。之所以用这几个字母,是因为它们在整个键盘的中排区域,手指几乎不用离开基准位,就可以完成上下左右移动。刚上手的时候你可以把系统方向键映射掉,强迫自己用 hjkl,两周以后就会习惯。
第二优先级是词移动和行内移动:
| 按键 | 作用 | 简记方式 |
|---|---|---|
w |
跳到下一个单词开头 | word |
b |
跳到上一个单词开头 | backward |
e |
跳到当前/下一个单词结尾 | end |
0 |
跳到行首 | 数字 0 |
^ |
跳到行首第一个非空白字符 | 可以理解为“真正的内容开头” |
$ |
跳到行尾 | 正则里的行尾 |
gg |
跳到文件第一行 | go go |
G |
跳到文件最后一行 | go 大写的 G |
nG |
跳到第 n 行 | 比如 42G 直达 42 行 |
第三优先级是“增量搜索式移动”。很多时候跳转目标并不是明确的行号,而是一个关键词。在普通模式下直接输入 /关键词,然后回车,就能跳到下一个匹配处,按 n 继续向下,按 N 向上。这种方式在长文件里找函数定义特别快。
我经常跟团队里的人说:你判断 Vim 水平,不用问会多少命令,看他移动光标是否依赖方向键就够了。默认方向键没被禁用,但如果你还在用它,说明你还没有进入模态编辑的快车道。
2.2 保存退出与进入插入模式:新手最容易混淆的顺序
进入插入模式是新手接触 Vim 的第一件正事。命令很少,但要理解它们之间的区别:
i:在当前光标之前插入。a:在当前光标之后插入。A:在当前行行尾插入,这个非常常用,比先$再a省一步。o:在当前行下方新建一行并进入插入模式。O:在当前行上方新建一行并进入插入模式。I:在当前行行首插入。
保存退出命令我已经在上面的表格列过一遍,这里讲一个新人经常搞反的点:很多人以为“保存退出”是一个原子动作,所以拼命找组合键。实际上 Vim 的理念是“先保存,再退出”,两者可以分开、可以组合,看你的即时需求。如果你只是改完一个文件还要继续改另一个,那 :w 就够了;如果你确定要关掉它,再使用 :wq。这个拆分的思路贯穿 Vim 的整个设计:每条命令做一件事,组合起来做复杂的事。
还有个小技巧:ZZ 是普通模式下的“保存退出”,ZQ 是“不保存退出”。如果哪天你按 :q 时忘了加 !,而 Vim 提示文件被修改过但你又不想保存,不要纠结,按 ZQ 就能直接走人。不过要小心,ZQ 会丢掉全部未保存内容,用前多确认一下。
2.3 删除、变换与撤销:比 Backspace 更高阶的逻辑
普通模式下 x 删除光标所在字符,dd 删除整行,D 删除从光标到行尾的内容。这个逻辑和市面上大多数编辑器不同:Vim 把“删除”看作是“剪切”,删除的内容会进入寄存器,之后可以用 p 粘贴出来。
这里需要搞明白几个容易混淆的命令:
| 命令 | 作用 | 常见误用 |
|---|---|---|
x |
删除光标下一个字符 | 新手容易按成 X,那是向前删除 |
dd |
剪切当前行 | 删除后可以 p 放回 |
dw |
删除到下一个词首 | 不是删除整个单词,会留下词尾 |
caw |
删除整个单词并进入插入模式 | ciw 是删单词内部,区别看范围 |
cc |
剪切整行并进入插入模式 | 相当于先 dd 再 i |
D |
从光标删到行尾 | 相当于 d$ |
yy |
复制当前行 | 不是删除,是复制 |
至于撤销,u 是撤销上一次修改,Ctrl+r 是重做。这个组合比任何编辑器的撤销都强,因为它支持几乎无限步的撤销。
我还特别建议新人忘掉 Backspace 长按的旧习惯,在 Vim 里想删除就用 d 系命令,想改就直接改,不要“回删再重敲”。这个观念转变非常重要,因为它决定了你是用 Vim 的方式思考,还是用记事本的方式在 Vim 里硬撑。
3. 真正提升效率的编辑范式:动词 + 范围 + 对象
3.1 用组合思维替代单键思维
如果说前面那些命令是单词量,那 Vim 真正的语法就是“动词 + 范围 + 对象”。这也是为什么很多人“背完命令还是不会用”,因为命令之间不是孤立的,而是可以像积木一样组合的。
Vim 的常用动词包括:
d:删除(delete)c:修改(change),删除后进入插入模式y:复制(yank,注意不叫 copy)v:选中(visual,可视范围)>/<:右缩进 / 左缩进gU/gu:改成大写 / 改成小写
动词后面要接范围与对象。所谓对象可以是:
- 字符级:
l(一个字符)、w(一个词) - 行级:
j、k或数字,比如d2j删除当前行及以下两行 - 语句/段落级:
(、)、{、}代表句与段 - 文本对象(最强大):
i(inside)和a(around)
举几个实际例子:
dw= 删除到下一个词首,中文场景下就是“删掉光标到词尾之间的内容”。ci"= 删除双引号内部的全部内容,然后进入插入模式。这个命令在改 JSON、改 HTML 属性时几乎是神技。ca(= 删除当前括号及其内部所有内容(比如整个函数参数列表)。yap= 复制当前整个段落。diw= 删除光标所在的整个单词,不留下多余空格。daW= 删除包括前后空格在内的整个大词(由空格分隔的词)。
这些组合看起来没什么,但一旦用顺了,普通人要花好几步操作的事情,你只需要按两三个键。这个差异不是“快一倍”的问题,而是编辑思路的彻底变化:你不再是逐字敲,而是在操作文本的逻辑单元。
3.2 用 . 命令把重复操作做到极致
很多人不知道,Vim 里的 . 命令可以重复上一次“完整的修改”。它是 Vim 里最被低估的效率神器之一。
什么叫“完整的修改”?比如你用 ciw 把当前单词改成 hello,敲完 Esc 后再按 .,Vim 会把这个动作原封不动地应用到下一处——删除光标下的单词并输入 hello。这个特性在成批修改代码时特别有用。
我举一个真实场景:一段配置里有很多 URL,你要把所有的 http:// 前缀删掉。传统做法是一个个找到位置,切到插入模式,删字符,再切回普通模式。在 Vim 里,你可以:
- 先删除第一处
http://。 - 之后用
n跳到下一处匹配。 - 按
.,自动执行同样的删除。
如果配合录制宏(q 键),那效果更加恐怖。宏的操作思路是:按 qa 开始录制到寄存器 a,录完按 q 停止,之后用 @a 重放,@@ 重放最近一次宏。碰到文件里 100 行都要加前缀,先把光标移到需要处理的某一行,录一次宏,然后 100@a 一口气执行 100 次,Vim 会自动在每次宏重放后移动到下一目标(如果宏末尾包含 j、n 这类移动命令的话)。
这里有个重要原则:录制宏之前,先保证光标所在的“位置关系”在每处要处理后都一样。宏不是智能 agent,它只是机械重放。如果处理第 1 行时光标在某列,那么第 2 行光标也必须在同一相对位置,宏才会有效。所以录制前最好先做一次“回到行首 + 通过搜索跳到目标”的动作,让宏内部自己保证每次都从相同状态开始。
4. 高频实战场景拆解:从热搜词看真实需求
4.1 一次注释多行,别再傻傻手动敲了
“vim 一次注释多行”是搜索热度非常高的词,很多同学到了要写脚本、调配置的时候,发现几十行代码都要临时注释掉,手工敲注释符效率太低。Vim 里至少有三种经典做法,我按推荐度排个序。
方法一:可视块操作(最快,推荐先学)
把光标移到需要注释的第一行开头。按 Ctrl+v 进入可视块模式,使用 j 或 k 上下选中多行(也可以按数字再按上下方向,比如 10j 往下选中 10 行)。选好之后按大写 I 进入插入模式,此时光标会跳到块的第一个字符处。输入注释符(比如 Python 的 #、Shell 的 #、C/C++ 的 //),最后按 Esc。你会看到刚才选中的每一行开头都出现了注释符。
这里最容易被忽略的细节是:进入插入模式前选中的是一个矩形块,插入内容会填充到整个块的每一行上。按完 Esc 后会有一点延迟才生效,不要以为卡住了,这是 Vim 的异步刷新。如果你用的是 Neovim,这个延迟通常更小。
方法二:命令行 :s 替换法
如果不想用可视模式,也可以选中要注释的行后在命令行里输入:
bash复制:'<,'>s/^/#/
'<,'> 是 Vim 自动填写的“上一次选中的范围”,^ 匹配每行行首,替换为 # 就是加注释符。这个方法的好处是可以指定行号范围,比如 :10,20s/^/#/ 只注释第 10 到 20 行。
方法三:宏录制
思路也很简单:在每一行行首插入注释符,然后用宏循环。缺点是宏需要处理“光标回到行首并移到下一行”的逻辑,不如可视块法直觉。
我自己的实践是,日常临时注释用可视块,写入脚本或配置时习惯用带行号范围的 s 命令,因为可以直接在命令中精确控制范围。
4.2 全选复制与屏幕上那条 “lines yanked”
另一个高频词是“vim全选复制 lines yanked”。新人总会遇到这种情况:在 Vim 里复制了几行文本,屏幕底部出现一行提示“7 lines yanked”,然后他跑到别的地方按 Ctrl+v 粘贴,发现什么都没有。这就要讲清楚 Vim 的剪贴板体系和系统剪贴板之间的区别了。
Vim 内部默认的复制(yank)结果存放在 Vim 自己的寄存器里,和操作系统剪贴板不是一回事。默认按 p 只能粘贴到 Vim 内部的缓冲区。如果你想把内容复制到系统剪贴板,然后粘贴到浏览器、IDE、其他编辑器,就必须明确指定系统剪贴板寄存器 +(或者 *,取决于系统)。
常用命令如下:
- 全选:
ggVG,表示跳转到第一行,进入可视模式并选中到文件末尾。 - 复制到 Vim 内部寄存器:
"默认就是匿名寄存器,直接y就行。 - 复制到系统剪贴板:全选后按
"+y,注意顺序是先ggVG再"+y。 - 或者更简洁:
:%y+,意思是把整个文件复制到系统剪贴板。
很多服务器上的 Vim 是精简版,编译时没有开启剪贴板支持。你可以先用下面这条命令检查:
bash复制vim --version | grep clipboard
如果输出中包含 +clipboard,说明支持;如果是 -clipboard,说明不支持系统剪贴板。这时 "+y 会直接报错。解决办法是换用带剪贴板支持的 Vim(比如安装 gvim 或 neovim),或者在 tmux 环境下用 tmux 的复制模式中转。
早期我在这上面卡了很久,复制成功后会看到 Vim 底部提示 “N lines yanked”,这里的 “yanked” 不是报错,而是 Vim 对复制动作的官方叫法。yank 在 Vim 语境里就是“复制到寄存器”。所以看到这个提示,你只需要知道操作成功了,接下来搞清楚它到底存到哪个寄存器就行。
4.3 已有占位数字的一列递增,怎么用?
这个热搜词非常实际。比如你已经写好了一列 1、然后想把它改成 1 到 100 的编号,或者一个模板里有几十个占位数字 0,你想把它们增量替换成有序号数。Vim 内建命令 g Ctrl+A 就能处理这个需求,不需要装插件。
先说原理:在普通模式下,Ctrl+A 会把光标下的数字加 1,Ctrl+X 会减 1。这个增量操作支持可视模式下对多行数字同时做“按行递增”。
具体操作步骤:
- 准备一列占位数字,比如在第一行输入
1,然后用yy和p复制出需要的行数,此时所有行都是1。 - 使用
V按行选中这些待编号的行,或者用Ctrl+v选中数字本身所在的列。 - 按下
g Ctrl+A,Vim 会从第一行开始,把每一行的数字依次增加 1,最终得到 1、2、3、4……递增的序列。
这里有一个重要细节:g Ctrl+A 执行递增时,参考的“起点”是当前可视区域第一行的数字。所以如果你希望序号从 10 开始而不是 1 开始,只需要把第一行的数字改成 10,再执行同样的操作即可。同理,如果你需要步长是 5,可以把起始数字设成 1,然后手动算好,或者更好的是用宏。
宏录制的思路是这样的:
- 第一行先输入
1。 qa开始录制。yy p在下一行复制同样的内容。Ctrl+A将新的这行数字加 1。q结束录制。- 接着重复执行
@a,每执行一次就多一行并加 1。
不过我个人更推荐第一种 g Ctrl+A 方案,因为它是全选后一次性完成,不产生中间步骤,操作更干净。唯一要注意的是,执行前光标必须放在数字上,否则 Vim 会找不到要递增的数字;如果该行没有数字,Ctrl+A 会原地不动。
这样一个功能,你在普通编辑器里往往要写一段代码或拉一个填充公式,在 Vim 里几下就完成了。这也是很多人一旦真正用熟 Vim 后就再也回不去的主要原因之一。
5. 搜索、替换与多文件操作
5.1 搜索与高亮:不要再用视线去大海捞针
前面提过 /关键词 是向下搜索、?关键词 是向上搜索。这里要补充的是搜索结果高亮管理。默认情况下 Vim 会把所有匹配项高亮显示,这很好——但当你搜索完想继续编辑时,高亮不消失会很烦人。你可以在命令行里输入 :nohlsearch,或者更顺手地配置一个快捷键,比如在 .vimrc 里加上:
vim复制noremap <silent> <C-l> :nohlsearch<CR><C-l>
这个映射让 Ctrl+L 既清屏又清除高亮。
搜索时还要注意大小写问题。Vim 默认区分大小写,所以搜 function 不会匹配 Function。如果你希望默认智能处理——输入全小写时不区分大小写,输入含大写时区分大小写,可以在 .vimrc 中设置:
vim复制set ignorecase
set smartcase
这两个配置配合起来非常常用,算是老用户标配。
5.2 替换的细节与确认流
替换操作看起来简单,但细节很多。最基础的命令是:
bash复制:s/old/new/
只替换当前行第一个匹配;要替换当前行所有匹配,写成:
bash复制:s/old/new/g
如果要对整个文件替换,在前面加上范围:
bash复制:%s/old/new/g
这里的 % 表示所有行。想限定某段行号则是 :10,20s/old/new/g。
重点想讲的是 c 标志,也就是确认模式:
bash复制:%s/old/new/gc
添加 c 后,Vim 每找到一处匹配都会停下来问你是否替换,并提示 y/n/a/q/l 等选项。如果你不确定哪些该替换、哪些不该替换,这个选项能帮你逐处确认。需要注意的是,按 a 是全部替换,按 l 是只改当前这一处然后结束,按 q 是退出。
新人最常犯的错误是把特殊字符当作普通字符来搜索。比如替换 JSON 里的大量双引号、反斜杠,或者路径里的 /,如果没有转义,/ 会和替换命令的分隔符冲突。我的习惯是替换路径时把分隔符换成别的符号,比如:
bash复制:%s#/usr/local#/opt/homebrew#g
用 # 当分隔符就不会被路径里的 / 干扰。
5.3 多文件与分屏:从单文件编辑走向全局操作
Vim 本身不是 IDE,但它提供了在多个文件间切换的基础能力。最简单的是直接用 vim file1 file2 file3 打开多个文件,然后通过 :next 和 :prev 来回切换。
更常用的是缓冲区列表。你可以在一个 Vim 进程里打开多个文件,用 :ls 查看缓冲区列表,用 :buffer N 跳转到第 N 号缓冲区,用 :bdelete N 卸载某个文件。如果配合文件管理器插件,这其实已经有点像现代 IDE 的文件 Tab 了。
我自己用分屏比较多。sp 水平分割,vsp 垂直分割,然后可以用 Ctrl+w 加方向键切换光标所在窗格,:close 关闭当前窗格。如果你要同时比对两个文件,Vim 的 diff 模式更直观:
bash复制vim -d file1 file2
它会自动高亮出两个文件之间的差异,并可以直接在两侧窗口间拷贝和合并修改。这个功能在排查合并冲突、代码审查时非常好用,几乎可以替代部分图形化的 diff 工具。
6. 从熟练到顺手:配置与扩展
6.1 必配的 .vimrc 核心选项
Vim 默认配置更适合上世纪的老终端,放到现代环境下体验不好。所以先别急着装插件,把 .vimrc 里最核心的几项配置加好,体验就能提升一大截。
vim复制" 显示行号与相对行号
set number
set relativenumber
" 缩进相关
set tabstop=4
set shiftwidth=4
set expandtab
" 搜索体验
set incsearch
set hlsearch
set ignorecase
set smartcase
" 编码与格式
set encoding=utf-8
filetype plugin indent on
" 普通模式下映射 jj 到 Esc
inoremap jj <Esc>
其中 set relativenumber 是一个被很多人低估的配置。它把行号显示成“相对当前行的距离”,比如当前在第 10 行,上下几行显示的是 3、2、1 这样的数字。这样你就知道按 7j 可以下移 7 行,按 5k 可以上移 5 行,把“数行号”的脑力负担降到最低。
inoremap jj <Esc> 是很多人的最爱,它的作用是让你在插入模式里快速连按两个 j 就回到普通模式,避免每次把手挪到 Esc 键。我承认这个映射需要一定时间去适应,但一旦适应后,效率提升非常明显。
6.2 插件管理的最小实践
如果你不想把 Vim 变成 IDE,那就只需要一个轻量插件管理器。我个人推荐 vim-plug,安装很简单,使用方式也很直观。
在 .vimrc 里加入:
vim复制call plug#begin('~/.vim/plugged')
Plug 'preservim/nerdtree'
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
Plug 'tpope/vim-surround'
call plug#end()
然后在 Vim 里执行 :PlugInstall,插件就会自动安装。
这几个插件里,我最想强调的是 vim-surround,它对“批量补全引号或括号”的需求帮助极大。比如你想把一句话的普通双引号改成单引号,只需把光标移到字符串上,按 cs"',Vim 会立刻把整个被 " 包围的文字最外层引号替换成单引号。
不过要很诚恳地说一句:插件是锦上添花,不是必需品。很多人刚学会几个插件就疯狂装主题、装语法补全、装文件树,结果启动速度变慢、快捷键冲突、报错不断,最后把 Vim 用成了“卡卡的 IDE”,得不偿失。我建议入门阶段先把内建功能用顺,再慢慢加插件,逐个体会它们带来的增量价值。
6.3 别掉进“配置陷阱”,编辑器只是手段
前面标题里有个相关热搜叫“分别用vim和xcode”,我看到之后的第一个感想是:不是每个人都需要把 Vim 换成 Xcode,也不是所有场景都适合用 Vim。如果是 macOS/iOS 平台的图形界面应用开发,Xcode 的项目管理、界面设计器、断点调试天然有优势;而如果你在处理服务器配置、写脚本、快速改一个文件,或者身在 SSH 远程终端里,Vim 的轻量、跨平台、无 GUI 依赖就是最大优势。这两者的关系不是非此即彼,很多开发者是 Xcode 配合 Vim 模式插件一起用的。
我个人给团队里新人的建议是:无论你最终主力编辑器是什么,都应该花一周时间把 Vim 的基本操作过一遍。原因很简单,服务器上总会遇到没有图形界面的时刻,和 Git 打交道的编辑器回调也可能默认为 vi;更重要的是,Vim 的“不离开键盘、直接操作文本逻辑单元”这一套思想,本身就在帮你重新理解怎么高效编辑文本。工具会过时,但这种思维是长期有价值的。
有一类人特别容易踩“配置陷阱”——花大量时间找插件、调配色、写复杂映射,结果实际写代码的时间反而少了。我自己也曾陷入这种状态,最后发现很多自定义配置一个月都用不上一次。最好的路径是先保留一个干净的最小配置,按自己的真实需求慢慢迭代,而不是一来就抄别人的整套配置。
7. 常见问题与排查技巧实录
7.1 你几乎一定会遇到的几个问题
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 按方向键出现 A B C D | Vim 处于插入模式且终端对方向键解释异常 | 先按 Esc 退回普通模式,再按方向键;如果仍异常,确认当前是否为纯终端环境 |
| 保存时报 E45: 'readonly' option is set | 文件只读,或被另一进程占用 | 强制保存用 :w!,但要确认你确实有权限修改它 |
dd 后立刻后悔,想找回内容 |
删除后被操作覆盖了 | 按 u 撤销;如果已经执行了别的操作,用 :earlier 5m 回到 5 分钟前的文本状态 |
| 按 Backspace 无法删除缩进空格 | backspace 选项默认保守 |
在 .vimrc 里加 set backspace=indent,eol,start |
| 文件编码乱码 | 文件可能是 GBK 编码,当前为 UTF-8 | 重新打开指定编码:vim --cmd "set encoding=utf-8" file 或 :e ++enc=gbk file |
| 卡在“完全没有反应”的状态 | 可能是按了 Ctrl+S,终端进入 XOFF 软件流控 |
按 Ctrl+Q 恢复输出 |
这些问题的共同点在于:它们都不是 Vim 本身崩溃,而是模式、终端流控或者配置项造成的误会。排查的时候先确认自己处于什么模式,再看终端是否对 Vim 状态产生了干扰,最后检查 .vimrc 配置是否和默认行为冲突。
7.2 三个值得拿小本子记的避坑经验
第一,不要在系统 Vim 是旧版本时使用新特性。很多 Linux 发行版默认装的是 Vim 8 或者更早的版本,部分较新的语法(比如 :terminal、某些弹出窗口特性)在 vim 7.x 上完全不支持。如果你需要这些特性,建议直接装编译新版或者用 Neovim,而不是煞费苦心地找替代方案。
第二,使用中文输入法时操作 Vim 容易出诡异问题。比如插入模式下输入中文后,按 Esc 回到普通模式,再按 / 搜索,此时如果输入法还停留在中文状态,搜索框里就会出现全角字符,导致搜不到任何内容。久而久之我养成了一个习惯:Vim 里做命令操作前,先按一次 Shift,确保输入法临时切到英文模式。
第三,不要在改重要文件前禁用备份。默认情况下 Vim 的 swap 文件机制会在你意外崩溃后保留现场,但要是你在 .vimrc 里盲目关闭了备份,又碰到断电或终端被强杀,就会丢掉大量未保存内容。建议至少保留 set swapfile,或者配置 set backupdir 到独立目录,把备份文件集中管理,需要清理也方便。
写在最后
我自己这些年从 Vim 里学到的不只是“怎么按快捷键”,更多是一种分而治之的思维:所有复杂的文本处理,都可以拆成移动、选择、修改、重复这几个环节,每个环节只做好一件事,再通过组合和宏来完成大任务。
如果你刚接触 Vim,我建议先别急着读完整篇文章里的所有命令。今天就先练几件事:打开文件、移动光标、进入插入模式写几行字、保存退出;明天再加删行、复制行、搜索替换;一周后你已经能应付日常的配置修改和脚本编辑了。两个月后,等你真正用熟了文本对象和宏,你会发现自己再也不想回到那个必须频繁抬手摸鼠标的旧世界。这也是我为什么愿意花这么多篇幅写这篇内容的原因——Vim 的学习曲线确实陡峭,但一旦跨过去,回报是长期的。
