vim 程序编辑器
vim(Vi IMproved)是 Linux/Unix 系统中最常用的文本编辑器,是 vi 的增强版本。它是一款模式化编辑器,通过不同模式切换来执行不同的编辑操作。
1. vim 的三种模式
| 模式 | 说明 | 进入方式 | 退出方式 |
|---|
| 一般模式(Normal) | 默认模式,用于浏览、复制、粘贴、删除等 | 打开文件即进入 | 按 i/a/o 等进入编辑模式,按 : 进入命令模式 |
| 编辑模式(Insert) | 用于输入和修改文本内容 | i/a/o/I/A/O 等 | 按 Esc 回到一般模式 |
| 命令行模式(Command) | 用于保存、退出、搜索替换等高级操作 | 从一般模式按 : / ? | 执行完命令自动回到一般模式 |
模式切换关系
┌──────────┐
┌────▶│ 编辑模式 │────┐
│ └──────────┘ │
i/a/o │ Esc │
┌──────────┐ │ │
│ 一般模式 │◀┘ ▼ Esc
│ (Normal) │ ┌──────────┐
│ │──────────────▶│ 命令模式 │
└──────────┘ : / ? │ (Command)│
Esc 回到 └──────────┘
一般模式
2. 启动与退出 vim
启动 vim
vim # 新建空文件
vim filename.txt # 打开/新建文件
vim +N filename.txt # 打开文件并跳到第 N 行
vim + filename.txt # 打开文件并跳到最后一行
vim -R filename.txt # 以只读模式打开
vim file1 file2 file3 # 同时打开多个文件
vim -d file1 file2 # diff 模式比较两个文件
退出 vim(在命令行模式下)
| 命令 | 说明 |
|---|
:w | 保存(不退出) |
:w! | 强制保存(只读文件需要) |
:q | 退出(未修改时) |
:q! | 强制退出(不保存修改) |
:wq 或 :x 或 ZZ | 保存并退出 |
:wq! | 强制保存并退出 |
:e! | 放弃所有修改,恢复到上次保存的状态 |
3. 一般模式常用操作
3.1 光标移动
基础移动
| 按键 | 说明 |
|---|
h / ← | 左移一个字符 |
j / ↓ | 下移一行 |
k / ↑ | 上移一行 |
l / → | 右移一个字符 |
记忆技巧:j 像向下箭头,k 像向上箭头
行内移动
| 按键 | 说明 |
|---|
0 或 Home | 移到行首 |
^ | 移到行首第一个非空字符 |
$ 或 End | 移到行尾 |
w | 跳到下一个单词词首 |
b | 跳到上一个单词词首 |
e | 跳到当前/下一个单词词尾 |
f{char} | 跳到本行下一个出现 {char} 的位置 |
t{char} | 跳到本行下一个出现 {char} 的前一个位置 |
F{char} | 跳到本行上一个出现 {char} 的位置 |
行间移动
| 按键 | 说明 |
|---|
gg | 跳到文件第一行 |
G | 跳到文件最后一行 |
NG 或 Ngg | 跳到第 N 行 |
Ctrl+f | 向下翻一页(Page Down) |
Ctrl+b | 向上翻一页(Page Up) |
Ctrl+d | 向下翻半页 |
Ctrl+u | 向上翻半页 |
H | 跳到当前屏幕顶部 |
M | 跳到当前屏幕中间 |
L | 跳到当前屏幕底部 |
{ | 跳到上一个空行(段落开头) |
} | 跳到下一个空行(段落结尾) |
% | 跳到匹配的括号处(()、[]、{}) |
3.2 删除操作
| 按键 | 说明 |
|---|
x | 删除光标处一个字符 |
X | 删除光标前一个字符 |
nx | 删除光标后 n 个字符 |
dd | 删除(剪切)整行 |
ndd | 删除(剪切)从当前行开始的 n 行 |
dG | 删除到文件末尾 |
dgg | 删除到文件开头 |
d0 | 删除从行首到光标处 |
d$ | 删除从光标处到行尾 |
dw | 删除一个单词 |
D | 删除从光标处到行尾(同 d$) |
注意:dd 删除的内容会被放入剪贴板,可以用 p 粘贴。
3.3 复制与粘贴
| 按键 | 说明 |
|---|
yy | 复制整行 |
nyy | 复制从当前行开始的 n 行 |
yw | 复制一个单词 |
y$ | 复制从光标到行尾 |
y0 | 复制从行首到光标处 |
p | 在光标后粘贴 |
P | 在光标前粘贴 |
"ayy | 复制整行到寄存器 a |
"ap | 粘贴寄存器 a 的内容 |
3.4 撤销与重做
| 按键 | 说明 |
|---|
u | 撤销上一步操作 |
Ctrl+r | 重做(反撤销) |
U | 撤销对当前行的所有修改 |
. | 重复上一次操作 |
3.5 查找与替换
查找(一般模式下)
| 按键 | 说明 |
|---|
/keyword | 向下查找 keyword |
?keyword | 向上查找 keyword |
n | 跳到下一个匹配 |
N | 跳到上一个匹配 |
* | 向下查找当前光标所在单词 |
# | 向上查找当前光标所在单词 |
查找支持正则表达式,如 /^hello 查找行首为 hello 的行。
替换(命令行模式下)
# 基本语法
:s/old/new/ # 替换当前行第一个匹配
:s/old/new/g # 替换当前行所有匹配
:s/old/new/gc # 替换当前行所有匹配(逐个确认)
:%s/old/new/g # 替换全文所有匹配
:%s/old/new/gc # 替换全文所有匹配(逐个确认)
# 指定范围替换
:1,10s/old/new/g # 替换第 1-10 行
:5,$s/old/new/g # 替换第 5 行到文件末尾
:'a,'bs/old/new/g # 替换标记 a 到标记 b 之间
# 分隔符替换(当 old 或 new 含 / 时)
:s#old#new#g
:s|old|new|g
3.6 其他常用操作
| 按键 | 说明 |
|---|
r | 替换光标处单个字符 |
R | 进入替换模式(持续替换直到按 Esc) |
J | 将下一行合并到当前行 |
~ | 切换光标处字符大小写 |
Ctrl+a | 光标所在数字加 1 |
Ctrl+x | 光标所在数字减 1 |
>> | 当前行缩进 |
<< | 当前行反缩进 |
== | 自动缩进当前行 |
ga | 查看光标处字符的 ASCII 码 |
Ctrl+g | 显示当前文件名和行号信息 |
4. 编辑模式
从一般模式进入编辑模式的方式:
| 按键 | 说明 |
|---|
i | 在光标前插入 |
I | 在行首插入 |
a | 在光标后插入 |
A | 在行尾插入 |
o | 在当前行下方新建一行并进入编辑模式 |
O | 在当前行上方新建一行并进入编辑模式 |
s | 删除光标处字符并进入编辑模式 |
S | 删除整行内容并进入编辑模式 |
5. 命令行模式常用命令
5.1 文件操作
:w # 保存
:w filename # 另存为 filename
:r filename # 在光标处插入文件内容
:r !command # 在光标处插入命令的输出
:n # 编辑下一个文件
:N # 编辑上一个文件
:e filename # 打开新文件
:e! # 重新加载文件(放弃修改)
:bn # 切换到下一个 buffer
:bp # 切换到上一个 buffer
:ls # 列出所有 buffer
:bd # 关闭当前 buffer
5.2 行号与显示
:set nu # 显示行号(number)
:set nonu # 隐藏行号
:set rnu # 显示相对行号
:syntax on # 开启语法高亮
:syntax off # 关闭语法高亮
:set hlsearch # 高亮搜索结果(hls)
:set nohlsearch # 取消搜索高亮
:set incsearch # 增量搜索(输入时实时匹配)
:set ignorecase # 搜索忽略大小写(ic)
:set noignorecase # 搜索区分大小写
:set cursorline # 高亮当前行
:set cursorcolumn # 高亮当前列
:set wrap # 自动换行
:set nowrap # 不自动换行
:set list # 显示不可见字符(Tab、换行符等)
:set nolist # 隐藏不可见字符
:set scrolloff=5 # 上下滚动时保留 5 行
:set sidescrolloff=10 # 左右滚动时保留 10 列
5.3 执行外部命令
:!command # 执行外部命令(如 :!ls)
:!! # 重复上一次外部命令
:shell # 进入 Shell(输入 exit 返回 vim)
5.4 多窗口操作
# 分屏
:sp filename # 水平分屏
:vsp filename # 垂直分屏
Ctrl+w s # 水平分屏当前文件
Ctrl+w v # 垂直分屏当前文件
# 切换窗口
Ctrl+w h # 切换到左边窗口
Ctrl+w j # 切换到下边窗口
Ctrl+w k # 切换到上边窗口
Ctrl+w l # 切换到右边窗口
Ctrl+w w # 循环切换窗口
# 调整窗口大小
Ctrl+w = # 所有窗口等高
Ctrl+w + # 增加当前窗口高度
Ctrl+w - # 减少当前窗口高度
# 关闭窗口
Ctrl+w c # 关闭当前窗口
Ctrl+w q # 退出当前窗口
:only # 只保留当前窗口
6. 多文件编辑
Buffer 列表
vim 打开多个文件时,会将它们放入 buffer 列表:
vim file1.c file2.c file3.c
:ls # 查看 buffer 列表
:bn # 下一个 buffer
:bp # 上一个 buffer
:b1 # 跳到第 1 个 buffer
:bd # 关闭当前 buffer
:bw # 彻底关闭 buffer
Buffer 列表显示
:ls
1 %a "file1.c" line 1
2 "file2.c" line 0
3 "file3.c" line 0
| 标志 | 说明 |
|---|
% | 当前 buffer |
# | 上一个 buffer |
a | 活跃 buffer |
7. 文本标记与折叠
文本标记
# 设置标记
m{a-z} # 设置局部标记(当前文件有效)
m{A-Z} # 设置全局标记(跨文件有效)
# 跳转到标记
'{a-z} # 跳转到标记所在行的行首
'{a-z} # 跳转到标记所在位置
:marks # 查看所有标记
常用内置标记
| 标记 | 说明 |
|---|
'' | 上一次跳转的位置 |
'"' | 上一次关闭文件的位置 |
'^' | 上一次插入的位置 |
'.' | 上一次修改的位置 |
代码折叠
# 手动折叠
zf{motion} # 创建折叠(如 zfaq 折叠一个段落)
zo # 打开折叠
zc # 关闭折叠
za # 切换折叠状态
zR # 打开所有折叠
zM # 关闭所有折叠
# 折叠方法
:set foldmethod=manual # 手动折叠(默认)
:set foldmethod=indent # 按缩进折叠
:set foldmethod=syntax # 按语法折叠
:set foldmethod=marker # 按标记折叠(默认标记 {{{ 和 }}})
8. vim 配置文件
配置文件位置
| 文件 | 作用域 | 说明 |
|---|
/etc/vimrc | 全局 | 所有用户生效 |
~/.vimrc | 当前用户 | 个人配置(推荐) |
.exrc | 当前用户 | 兼容 vi 的配置 |
常用配置示例
# ~/.vimrc
" ===== 基本设置 =====
set nu " 显示行号
set relativenumber " 显示相对行号
set tabstop=4 " Tab 宽度为 4 个空格
set shiftwidth=4 " 缩进宽度 4
set expandtab " Tab 替换为空格
set autoindent " 自动缩进
set smartindent " 智能缩进
set cindent " C/C++ 缩进
set ruler " 显示光标位置
set cursorline " 高亮当前行
set showmatch " 括号匹配高亮
set laststatus=2 " 始终显示状态栏
" ===== 搜索设置 =====
set hlsearch " 高亮搜索结果
set incsearch " 增量搜索
set ignorecase " 搜索忽略大小写
set smartcase " 有大写时区分大小写
" ===== 编码设置 =====
set encoding=utf-8 " 文件编码
set fileencodings=utf-8,gbk,gb2312,cp936
" ===== 其他设置 =====
set nobackup " 不创建备份文件
set noswapfile " 不创建交换文件
set autoread " 文件变化时自动重新加载
set clipboard=unnamed " 使用系统剪贴板
set mouse=a " 支持鼠标
set t_Co=256 " 256 色支持
syntax on " 语法高亮
filetype indent on " 根据文件类型自动缩进
" ===== 快捷键映射 =====
let mapleader="," " 设置 Leader 键为逗号
" 快速保存
nnoremap <leader>w :w<CR>
" 快速退出
nnoremap <leader>q :q<CR>
" 禁用方向键(强制使用 h/j/k/l)
nnoremap <Up> <NOP>
nnoremap <Down> <NOP>
nnoremap <Left> <NOP>
nnoremap <Right> <NOP>
9. vim 实用技巧
9.1 批量操作
# 批量添加注释(行首加 #)
:1,10s/^/#/g
# 批量取消注释(行首去掉 #)
:1,10s/^#//g
# 批量缩进
:1,10s/^/ /g # 添加 4 个空格缩进
# 在每行末尾加分号
:%s/$/;/g
# 删除行尾空白
:%s/\s\+$//g
9.2 宏录制与回放
# 录制宏
q{a-z} # 开始录制到寄存器 a
# ... 执行一系列操作 ...
q # 停止录制
# 回放宏
@a # 回放寄存器 a 中的宏
@@ # 回放上一次的宏
10@a # 回放 10 次
示例:给多行加引号
1. 光标移到第一行,按 qa 开始录制
2. 按 I 进入行首编辑模式,输入 "
3. 按 Esc 回到一般模式
4. 按 $ 跳到行尾,按 A 进入行尾编辑模式,输入 "
5. 按 Esc,按 j 移到下一行
6. 按 q 停止录制
7. 按 10@a 对接下来 10 行执行同样的操作
9.3 可视模式(Visual Mode)
| 按键 | 说明 |
|---|
v | 进入字符可视模式 |
V | 进入行可视模式 |
Ctrl+v | 进入块可视模式(列选择) |
可视模式下的操作
# 选择后可执行
d # 删除选中内容
y # 复制选中内容
> # 缩进选中内容
< # 反缩进选中内容
~ # 切换大小写
u # 转为小写
U # 转为大写
块可视模式(列编辑)
1. 按 Ctrl+v 进入块可视模式
2. 用 hjkl 选择矩形区域
3. 按 I 输入内容(在选中区域每行开头插入)
4. 按 Esc 完成
块编辑非常适合批量修改对齐的文本,如批量修改注释、添加/删除列等。
9.4 快速跳转
Ctrl+o # 跳转到上一个位置
Ctrl+i # 跳转到下一个位置
Ctrl+t # 跳转到标签定义(需 ctags)
gd # 跳转到局部变量定义
gf # 打开光标下的文件路径
10. vim 常见问题
10.1 交换文件冲突
E325: ATTENTION
Found a swap file by the name ".file.txt.swp"
解决方法:
# 查看是否有其他 vim 进程
ps aux | grep vim
# 如果确认没有其他进程,直接删除交换文件
rm .file.txt.swp
# 在 vim 中选择处理方式
# [O]pen Read-Only 以只读方式打开
# [E]dit anyway 忽略交换文件继续编辑
# [R]ecover 恢复数据
# [D]elete it 删除交换文件
# [Q]uit 退出
# [A]bort 中止
10.2 文件编码问题
# 查看当前文件编码
:set fileencoding
# 转换编码
:set fileencoding=utf-8
# 打开指定编码的文件
vim ++enc=gbk filename.txt
10.3 文件格式(换行符)
:set fileformat # 查看:unix(LF)/ dos(CRLF)/ mac(CR)
:set ff=unix # 设为 Unix 格式(LF)
:set ff=dos # 设为 Windows 格式(CRLF)
10.4 意外关闭后的恢复
# vim 非正常关闭后,可通过交换文件恢复
vim -r filename.txt # 恢复模式打开文件
11. vi 与 vim 的区别
| 特性 | vi | vim |
|---|
| 语法高亮 | 不支持 | 支持 |
| 撤销 | 只能撤销一次 | 无限撤销 |
| 多窗口 | 不支持 | 支持 |
| 插件 | 不支持 | 支持丰富的插件生态 |
| 折叠 | 不支持 | 支持 |
| 自动补全 | 不支持 | 支持(Ctrl+n / Ctrl+p) |
| 分屏 | 不支持 | 支持 |
| 帮助系统 | 简单 | 完整(:help) |
12. vim 学习路径建议
| 阶段 | 内容 |
|---|
| 入门 | 掌握三种模式切换、基本光标移动(hjkl)、保存退出(:wq)、插入(i/a/o)、删除(dd/x) |
| 基础 | 复制粘贴(yy/p)、撤销重做(u/Ctrl+r)、查找替换(/:%s)、可视模式(v/V) |
| 进阶 | 多窗口(:sp/:vsp)、宏录制(q)、块可视模式(Ctrl+v)、标记(m)、缓冲区管理 |
| 高级 | 自定义配置(.vimrc)、插件使用、正则表达式、脚本编程 |
提示:可以在终端输入 vimtutor 进入 vim 官方交互式教程,约 30 分钟即可掌握基本操作。