04.Vim 入门:从模式切换、文件保存到高效移动
Vim 并不是“没有鼠标的记事本”,而是一套以键盘命令为核心的文本编辑方式。初学者真正需要先掌握的不是几十个快捷键,而是模式、命令结构和安全保存文件的方法。本文从第一次打开文件开始,讲清 Vim 的工作模式、插入命令、保存退出、光标移动、交换文件及基础配置。
一、Vim 是什么
在 Linux 终端中编写 C 语言代码,常见工具可以分成两类:
- 编辑器负责创建和修改源代码,例如 Vim;
- 编译器负责把源代码转换成可执行程序,例如 GCC。
Vim 是 Vi Improved 的缩写,可以理解为在经典vi编辑器基础上扩展而来的版本。它支持语法高亮、多级撤销、窗口拆分、补全、插件等功能,同时保留了 Vi 最重要的“模式化编辑”思想。
很多 Linux 系统都提供vi命令,但它可能是精简版,也可能是指向 Vim 的符号链接。可以分别查看:
vi--versionvim--versionUbuntu 中如果尚未安装 Vim,可以执行:
sudoaptupdatesudoaptinstallvim安装完成后,使用下面的命令确认版本:
vim--version|head二、打开、创建和定位文件
1. 打开已有文件或创建新文件
vimhelloworld.c- 如果
helloworld.c已经存在,Vim 会打开它; - 如果文件不存在,Vim 会打开一个以该名称命名的新缓冲区;
- 只有执行保存命令后,新文件才真正写入磁盘。
屏幕底部出现[New]或[新文件]时,表示当前编辑的是尚未保存的新文件。不要把“Vim 已经显示了文件名”误认为文件已经创建成功。
2. 打开后直接定位到指定行
vim+20 helloworld.c这条命令打开文件后把光标放到第 20 行。处理编译器报错时非常方便,例如 GCC 提示错误位于main.c:37,可以直接执行:
vim+37 main.c也可以让光标直接定位到文件末尾:
vim+ helloworld.c还可以定位到第一个匹配指定内容的位置:
vim+/main helloworld.c3. 只读打开文件
查看重要配置而不希望误改时,可以使用:
vim-R/etc/hosts-R表示只读模式。它主要用于防止误操作,并不是文件权限控制;如果确实拥有写权限,仍可在 Vim 中强制写入,因此编辑系统文件时依然要谨慎。
三、先建立正确的“模式”概念
普通编辑器中,按下字母通常就是输入字母;Vim 中,同一个按键在不同模式下有不同含义。例如,普通模式中的w表示向后移动一个单词,插入模式中的w才会输入字符w。
Vim 最常用的四种模式如下。
| 模式 | 主要用途 | 常见进入方式 | 常见离开方式 |
|---|---|---|---|
| 普通模式 Normal | 移动、删除、复制、粘贴、执行编辑命令 | 启动 Vim 后默认进入;按Esc返回 | 按i、v、:等进入其他模式 |
| 插入模式 Insert | 像普通编辑器一样输入文字 | i、a、o、I、A、O | Esc或Ctrl+[ |
| 可视模式 Visual | 选择字符、整行或矩形文本 | v、V、Ctrl+v | Esc |
| 命令行模式 Command-line | 保存、退出、替换、设置选项 | 在普通模式中按:、/或? | 执行后通常自动返回;也可按Esc取消 |
有些教程把普通模式称为“命令模式”,把命令行模式称为“末行模式”。名称不同,但关键是分清两件事:
- 普通模式中直接按
dd、yy、G等按键; - 保存退出等命令通常先按
:,命令出现在屏幕底部。
当不知道自己处于什么状态时,先按一两次Esc回到普通模式。这是学习 Vim 时最可靠的“复位动作”。
四、完成第一次编辑
打开一个 C 源文件:
vimhello.c此时处于普通模式,按i进入插入模式,然后输入:
#include<stdio.h>intmain(void){printf("Hello, world!\n");return0;}输入完成后按Esc返回普通模式,再依次输入:
:wq最后按回车。w是 write,表示保存;q是 quit,表示退出。回到终端后可以检查文件:
ls-lhello.ccathello.c整个流程可以记成:
vim 文件名 -> i -> 输入内容 -> Esc -> :wq -> Enter如果只记住一套最小操作,这一套就足以开始使用 Vim。
五、六组常用插入命令
在普通模式下,插入命令决定“从哪里开始输入”。
| 命令 | 作用 |
|---|---|
i | 在光标所在字符之前插入 |
a | 在光标所在字符之后追加 |
I | 在当前行第一个非空白字符之前插入 |
A | 在当前行末尾追加 |
o | 在当前行下方新建一行并进入插入模式 |
O | 在当前行上方新建一行并进入插入模式 |
例如,光标位于下面一行的分号上:
return0;- 按
I会跳到r前开始输入; - 按
A会跳到分号后开始输入; - 按
o会在下一行创建新行; - 按
O会在上一行创建新行。
区分大小写非常重要。i和I、o和O是不同命令,文档中的大写字母通常意味着按住Shift。
六、保存、退出与重新加载
这些命令都要在普通模式中先按:,输入命令后再按回车。
| 命令 | 作用 |
|---|---|
:w | 保存当前文件,但不退出 |
:q | 退出;有未保存修改时会拒绝退出 |
:wq | 保存并退出 |
:x | 有修改时保存,然后退出 |
:q! | 放弃本次未保存修改并强制退出 |
:w! | 尝试强制写入,不能绕过操作系统权限 |
:e! | 放弃未保存修改,从磁盘重新读取当前文件 |
1.:wq、:x和ZZ的区别
三者都常用于离开 Vim:
:wq总是执行一次写入后退出;:x只在内容变化时写入,然后退出;- 普通模式中的
ZZ与:x类似,不需要输入冒号和回车。
普通模式中的ZQ等价于:q!,会放弃修改并退出。由于它不会询问确认,初学阶段不建议形成随手使用的习惯。
2. 另存文件
:w hello_backup.c这会把当前内容写入hello_backup.c,但当前缓冲区通常仍然对应原文件。如果希望另存后继续编辑新文件名,使用:
:saveas hello_backup.c3. 保存失败时先看原因
常见提示包括:
E212: Can't open file for writing:目录或文件没有写权限;E45: 'readonly' option is set:当前缓冲区处于只读状态;E37: No write since last change:存在未保存修改,Vim 拒绝执行退出或切换操作。
不要一看到错误就使用感叹号。!只能跳过 Vim 自己的部分保护,无法让普通用户突破 Linux 文件权限。先用:w确认报错,再检查路径和权限更稳妥。
七、普通模式中的基础移动
1. 字符级移动
| 命令 | 作用 |
|---|---|
h | 左移一个字符 |
j | 下移一行 |
k | 上移一行 |
l | 右移一个字符 |
方向键也能使用,但h j k l不需要把手移出键盘主区,后续还可以与数字和编辑命令组合。
命令前可以加次数:
5j 向下移动 5 行 12l 向右移动 12 个字符2. 按单词移动
| 命令 | 作用 |
|---|---|
w | 移到下一个单词的开头 |
b | 移到当前或上一个单词的开头 |
e | 移到当前或下一个单词的结尾 |
ge | 移到上一个单词的结尾 |
W、B、E | 按空白分隔的“大单词”移动 |
小写命令会把标点视为分隔,例如sum=num1+num2中会经过多个位置;大写命令主要把连续的非空白内容视为一个整体。代码中两组命令都很有用。
3. 在一行内定位
| 命令 | 作用 |
|---|---|
0 | 移到物理行首 |
^ | 移到本行第一个非空白字符 |
$ | 移到行尾 |
g_ | 移到本行最后一个非空白字符 |
f字符 | 在本行向右找到该字符并落在字符上 |
t字符 | 在本行向右找到该字符并停在它前面 |
; | 重复上一次f、t、F或T查找 |
, | 反方向重复行内字符查找 |
例如一行中有多个逗号,输入f,可以移动到下一个逗号,继续按;会依次跳到后面的逗号。
4. 按行号和文件位置移动
| 命令 | 作用 |
|---|---|
gg | 文件第一行 |
G | 文件最后一行 |
20G或20gg | 第 20 行 |
:20 | 第 20 行 |
Ctrl+g | 显示当前文件名、行号和文件位置 |
当 GCC 给出main.c:20:5时,先输入20G到第 20 行,再在本行定位第 5 列,通常比连续按方向键快得多。
5. 翻页和屏幕内移动
| 命令 | 作用 |
|---|---|
Ctrl+f | 向下翻一页 |
Ctrl+b | 向上翻一页 |
Ctrl+d | 向下翻半页 |
Ctrl+u | 向上翻半页 |
H | 移到当前屏幕顶部附近 |
M | 移到当前屏幕中部 |
L | 移到当前屏幕底部附近 |
zz | 把当前行滚动到屏幕中央 |
zt | 把当前行滚动到屏幕顶部 |
zb | 把当前行滚动到屏幕底部 |
注意,H、M、L移动光标,zz、zt、zb主要调整屏幕显示位置。
6. 按段落和成对符号移动
Vim 通常把空行分隔的文本视为段落:
{移到上一段;}移到下一段;%在配对的()、[]、{}之间跳转。
阅读 C 函数时,把光标放到左花括号上按%,可以快速找到对应的右花括号。这对排查括号层级错误非常实用。
八、行号、语法高亮和缩进设置
1. 临时显示行号
:set number关闭行号:
:set nonumber相对行号会显示其他行与当前行的距离,便于使用5j、8k等命令:
:set relativenumber同时显示当前绝对行号和其他行的相对行号:
:set number relativenumber2. 临时设置 C 代码缩进
:set expandtab :set tabstop=4 :set shiftwidth=4 :set softtabstop=4这些选项的含义是:
expandtab:按 Tab 时插入空格;tabstop=4:已有制表符显示为 4 列宽;shiftwidth=4:自动缩进和>>、<<每次移动 4 列;softtabstop=4:插入模式下 Tab 和退格按 4 列处理。
3. 写入个人配置文件
冒号命令只对当前 Vim 会话生效。希望每次启动都生效,可以编辑~/.vimrc:
syntax on filetype plugin indent on set number set cursorline set expandtab set tabstop=4 set shiftwidth=4 set softtabstop=4 set backspace=indent,eol,start set incsearch set hlsearch set ignorecase set smartcase配置含义如下:
syntax on开启语法高亮;filetype plugin indent on根据文件类型加载缩进规则;cursorline突出显示当前行;incsearch在输入搜索词时实时定位;ignorecase默认忽略搜索大小写;smartcase在搜索词包含大写字母时自动区分大小写。
如果某一行配置报错,可以使用下面的命令查看 Vim 实际读取了哪些配置文件:
:scriptnames九、交换文件是什么
Vim 编辑文件时通常会创建交换文件,名称类似:
.hello.c.swp它是隐藏文件,用于崩溃恢复,也用于提醒“同一文件可能正在被另一个 Vim 进程编辑”。如果 Vim 或终端异常退出,再次打开原文件时可能看到E325: ATTENTION。
遇到提示时不要直接按D删除,先判断情况:
- 检查提示中的进程是否仍在运行;
- 确认是否有另一个终端正在编辑同一文件;
- 如果上次确实崩溃,选择恢复,或执行
vim -r hello.c; - 检查恢复内容,保存到安全文件;
- 确认交换文件已经无用后再删除。
一种稳妥的恢复方式是:
vim-rhello.c进入后先另存备份:
:w hello_recovered.c确认恢复内容无误并且不存在其他编辑进程后,再处理旧交换文件。交换文件不是普通备份,也不能替代 Git。
十、查看帮助,不必死记全部命令
Vim 自带非常完整的帮助系统。在普通模式中输入:
:help查询具体命令:
:help i :help :w :help motion.txt :help usr_02.txt帮助窗口中的Ctrl+]可以跟随光标下的链接,Ctrl+o可以跳回上一个位置,:q关闭帮助窗口。
系统还可能提供交互式入门教程:
vimtutor它会复制一份练习文本供当前用户操作,不会修改系统文件。
十一、初学者常见问题
1. 按键后没有输入字母
很可能仍处于普通模式。按i进入插入模式,屏幕底部通常会显示-- INSERT --。
2. 输入:q却无法退出
当前文件有未保存修改。需要保留修改就使用:wq;确认全部放弃才使用:q!。
3. 终端突然像“卡住”一样不响应
可能误按了Ctrl+s,触发终端的软件流控制。按Ctrl+q恢复输出。它与 Vim 的保存功能无关。
4. 中文出现乱码或换行异常
先查看编码和换行格式:
:set encoding? :set fileencoding? :set fileformat?Linux 通常使用 UTF-8 和 Unix 换行。如果文件来自 Windows,可能显示fileformat=dos。转换为 Unix 换行后需要重新保存:
:set fileformat=unix :w5. 鼠标复制的内容无法用p粘贴
普通模式中的p粘贴的是 Vim 寄存器内容,不一定是系统剪贴板。终端粘贴、Vim 寄存器和系统剪贴板是三个相关但不完全相同的概念,下一篇会详细说明。
6. 误操作后不知道发生了什么
先按Esc回到普通模式,再按u撤销最近一次修改;如果多撤销了一步,按Ctrl+r恢复撤销。不要在慌乱中连续输入随机命令。
十二、第一阶段速查表
| 目标 | 命令 |
|---|---|
| 打开文件 | vim 文件名 |
| 打开并跳到第 20 行 | vim +20 文件名 |
| 进入插入模式 | i |
| 行末追加 | A |
| 下方新建一行 | o |
| 返回普通模式 | Esc |
| 保存 | :w |
| 保存退出 | :wq或:x |
| 放弃修改退出 | :q! |
| 文件首行、末行 | gg、G |
| 行首、首个非空白、行尾 | 0、^、$ |
| 上下翻页 | Ctrl+b、Ctrl+f |
| 跳转配对括号 | % |
| 显示行号 | :set number |
| 撤销、恢复撤销 | u、Ctrl+r |
十三、总结
学习 Vim 的第一道门槛是模式,而不是快捷键数量。只要先形成“按Esc回普通模式”的习惯,并掌握i、:wq、:q!、h j k l、w b、0 ^ $、gg G等基础命令,就可以安全地完成日常代码编辑。
接下来真正提升效率的关键,是理解 Vim 的“操作符 + 移动范围”语法。例如d表示删除,w表示移动到下一个单词,把它们组合为dw就能删除一个单词。下一篇将在此基础上系统讲解删除、修改、复制粘贴、寄存器、可视模式、查找替换、多行注释和多文件编辑。