视频时长: 18分10秒
概述#
本节是 vi/vim 编辑器的进阶操作篇,承接上一讲(三种模式、光标移动、文本查找)的内容,继续深入讲解撤销与重做、删除剪切、复制粘贴、可视模式区块操作、命令行模式命令、搜索替换、分屏编辑、寄存器、宏录制以及 .vimrc 进阶配置。末尾保留了视频中总结的6个最常用快捷键,帮助初学者快速上手。
建议在阅读本节前,先通过 vimtutor 巩固上一讲的基础操作:
$ vimtutor[TOC]
核心要点#
1. 撤销与重做 (Undo & Redo)#
撤销是编辑器中最重要的功能之一。vi 和 vim 在撤销机制上有本质区别。
1.1 vi 与 vim 的撤销差异#
| 编辑器 | 快捷键 | 撤销次数 | 说明 |
|---|---|---|---|
| 原始 vi | u | 仅一次 | 按 u 撤销后再次按 u,会撤销"撤销",相当于来回切换 |
| vim | u (可多次) | 无限次 | 可反复按 u 一直回退到文件打开时的状态 |
| Ubuntu vi | u | 仅一次 | Ubuntu 中 vi 实际指向 vim.tiny(精简版),同样只支持单次撤销 |
如果想获得完整的多级撤销能力,建议安装完整版 vim:
$ sudo apt update
$ sudo apt install vim -y1.2 撤销与重做命令详解#
| 快捷键 | 功能 | 说明 |
|---|---|---|
| u | 撤销 (undo) | 撤销最近一次操作。在 vim 中可连续按多次,逐步回退 |
| Ctrl+r | 重做 (redo) | 恢复被 u 撤销的操作。相当于"反撤销" |
| U | 撤销当前行的所有修改 | 仅当光标没有离开该行时有效(大写的 U) |
| . (句点) | 重复上一次操作 | 重复最近一次编辑操作(修改、删除、粘贴等),极其实用 |
实操示例#
# 打开一个文件,进行一系列操作:
vim test.txt
# 在一般模式下:
i # 进入插入模式
hello world # 输入文本
Esc # 回到一般模式
u # 撤销刚才输入的文本(hello world 消失)
Ctrl+r # 重做,文本恢复
# 多级撤销示例:
i # 进入插入模式
line1 Enter line2 Enter line3 # 输入三行
Esc # 回到一般模式
u # 撤销第三行
u # 撤销第二行
u # 撤销第一行(文件回到空状态)
Ctrl+r # 恢复第一行
Ctrl+r # 恢复第二行
Ctrl+r # 恢复第三行
# .(重复)的用法:
dd # 删除当前行
. # 再删除一行(重复 dd 操作)
. # 再删除一行
# . 会重复任何修改操作,包括删除、粘贴、替换等1.3 时间旅行式撤销#
vim 也提供了按时间点撤销的能力:
:earlier 10s # 回退到 10 秒前的状态
:earlier 5m # 回退到 5 分钟前的状态
:later 10s # 前进到 10 秒后的状态
:undolist # 查看撤销历史列表2. 删除操作详解#
vim 的删除命令本质上是"剪切",被删除的内容会存入寄存器(见第 8 节),可以通过 p 或 P 粘贴出来。
2.1 字符级删除#
| 快捷键 | 功能 | 示例与说明 |
|---|---|---|
| x | 删除光标处单个字符 | 相当于普通编辑器的 Delete 键 |
| X | 删除光标前单个字符 | 相当于 Backspace 键 |
| nx | 删除光标后 n 个字符 | 5x 删除从光标开始的 5 个字符 |
2.2 单词级删除#
| 快捷键 | 功能 | 说明 |
|---|---|---|
| dw | 删除从光标到下一个单词开头 | delete word(不含当前单词前的空格) |
| daw | 删除光标所在的整个单词(含前后空格之一) | delete a word(对中文也有效) |
| diw | 删除光标所在的整个单词(不含空格) | delete inner word |
| de | 删除从光标到单词结尾 | delete to end of word |
| db | 删除从光标到单词开头 | delete backward |
dw vs daw 的区别:dw 删除从光标位置到下一个单词开头,daw 删除光标所在的完整单词(不管光标在单词的哪个位置)。daw 通常更实用。
2.3 行级删除#
| 快捷键 | 功能 | 说明 |
|---|---|---|
| dd | 删除当前行 | 最常用,相当于"剪切当前行" |
| ndd | 删除从当前行起的 n 行 | 3dd 删除当前行及以下共 3 行 |
| D | 删除从光标到行尾 | Delete to end of line(等价于 d$) |
| d0 | 删除从光标到行首 | 0 表示行首 |
| d^ | 删除从光标到行首第一个非空字符 | ^ 表示第一个非空字符 |
| d$ | 删除从光标到行尾 | $ 表示行尾 |
| dG | 删除从当前行到文件末尾 | G 表示文件末尾 |
| dgg | 删除从当前行到文件开头 | gg 表示文件开头 |
2.4 其他组合删除#
| 快捷键 | 功能 |
|---|---|
| di( 或 dib | 删除括号内的内容(delete inside brackets) |
| di" | 删除双引号内的内容 |
| di' | 删除单引号内的内容 |
| da( 或 dab | 删除括号及括号内的内容(delete a bracket block) |
实操示例#
# 假设有以下文本,光标在 h 处(用 | 标记):
# |hello world, this is a (test) file.
x # 删除 h -> ello world, this is a (test) file.
dw # 删除 ello(到下一个单词开头)
# -> world, this is a (test) file.
daw # 在 world 的任意位置按 daw,删除整个 world
# -> , this is a (test) file.
dd # 删除整行 -> 空
# 行部分删除示例:
# 文本:This is a very long line of text
# 光标在 v 处(very)
D # 删除 very 到行尾 -> This is a
d0 # 删除行首到 very 之前(在 very 的 v 后) -> very long line of text
# 括号内容删除:
# 文本:function(arg1, arg2, arg3)
# 光标在括号内任意位置
di( # 删除括号内参数 -> function()
da( # 删除括号及参数 -> function3. 复制与粘贴#
3.1 基础复制命令#
| 快捷键 | 功能 | 说明 |
|---|---|---|
| yy | 复制当前行 | 最常用(yank) |
| nyy | 复制从当前行起的 n 行 | 3yy 复制 3 行(等价于 y3y) |
| Y | 复制当前行 | 同 yy(在某些配置中等同于 y$) |
| yw | 复制一个单词 | 从光标位置到下一个单词开头 |
| yaw | 复制光标所在整个单词 | 不管光标在单词的哪个位置 |
| y$ | 复制从光标到行尾 | yank to end of line |
| y0 | 复制从光标到行首 | yank to beginning of line |
| yG | 复制从当前行到文件末尾 | |
| ygg | 复制从当前行到文件开头 |
3.2 基础粘贴命令#
| 快捷键 | 功能 | 使用场景 |
|---|---|---|
| p (小写) | 粘贴到光标之后 | 光标在行内则贴到字符后;复制整行时贴到当前行下方 |
| P (大写) | 粘贴到光标之前 | 光标在行内则贴到字符前;复制整行时贴到当前行上方 |
关键区分:复制整行(yy)时,p 贴到下方,P 贴到上方。复制部分文本(yw)时,p 贴到光标后,P 贴到光标前。这是初学者最容易混淆的地方。
3.3 可视模式下的复制粘贴(推荐方式)#
可视模式可以让你像现代编辑器一样用鼠标/方向键选中文字后再操作。这是初学者最容易接受的方式:
# 字符选择模式(v)
v # 进入字符可视模式(左下角显示 -- VISUAL --)
移动光标 # 用 hjkl 或方向键选中文字(高亮显示)
y # 复制选中区域(yank)
p # 粘贴(贴到光标后)
# 行选择模式(V)
V # 进入行可视模式(左下角显示 -- VISUAL LINE --)
j 或 k # 上下移动选择整行(高亮显示)
y # 复制选中的行
p # 粘贴到当前行下方
P # 粘贴到当前行上方
# 块选择模式(Ctrl+v)
Ctrl+v # 进入块可视模式(左下角显示 -- VISUAL BLOCK --)
移动光标 # 选择一个矩形块(对列操作非常有用)
y # 复制矩形块
p # 粘贴实操示例#
# 示例 1:复制粘贴单行
vim test.txt
yy # 复制当前行
p # 粘贴到下一行(连续按 p 可多次粘贴)
# 示例 2:复制多行
3yy # 复制 3 行(当前行 + 下面 2 行)
G # 跳到文件末尾
p # 在文件末尾粘贴这 3 行
# 示例 3:可视模式复制
v # 进入可视模式
j j j # 向下选择 3 行(高亮)
y # 复制
P # 粘贴到当前行上方
# 示例 4:块选择模式(列编辑)
# 文本:
# apple red
# banana yellow
# grape purple
# 目标:在所有行前面添加 "fruit: "
gg # 跳到第一行
Ctrl+v # 进入块选择模式
G # 选择到文件末尾(选中第一列)
I # 在块前插入(进入插入模式)
fruit: # 输入文本
Esc # 按 Esc 后,所有选中行的第一列都会添加 "fruit: "4. 可视模式(Visual Mode)详解#
可视模式是 vim 区别于原始 vi 的重要特性,提供可视化文本选择。
| 快捷键 | 模式名称 | 英文提示 | 功能 |
|---|---|---|---|
| v (小写) | 字符选择模式 | – VISUAL – | 按字符选择,从光标起始位置到结束位置 |
| V (大写) | 行选择模式 | – VISUAL LINE – | 按整行选择,自动包含完整行 |
| Ctrl+v | 块选择模式 | – VISUAL BLOCK – | 矩形块选择,对列操作特别有用 |
4.1 可视模式下的操作流程#
1. 按 v / V / Ctrl+v 进入可视模式
2. 移动光标 扩展选择区域
3. 按操作键 执行操作(d 删除、y 复制等)选中区域后可以执行的操作:
| 操作 | 快捷键 | 说明 |
|---|---|---|
| 删除 | d | 删除选中内容并存入寄存器 |
| 复制 | y | 复制选中内容到寄存器 |
| 改大小写 | ~ 或 U 或 u | ~ 切换大小写,U 全大写,u 全小写 |
| 缩进 | > 或 < | > 右缩进,< 左缩进 |
| 替换 | r + 字符 | 将选中内容全部替换为指定字符 |
| 连接行 | J | 将选中行连接为一行 |
4.2 块选择模式的特殊用法#
块选择模式(Ctrl+v)支持列编辑,这是普通编辑器难以实现的功能:
# 示例:给多行代码添加注释
# 原始文本:
# line1
# line2
# line3
# line4
gg # 跳到第一行
Ctrl+v # 进入块选择模式
4j # 向下选 4 行(选中最左列)
I # 在块前插入(大写 I)
# # 输入 # 注释符
Esc # 等待片刻,所有行前面都加上 #5. 搜索与替换#
搜索替换是编辑工作中最重要的操作之一。vim 提供了强大的 :s (substitute) 命令。
5.1 继续查找(接上一讲)#
上一讲介绍了 /text 和 ?text 查找功能。本节补充在查找到匹配项后的操作:
| 快捷键 | 功能 |
|---|---|
| n | 跳转到下一个匹配项 |
| N | 跳转到上一个匹配项 |
| * | 向下查找光标所在的单词(快速查找相同单词) |
| # | 向上查找光标所在的单词 |
| g* | 向下查找光标所在的部分单词(模糊匹配) |
| g# | 向上查找光标所在的部分单词(模糊匹配) |
5.2 :s 替换命令基础语法#
:[range]s/old/new/[flags]| 部分 | 说明 |
|---|---|
| range | 替换范围(行号、% 全文、.,$ 当前行到末尾等) |
| s | substitute 命令 |
| old | 要被替换的文本(支持正则表达式) |
| new | 替换后的文本 |
| flags | 替换标志(g 全部替换、c 确认、i 忽略大小写等) |
5.3 :s 命令常用形式#
| 命令 | 功能 | 说明 |
|---|---|---|
:s/old/new/ | 替换当前行第一个匹配的 old | 只替换当前行的第一个匹配 |
:s/old/new/g | 替换当前行所有匹配的 old | g = global,当前行内全部替换 |
:s/old/new/gc | 替换当前行所有匹配,每次确认 | c = confirm,每次替换前询问 |
:%s/old/new/g | 替换整个文件中所有 old | % 表示全文范围 |
:%s/old/new/gc | 替换整个文件,每次确认 | 最安全的全文替换方式 |
:3,10s/old/new/g | 替换第 3 到第 10 行中的所有 old | 指定行范围 |
:.,$s/old/new/g | 替换当前行到文件末尾 | . 表示当前行,$ 表示最后一行 |
:'<,'>s/old/new/g | 替换可视模式选中区域 | 在可视模式下按 : 自动出现此范围标记 |
实操示例#
# 假设文件内容:
# red apple
# red banana
# red cherry
:%s/red/green/g # 全文替换,所有 red -> green
# green apple
# green banana
# green cherry
:%s/red/green/gc # 全文替换,每次确认
# replace with green (y/n/a/q/l/^E/^Y)?
# y=替换当前, n=跳过, a=替换全部剩余, q=退出替换
# l=替换当前并退出, ^E=下滚, ^Y=上滚
# 替换当前行所有 old 为 new(不带 %)
:s/hello/world/g # 只替换当前行
# 使用正则表达式
:%s/^\s*//g # 删除所有行首的空白字符(^行首 \s空白 *任意数量)
:%s/\s*$//g # 删除所有行尾的空白字符
:%s/^#//g # 取消所有行的注释(删除行首的 #)5.4 替换时的分隔符#
当替换内容本身包含 / 时(如文件路径),可以换用其他分隔符(#、@、, 等):
:%s#/home/user#/home/admin#g # 将路径 /home/user 替换为 /home/admin
:%s@http://old.com@https://new.com@g # URL 替换6. 分屏编辑#
vim 支持在同一个终端窗口中分割出多个编辑区域,同时查看或编辑多个文件。这是 vim 相比原始 vi 的重要增强功能。
6.1 分屏命令#
| 命令 | 简写 | 功能 |
|---|---|---|
:split | :sp | 水平分割窗口(上下分屏) |
:split filename | :sp filename | 水平分屏并打开指定文件 |
:vsplit | :vs 或 :vsp | 垂直分割窗口(左右分屏) |
:vsplit filename | :vs filename | 垂直分屏并打开指定文件 |
:new | - | 水平分屏并打开一个空白缓冲区 |
:vnew | - | 垂直分屏并打开一个空白缓冲区 |
:close 或 :q | - | 关闭当前窗口 |
:only 或 Ctrl+w o | - | 只保留当前窗口,关闭其他所有窗口 |
6.2 窗口间切换#
| 快捷键 | 功能 |
|---|---|
| Ctrl+w h | 切换到左侧窗口 |
| Ctrl+w j | 切换到下方窗口 |
| Ctrl+w k | 切换到上方窗口 |
| Ctrl+w l | 切换到右侧窗口 |
| Ctrl+w w | 在所有窗口中循环切换 |
| Ctrl+w t | 切换到最左上角的窗口 |
| Ctrl+w b | 切换到最右下角的窗口 |
记忆技巧:Ctrl+w 是窗口操作的"前缀键",后面跟 hjkl 方向键移动。
6.3 调整窗口大小#
| 快捷键 | 功能 |
|---|---|
| Ctrl+w = | 使所有窗口等宽等高 |
| Ctrl+w + | 增加当前窗口高度 |
| Ctrl+w - | 减少当前窗口高度 |
| Ctrl+w > | 增加当前窗口宽度 |
| Ctrl+w < | 减少当前窗口宽度 |
实操示例#
# 场景 1:同时查看两个文件
vim file1.txt
:split file2.txt # 上下分屏,上方 file1,下方 file2
Ctrl+w j # 切换到下方窗口
Ctrl+w k # 切换回上方窗口
Ctrl+w = # 让窗口等分
# 场景 2:左右对比两个文件
vim -d file1.txt file2.txt # vimdiff 模式,自动垂直分屏并高亮差异
# 或手动操作:
vim file1.txt
:vsplit file2.txt # 左右分屏
Ctrl+w l # 切换到右边
Ctrl+w h # 切换回左边
# 场景 3:编辑文件的同时查看另一个文件
vim script.sh
:split /var/log/syslog # 下方打开日志文件(只读查看)6.4 在分屏间复制粘贴#
分屏模式下复制粘贴与单窗口完全相同,因为所有窗口共享寄存器:
# 在窗口 A 中复制:
yy # 复制当前行
# 切换到窗口 B:
Ctrl+w j # 切换到下方窗口
p # 粘贴7. 寄存器(Registers)#
寄存器是 vim 内部存储复制、删除内容的"存储槽"。理解寄存器是掌握 vim 复制粘贴的关键。
7.1 寄存器类型#
| 寄存器 | 名称 | 说明 |
|---|---|---|
"" | 无名寄存器 | 默认寄存器,d/c/s/x/y 操作的内容都存到这里 |
"0 | 复制专用寄存器 | y(复制)操作的内容存在这里,不会被删除操作覆盖 |
"1 - "9 | 编号寄存器 | "1 存最近一次删除的内容,"2 存倒数第二次…,最多到 "9 |
"a - "z | 命名寄存器 | 用户可以显式指定使用哪个字母寄存器(26个) |
"+ | 系统剪贴板 | 与操作系统剪贴板互通(需要 vim 编译时支持 +clipboard) |
"* | 选择寄存器 | 与鼠标中键粘贴互通(X11 系统) |
"/ | 搜索寄存器 | 存储最近一次搜索的模式 |
": | 命令寄存器 | 存储最近一次命令行模式命令 |
"% | 文件名寄存器 | 存储当前文件名 |
". | 最后插入文本寄存器 | 存储最近一次插入的文本 |
7.2 寄存器操作命令#
| 命令 | 功能 |
|---|---|
:reg 或 :registers | 查看所有寄存器内容 |
"ayy | 复制当前行到寄存器 a |
"ap | 粘贴寄存器 a 的内容 |
"byw | 复制一个单词到寄存器 b |
"5dd | 删除 5 行到寄存器 1(自动,也可显式指定) |
"+yy | 复制当前行到系统剪贴板(可与系统其他程序互通) |
"+p | 从系统剪贴板粘贴 |
实操示例#
# 查看所有寄存器内容
:reg
# --- Registers ---
# "" hello world
# "0 hello world
# "1 deleted line
# "+ clipboard content
# 使用命名寄存器分别存储不同内容
"ayy # 复制当前行到寄存器 a
G # 跳到文件末尾
"byy # 复制最后一行到寄存器 b
"ap # 先粘贴寄存器 a 的内容
"bp # 再粘贴寄存器 b 的内容
# 系统剪贴板互通
# 在 vim 中复制文本到系统剪贴板:
"+yy # 复制当前行到剪贴板
# 现在可以在浏览器、VS Code 等程序中 Ctrl+v 粘贴
# 从系统剪贴板粘贴到 vim:
"+p # 在一般模式下,从剪贴板粘贴
# 检查是否支持系统剪贴板:
vim --version | grep clipboard
# 如果看到 +clipboard 说明支持
# 如果看到 -clipboard 说明不支持,需要安装 vim-gtk3 或 vim-gnome:
sudo apt install vim-gtk3 -y7.3 无名寄存器 vs 复制专用寄存器的关键区别#
这是一个容易踩坑的地方:
# 复制一行:
yy # 内容存入 "" 和 "0
# 删除一行:
dd # 内容存入 "",但 "0 不受影响
# 粘贴:
p # 会粘贴 "" 的内容(即被删除的那行,不是你复制的那行!)
# 如果你想粘贴之前复制的内容:
"0p # 使用 "0 寄存器,粘贴复制的内容结论:如果需要粘贴之前复制的内容,使用
"0p最可靠。
8. 宏录制 (Macro Recording)#
宏录制是 vim 最强大的功能之一。它允许你录制一系列操作,然后在需要的地方重放这些操作,实现批量编辑。
8.1 宏录制与回放命令#
| 快捷键 | 功能 |
|---|---|
| qa | 开始录制宏到寄存器 a(a 可以是任意字母 a-z) |
| q | 结束录制(在录制过程中按 q) |
| @a | 回放寄存器 a 中的宏 |
| @@ | 回放最近一次回放的宏(重复上一次 @ 操作) |
| n@a | 将寄存器 a 中的宏执行 n 次 |
8.2 宏录制完整流程#
1. qa 开始录制(将宏保存到寄存器 a)
2. 执行操作 在一般模式下执行要录制的编辑命令序列
3. q 结束录制
4. @a 回放宏(执行一次)
5. 10@a 回放宏 10 次实操示例#
# 示例 1:给多行文本添加引号
# 原始文本:
# apple
# banana
# cherry
# 目标:给每行加引号和逗号,变成 "apple", "banana", "cherry"
# 录制宏:
qa # 开始录制到寄存器 a(左下角显示 recording @a)
I" # 在行首插入双引号(大写 I = 行首插入)
Esc # 回到一般模式
A", # 在行尾插入双引号和逗号(大写 A = 行尾追加)
Esc # 回到一般模式
j # 移动到下一行
q # 结束录制
# 回放宏:
@a # 对第二行执行宏(apple 已处理,现在在第1行)
2@a # 对剩余两行执行
# 或者一次性处理 100 行:
100@a # 执行 100 次# 示例 2:批量格式化注释
# 原始文本:
# TODO fix bug
# TODO add test
# TODO refactor
# 目标:每行前面加 # 注释符,行尾加 ;
# 录制宏:
qb # 开始录制到寄存器 b
I# # 行首插入 #
Esc # 回到一般模式
A; # 行尾插入 ;
Esc # 回到一般模式
j # 下一行
q # 结束录制
# 回放:
2@b # 处理剩余两行# 示例 3:宏的嵌套调用
# 可以在宏录制中调用另一个宏
# 寄存器 a 中录制了基础操作,寄存器 b 中录制时调用 @a
qc # 录制到 c
@a # 调用宏 a
j # 下一行
q # 结束
# 这样 @c 每次执行时都会先执行 @a 再移动到下一行8.3 注意事项#
- 录制过程中不要使用鼠标,所有操作必须通过键盘完成
- 录制时选择相对位置操作,不要用绝对行号(如
50G),否则回放时行为不可预测 - 使用
w/b/j/k等相对移动命令,而不是gg/G等绝对移动命令 - 录制过程中如果出错,可以按
q停止,然后重新录制 - 查看已录制的宏内容:
:reg a(查看寄存器 a 中的宏)
9. 命令行模式常用命令#
9.1 文件操作命令#
| 命令 | 功能 | 说明 |
|---|---|---|
:w | 保存文件 | write |
:w filename | 另存为 filename | 不改变当前编辑文件名 |
:w! filename | 强制覆盖已存在的 filename | |
:r filename | 读取 filename 内容插入到光标位置 | read |
:r !command | 读取命令输出插入到光标位置 | 如 :r !date 插入当前日期 |
:e filename | 打开(编辑)另一个文件 | edit |
:e! | 放弃所有修改,重新加载文件 | “恢复出厂设置” |
:q | 退出(未修改时) | quit |
:q! | 强制退出,不保存修改 | quit without write |
:wq | 保存并退出 | write and quit |
:x | 保存并退出(仅文件有修改时才写入) | 同 :wq,但更智能 |
:wqa | 保存所有窗口并退出 | write quit all |
:qa! | 强制退出所有窗口 | quit all |
9.2 显示设置命令#
| 命令 | 简写 | 功能 |
|---|---|---|
:set number | :set nu | 显示行号 |
:set nonumber | :set nonu | 取消行号显示 |
:set relativenumber | :set rnu | 显示相对行号 |
:set hlsearch | :set hls | 高亮搜索结果 |
:set nohlsearch | :set nohls | 取消高亮 |
:set list | - | 显示不可见字符(Tab 显示为 ^I,行尾显示 $) |
:set nolist | - | 隐藏不可见字符 |
:set paste | - | 粘贴模式(防止缩进错乱) |
:set nopaste | - | 退出粘贴模式 |
9.3 执行外部命令#
| 命令 | 功能 | 示例 |
|---|---|---|
:!command | 执行外部命令并显示结果 | :!ls -la |
:r !command | 将命令输出插入到光标位置 | :r !date |
:sh | 临时回到 Shell | 输入 exit 返回 vim |
:!% | 执行当前文件 | % 表示当前文件名,如 :!python % |
9.4 信息查看命令#
| 命令 | 功能 |
|---|---|
:f 或 Ctrl+g | 显示当前文件名、行号、修改状态 |
:version | 显示 vim 版本信息 |
:scriptnames | 显示所有已加载的脚本/插件 |
:map | 显示所有快捷键映射 |
:set | 显示所有不同于默认值的设置 |
:set all | 显示所有设置项 |
10. 进阶 .vimrc 配置详解#
上一讲介绍了基础 .vimrc 配置,本节补充更多实用配置项。
10.1 完整初学者配置示例#
" ============================================
" Vim 初学者配置文件 (~/.vimrc)
" ============================================
" --- 基础设置 ---
set nocompatible " 必须放第一行:禁用 vi 兼容模式,启用 vim 全部功能
filetype on " 启用文件类型检测
filetype plugin on " 启用文件类型插件
filetype indent on " 启用文件类型缩进规则
syntax on " 启用语法高亮
" --- 界面设置 ---
set number " 显示绝对行号
set relativenumber " 显示相对行号(当前行显示绝对行号,其他行显示相对距离)
set cursorline " 高亮当前行
set showmatch " 高亮匹配的括号/引号
set ruler " 右下角显示光标位置(行号,列号)
set showcmd " 右下角显示正在输入的命令(如按 dd 时显示 "dd")
set showmode " 左下角显示当前模式(-- INSERT -- 等)
set laststatus=2 " 始终显示状态栏
set wildmenu " 命令行补全增强(Tab 补全时显示菜单)
set title " 终端标题显示文件名
" --- 搜索设置 ---
set hlsearch " 高亮所有搜索结果
set incsearch " 增量搜索(输入时实时显示匹配)
set ignorecase " 搜索默认忽略大小写
set smartcase " 智能大小写:搜索词有大写时区分大小写
" --- 缩进设置 ---
set autoindent " 自动缩进(保持上一行缩进级别)
set smartindent " 智能缩进(根据语法自动调整)
set tabstop=4 " Tab 显示为 4 个空格的宽度
set softtabstop=4 " 编辑时 Tab 键产生 4 个空格
set shiftwidth=4 " >> / << / == 缩进使用 4 个空格
set expandtab " 按 Tab 键时插入空格而非制表符
set smarttab " 行首按 Tab 插入 shiftwidth 个空格
" --- 编码设置 ---
set encoding=utf-8 " Vim 内部编码
set fileencodings=utf-8,gbk,gb2312,cp936,latin1 " 打开文件时的编码检测顺序
set fileformat=unix " 默认使用 Unix 换行符(LF)
set fileformats=unix,dos,mac " 自动检测换行符类型
" --- 编辑行为 ---
set backspace=indent,eol,start " 允许退格键跨行、跨缩进删除
set history=1000 " 保存 1000 条命令历史和搜索历史
set undofile " 持久化撤销历史(关闭文件后再打开仍可撤销)
set undodir=~/.vim/undodir " 撤销文件存储目录
set scrolloff=3 " 光标距离屏幕顶部/底部至少保留 3 行
set sidescrolloff=5 " 光标距离屏幕左/右侧至少保留 5 列
set wrap " 自动换行(长行折行显示)
set linebreak " 在单词边界换行(不打断单词)
set display+=lastline " 尽可能显示最后一行的内容
set hidden " 允许不保存就切换缓冲区
set confirm " 退出时如果有未保存文件,弹出确认对话框
set autoread " 文件被外部修改时自动重新加载
" --- 状态栏格式 ---
set statusline=%F%m%r%h%w\ [%{&ff}]\ [%Y]\ [pos=%l,%v]\ [%p%%]
" --- 快捷键映射 ---
" 去掉搜索高亮(按两次 leader 键)
nnoremap <leader><leader> :nohlsearch<CR>
" 将 jk 映射为 Esc(快速退出插入模式)
inoremap jk <Esc>
" 分屏切换(不需要按 Ctrl+w)
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
" --- Leader 键设置 ---
let mapleader=" " " 将 leader 键设为空格(默认是 \)
" --- 配色方案 ---
colorscheme desert " 使用 desert 配色(vim 自带)
" 终端支持 256 色时启用
if &term =~ "256color"
set t_Co=256
endif10.2 按需加载的配置(条件配置)#
" 只在编辑 Python 文件时生效
autocmd FileType python setlocal tabstop=4 shiftwidth=4 expandtab
" 只在编辑 Markdown 时自动换行
autocmd FileType markdown setlocal wrap linebreak
" 保存文件时自动删除行尾空白
autocmd BufWritePre * :%s/\s\+$//e
" 记住上次打开时的光标位置
autocmd BufReadPost *
\ if line("'\"") >= 1 && line("'\"") <= line("$") |
\ execute "normal! g`\"" |
\ endif10.3 配置文件生效#
# 创建配置目录和文件
mkdir -p ~/.vim/undodir
vim ~/.vimrc
# 让配置立即生效(在 vim 中执行)
:source ~/.vimrc
# 或者重新打开 vim11. 核心总结:6个必记快捷键#
讲师建议初学者只需记住以下6个快捷键即可初步使用 vi。这6个键覆盖了编辑文件的最基本需求。
| # | 快捷键 | 分类 | 作用 | 说明 |
|---|---|---|---|---|
| 1 | i | 模式切换 | 进入插入模式 | 按 i 后可以像普通编辑器一样输入文字 |
| 2 | Esc | 模式切换 | 回到一般模式 | 任何时候不确定,连续按几次 Esc 回到安全状态 |
| 3 | : | 模式切换 | 进入命令行模式 | 输入保存、退出、搜索等命令 |
| 4 | x | 修改 | 删除光标处字符 | 相当于 Delete 键,在一般模式下使用 |
| 5 | :wq! | 保存退出 | 强制保存并退出 | write quit! 保存所有修改后退出 |
| 6 | :q! | 退出 | 强制不保存退出 | quit! 放弃所有修改,直接退出 |
这6个快捷键覆盖了:
- 模式切换(i / Esc / :) – 学会切换模式是使用 vi 的第一步
- 修改(x) – 最基本的删除操作
- 保存/退出(:wq! / :q!) – 编辑完成后最重要的事
进阶建议:在掌握这6个快捷键后,逐步学习以下命令,每次学1-2个:
第二轮学习:u(撤销) dd(删除行) yy(复制行) p(粘贴)
第三轮学习:v(可视模式) /text(查找) :%s/old/new/g(替换)
第四轮学习:qa...q(宏) :split(分屏) Ctrl+w w(窗口切换)12. 常见操作场景#
场景一:批量替换配置项#
# 编辑配置文件,将 localhost 统一改为生产地址
vim config.ini
:%s/localhost/prod-server.example.com/gc # g=全部替换, c=每次确认
:wq场景二:提取日志中的错误行#
vim app.log
# 查找所有包含 ERROR 的行
/ERROR
n # 逐个查看
# 或使用全局命令收集错误行
:g/ERROR/ # 列出所有包含 ERROR 的行场景三:整理数据文件#
# 有一个 CSV 数据文件,需要删除所有空行
vim data.csv
:g/^$/d # 删除所有空行(^$ = 行首紧跟行尾 = 空行)
:wq场景四:对比两个配置文件差异#
vim -d old.conf new.conf # vimdiff 模式
# 在分屏对比界面中:
]c # 跳到下一个差异处
[c # 跳到上一个差异处
do # 将另一窗口的差异复制到当前窗口(diff obtain)
dp # 将当前窗口的差异推送到另一窗口(diff put)
:qa # 退出所有窗口场景五:快速格式化代码缩进#
vim script.py
gg # 跳到文件开头
=G # 格式化从当前行到文件末尾的缩进(= 是格式化命令)
# 或选中后再格式化:
ggVG # 全选:gg 跳到开头,V 行选择,G 跳到末尾
= # 格式化选中区域13. 初学者常见问题 FAQ#
Q1: 按 u 撤销后想恢复,但按 u 又撤销了撤销?
A: 这是因为你用的是 vi(或 Ubuntu 的 vim.tiny),它只支持单次撤销。按 u 撤销后如果再按 u,会"撤销撤销",相当于重做。安装完整版 vim 后可以用 Ctrl+r 重做。
Q2: 复制了一行(yy),删了一行(dd),粘贴 p 出来的是删除的内容?
A: 这是无名寄存器("")的问题。删除操作会覆盖复制的内容。使用 "0p(从复制专用寄存器粘贴)就能得到你复制的那一行。或者用命名寄存器:"ayy 复制到 a,"ap 从 a 粘贴。
Q3: 从浏览器复制的内容粘贴到 vim 里缩进全乱了?
A: 这是自动缩进造成的。在粘贴前输入 :set paste 进入粘贴模式,粘贴完再 :set nopaste 退出。快捷方法:如果是系统剪贴板,使用 "+p 或 "*p 粘贴。
Q4: 可视模式选中文本后按 y 复制了,怎么在系统其他地方(如浏览器)粘贴? A: 默认情况下 vim 的 y 只复制到 vim 内部寄存器,不会同步到系统剪贴板。解决方法:
- 使用
"+y复制到系统剪贴板,然后在其他程序中Ctrl+v粘贴 - 或在 .vimrc 中配置:
set clipboard=unnamedplus让 y/p 自动使用系统剪贴板
Q5: 录制宏时出错了怎么处理?
A: 按 q 停止当前录制。如果已经录制完但执行效果不对,直接重新录制到同一个寄存器即可覆盖(qa ... q)。
Q6: 分屏后怎么退出其中一个窗口?
A: 在要退出的窗口中输入 :q 即可。如果想关闭其他所有窗口只保留当前窗口::only 或 Ctrl+w o。强制退出所有::qa!。
Q7: :wq 和 :x 有什么区别?
A: :wq 总是写入文件再退出(会更新文件修改时间)。:x 仅在文件有修改时才写入。对于脚本和自动化场景,:x 更合理,因为它不会无故更新文件时间戳。
注意事项#
- 撤销次数 – vi 只支持单次撤销,完整版 vim 才支持多级撤销(u)+ 重做(Ctrl+r)。建议安装完整版 vim
- 大小写影响粘贴位置 – 小写 p 贴到光标后/行下,大写 P 贴到光标前/行上。复制整行时区分上下,复制部分文字时区分前后
- 删除即剪切 – vim 中 dd、dw、x 等删除操作的内容会被存入寄存器,相当于剪贴功能
- 无名寄存器的陷阱 – 复制 yy 后再删除 dd,p 粘贴出来的是删除的内容而不是复制的内容。使用
"0p或命名寄存器规避 - 系统剪贴板需额外配置 – 要检查
vim --version | grep clipboard看是否有 +clipboard 支持,没有则安装 vim-gtk3 - 搜索结果高亮 – vi 不支持,完整 vim 才支持。在 vim 中通过
:set hlsearch开启 - :q! vs :wq! –
:q!不保存强制退出,:wq!保存后强制退出。!表示强制执行(即使有只读等限制) - :!command – 可在不退出 vim 的情况下执行终端命令,执行完后按回车返回编辑界面
- .vimrc 配置 – 修改配置后,通过
:source ~/.vimrc让新配置立即生效,无需重启 vim - 宏录制建议 – 录制宏时使用相对移动(j/k/w/b),避免使用绝对移动(gg/G/nG),确保宏可复用在任意位置
课后延伸#
- 练习 vim 的撤销(u)和重做(Ctrl+r),感受多级撤销的便利
- 尝试用
:%s/old/new/gc进行全文替换,体会 c 标志的确认交互 - 用
:split和:vsplit分屏练习,掌握 Ctrl+w 系列窗口切换快捷键 - 录制一个简单的宏(如给多行代码添加注释),并用
@回放 - 检查系统剪贴板支持:
vim --version | grep clipboard,必要时安装 vim-gtk3 - 完善自己的
~/.vimrc配置文件,添加本章介绍的实用设置项 - 下一讲预告:《第13讲 - Shell脚本编程(上)》
附录:命令速查表#
A. 删除命令速查#
| 命令 | 作用 |
|---|---|
| x / X | 删除光标处 / 前一个字符 |
| dw | 删除到下一个单词开头 |
| daw / diw | 删除整个单词(含/不含前后空格) |
| dd | 删除当前行 |
| ndd | 删除 n 行 |
| D / d$ | 删除到行尾 |
| d0 / d^ | 删除到行首 |
| di( / da( | 删除括号内/含括号内容 |
B. 复制粘贴速查#
| 命令 | 作用 |
|---|---|
| yy | 复制当前行 |
| nyy | 复制 n 行 |
| yw / yaw | 复制一个单词 / 整个单词 |
| y$ / y0 | 复制到行尾 / 行首 |
| p / P | 粘贴到光标后 / 前(行下 / 行上) |
"+y / "+p | 复制/粘贴到系统剪贴板 |
"0p | 粘贴最近复制的内容(不受删除影响) |
C. 可视模式速查#
| 命令 | 作用 |
|---|---|
| v | 字符选择模式 |
| V | 行选择模式 |
| Ctrl+v | 块选择模式 |
| v + 移动 + d | 选中并删除 |
| v + 移动 + y | 选中并复制 |
D. 搜索替换速查#
| 命令 | 作用 |
|---|---|
| /text / ?text | 向后/向前搜索 |
| n / N | 下一个/上一个匹配 |
| * / # | 搜索光标所在单词(向前/向后) |
:s/old/new/ | 替换当前行第一个匹配 |
:s/old/new/g | 替换当前行所有匹配 |
:%s/old/new/g | 替换全文所有匹配 |
:%s/old/new/gc | 替换全文,每次确认 |
E. 分屏速查#
| 命令 | 作用 |
|---|---|
:sp / :vs | 水平/垂直分屏 |
| Ctrl+w h/j/k/l | 切换到左/下/上/右窗口 |
| Ctrl+w w | 循环切换窗口 |
| Ctrl+w = | 均分窗口大小 |
:q / :only | 关闭窗口 / 仅保留当前窗口 |
F. 宏录制速查#
| 命令 | 作用 |
|---|---|
| qa | 开始录制到寄存器 a |
| q | 结束录制 |
| @a | 回放寄存器 a 的宏 |
| @@ | 重复上一次回放 |
| n@a | 执行宏 n 次 |
G. 文件操作速查#
| 命令 | 作用 |
|---|---|
:w | 保存 |
:q | 退出 |
:q! | 强制退出不保存 |
:wq / :x | 保存退出 |
:w filename | 另存为 |
:r filename | 读取文件插入 |
:!command | 执行外部命令 |
