跳过正文
  1. 文章/

第12讲:使用编辑器(下)

·10220 字·21 分钟
Euin
作者
Euin
这里记录我的技术笔记、学习心得与生活随笔。
目录
Linux 入门 - 这篇文章属于一个选集。
§ 2: 本文

视频时长: 18分10秒

概述
#

本节是 vi/vim 编辑器的进阶操作篇,承接上一讲(三种模式、光标移动、文本查找)的内容,继续深入讲解撤销与重做、删除剪切、复制粘贴、可视模式区块操作、命令行模式命令、搜索替换、分屏编辑、寄存器、宏录制以及 .vimrc 进阶配置。末尾保留了视频中总结的6个最常用快捷键,帮助初学者快速上手。

建议在阅读本节前,先通过 vimtutor 巩固上一讲的基础操作:

$ vimtutor

[TOC]

核心要点
#

1. 撤销与重做 (Undo & Redo)
#

撤销是编辑器中最重要的功能之一。vi 和 vim 在撤销机制上有本质区别。

1.1 vi 与 vim 的撤销差异
#

编辑器快捷键撤销次数说明
原始 viu仅一次按 u 撤销后再次按 u,会撤销"撤销",相当于来回切换
vimu (可多次)无限次可反复按 u 一直回退到文件打开时的状态
Ubuntu viu仅一次Ubuntu 中 vi 实际指向 vim.tiny(精简版),同样只支持单次撤销

如果想获得完整的多级撤销能力,建议安装完整版 vim:

$ sudo apt update
$ sudo apt install vim -y

1.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(          # 删除括号及参数 -> function

3. 复制与粘贴
#

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替换范围(行号、% 全文、.,$ 当前行到末尾等)
ssubstitute 命令
old要被替换的文本(支持正则表达式)
new替换后的文本
flags替换标志(g 全部替换、c 确认、i 忽略大小写等)

5.3 :s 命令常用形式
#

命令功能说明
:s/old/new/替换当前行第一个匹配的 old只替换当前行的第一个匹配
:s/old/new/g替换当前行所有匹配的 oldg = 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-关闭当前窗口
:onlyCtrl+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 -y

7.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
endif

10.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`\"" |
    \ endif

10.3 配置文件生效
#

# 创建配置目录和文件
mkdir -p ~/.vim/undodir
vim ~/.vimrc

# 让配置立即生效(在 vim 中执行)
:source ~/.vimrc

# 或者重新打开 vim

11. 核心总结:6个必记快捷键
#

讲师建议初学者只需记住以下6个快捷键即可初步使用 vi。这6个键覆盖了编辑文件的最基本需求。

#快捷键分类作用说明
1i模式切换进入插入模式按 i 后可以像普通编辑器一样输入文字
2Esc模式切换回到一般模式任何时候不确定,连续按几次 Esc 回到安全状态
3:模式切换进入命令行模式输入保存、退出、搜索等命令
4x修改删除光标处字符相当于 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 即可。如果想关闭其他所有窗口只保留当前窗口::onlyCtrl+w o。强制退出所有::qa!

Q7: :wq 和 :x 有什么区别? A: :wq 总是写入文件再退出(会更新文件修改时间)。:x 仅在文件有修改时才写入。对于脚本和自动化场景,:x 更合理,因为它不会无故更新文件时间戳。


注意事项
#

  1. 撤销次数 – vi 只支持单次撤销,完整版 vim 才支持多级撤销(u)+ 重做(Ctrl+r)。建议安装完整版 vim
  2. 大小写影响粘贴位置 – 小写 p 贴到光标后/行下,大写 P 贴到光标前/行上。复制整行时区分上下,复制部分文字时区分前后
  3. 删除即剪切 – vim 中 dd、dw、x 等删除操作的内容会被存入寄存器,相当于剪贴功能
  4. 无名寄存器的陷阱 – 复制 yy 后再删除 dd,p 粘贴出来的是删除的内容而不是复制的内容。使用 "0p 或命名寄存器规避
  5. 系统剪贴板需额外配置 – 要检查 vim --version | grep clipboard 看是否有 +clipboard 支持,没有则安装 vim-gtk3
  6. 搜索结果高亮 – vi 不支持,完整 vim 才支持。在 vim 中通过 :set hlsearch 开启
  7. :q! vs :wq!:q! 不保存强制退出,:wq! 保存后强制退出。! 表示强制执行(即使有只读等限制)
  8. :!command – 可在不退出 vim 的情况下执行终端命令,执行完后按回车返回编辑界面
  9. .vimrc 配置 – 修改配置后,通过 :source ~/.vimrc 让新配置立即生效,无需重启 vim
  10. 宏录制建议 – 录制宏时使用相对移动(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执行外部命令
Linux 入门 - 这篇文章属于一个选集。
§ 2: 本文

相关文章