Vim 进阶教程
文本替换 (:s
)
这是 Vim
中最强大和最常用的进阶功能之一。
基本语法: :[range]s/old/new/[flags]
-
[range]
: 指定替换操作的范围。省略时默认为当前行。-
%
:整个文件 (例如:%s/old/new/
) -
5,10
:第5
行到第10
行 (例如:5,10s/old/new/
) -
.,$
:从当前行到文件末尾 (例如:.,$s/old/new/
) -
.+1,$-1
:从当前行下一行到文件倒数第二行 -
/pattern1/,/pattern2/
:从匹配pattern1
的行到匹配pattern2
的行 -
'<,'>
:当前选中的可视区域(在可视模式下按:
后自动填充)
-
-
s
: substitute (替换) 命令。 -
old
: 要被替换的文本(模式)。支持正则表达式! (这是它强大的核心) -
new
: 替换成的新文本。 -
[flags]
: 控制替换行为的标志(可选,可组合使用)。-
g (global)
: 对一行内的所有匹配项进行替换(默认只替换一行中的第一个匹配项)。非常重要! -
c (confirm)
: 每次替换前要求确认。按y
替换,n
跳过,a
替换所有,q
退出替换。 -
i (ignore case)
: 忽略大小写进行匹配。 -
I (no ignore case)
: 区分大小写进行匹配(默认行为)。 -
e (no errors)
: 如果old
没有匹配项,不报错(抑制错误信息)。
-
常见示例:
-
替换当前行第一个
foo
为bar
::s/foo/bar/
-
替换当前行所有
foo
为bar
::s/foo/bar/g
-
替换整个文件中所有
foo
为bar
(全局替换)::%s/foo/bar/g
-
替换第 10 行到第 20 行所有
foo
为bar
::10,20s/foo/bar/g
-
替换整个文件中所有
foo
为bar
,但每次替换前确认::%s/foo/bar/gc
-
将文件中所有
color
或colour
替换为hue
(忽略大小写)::%s/colou\?r/hue/gi
(这里\?
表示前面的u
可有可无,i
忽略大小写) -
删除所有行尾的空白字符:
:%s/\s\+$//g
(\s\+
匹配一个或多个空白字符,$
匹配行尾) -
删除所有行首的空白字符:
:%s/^\s\+//g
(^
匹配行首) -
将
"name"
替换为'name'
::%s/"$$[^"]*$$"/'\1'/g
(使用捕获组$$...$$
和反向引用\1
) -
在变量名后添加
_v2
(捕获组\1
)::%s/\<\(\w\+\)\>/\1_v2/g
重要提示:
-
正则表达式是核心: 要充分利用
:s
,必须学习基础的正则表达式 (Vim
使用自己的变种,但基础与其他类似)。 -
分隔符
/
可替换: 如果old
或new
中包含/
,可以用其他字符作为分隔符,如:s#old#new#g
或:s@old@new@g
。 -
先确认 (
c
标志): 对于全局替换 (:%s/...
),尤其是在生产代码中,强烈建议使用c
标志先检查确认。 -
查看匹配: 在输入
:s/old
后,按Ctrl-R Ctrl-W
(在命令模式下) 可以将光标下的单词插入到命令中。在替换前使用/old
搜索一下,用:nohl
取消高亮,可以直观看到哪些地方会被匹配。
批量操作/多文件操作
多行编辑(可视化块模式)
结合 Ctrl + v
(垂直选中)实现批量添加 / 删除前缀 / 后缀:
-
批量给多行添加前缀(如注释符号
//
):-
按
Ctrl + v
进入垂直选择模式 -
移动光标选中需要操作的行(如向下按
j
选 5 行) -
按
I
(大写I
,进入插入模式),输入前缀(如//
) -
按
ESC
,所有选中行都会添加前缀
-
-
批量删除多行前缀:
-
Ctrl + v
选中需要删除的前缀列(如前 2 个字符) -
按
d
直接删除选中的列
-
argdo / bufdo / windo / tabdo:
-
这些命令允许在多个参数列表文件(
argdo
)、缓冲区(bufdo
)、窗口(windo
)、标签页(tabdo
) 上执行相同的Ex
命令。 -
示例:
-
打开多个文件:
vim *.txt
-
在所有打开的
.txt
文件中替换old
为new
::argdo %s/old/new/ge | update
-
%s/old/new/ge
:在每个文件内执行全局替换 (g
),忽略错误 (e
防止没有匹配的文件报错退出)。 -
| update
:管道符|
连接命令,update
仅在文件被修改过时才保存。
-
-
在所有打开的缓冲区中执行替换并保存:
:bufdo %s/old/new/ge | w
-
-
注意:
argdo
操作的是:args
列表中的文件,bufdo
操作的是所有加载到缓冲区的文件。
:vimgrep / :grep:
-
在整个项目文件中搜索包含特定模式的行。
-
:vimgrep /pattern/[j][g] file(s)
-
/pattern/
:搜索模式(支持Vim
强大的正则)。 -
[j]
:不跳转到第一个匹配项(静默搜索)。 -
[g]
:每行只列出一次匹配(默认列出每行的所有匹配)。 -
file(s)
:文件模式,如**/*.py
递归搜索所有.py
文件。 -
示例:
:vimgrep /TODO/ **/*.py
(在所有.py
文件中搜索"TODO"
)
-
-
搜索结果会填充到
quickfix
列表 (:copen
打开列表,:cclose
关闭,:cn
下一个,:cp
上一个)。 -
结合
:cdo
/:cfdo
:-
:cdo command
:对quickfix
列表中的每一行执行命令 (光标会移动到对应行)。 -
:cfdo command
:对quickfix
列表中的每一个文件执行命令 (光标会移动到对应文件)。 -
强大示例: 在所有包含
"TODO"
的.py
文件中,将"TODO"
替换为"FIXME"
::vimgrep /TODO/ **/*.py
-
:cfdo %s/TODO/FIXME/ge | update
-
对每个匹配文件 (
:cfdo
) 执行全局替换 (%s/.../g
),忽略错误 (e
),修改才保存 (update
)。
-
-
宏录制 (q):
-
录制:
q + <register>
(例如qa
) 开始录制到寄存器a
-> 执行你的操作序列 ->q
停止录制。 -
播放:
@ + <register>
(例如@a
) 播放寄存器a
中的宏。@@
重复播放上一次播放的宏。 -
批量播放: 结合行号或可视选择。
-
:10,20 normal @a
:对第 10 行到第 20 行的每一行,在普通模式下执行寄存器a
中的宏。 -
在可视模式下选中多行,然后按
:
,会自动填充为:'<,'>
,然后输入normal @a
。
-
-
示例: 给一组连续的行添加注释 (
//
):-
将光标移动到第一行的行首。
-
qa
开始录制到a
。 -
I// <Esc>
:进入插入模式,输入//
,退出插入模式。 -
j
:移动到下一行。 -
q
:停止录制。 -
按
@a
对当前行执行宏(添加注释并下移一行)。 -
按
5@a
重复执行 5 次宏(给接下来的 5 行添加注释)。或者用jVG
选中剩余行,然后:'<,'>normal @a
。
-
其他高级技巧
重复操作(.命令)
.
可以重复上一次的编辑操作,是 Vim
最被低估的技巧之一:
-
例 1:删除一行后,按
.
会重复删除下一行 -
例 2:在某行末尾添加
;
,按.
会在其他行末尾重复添加
快速跳转与定位
-
按内容跳转:
-
*
:向下跳转到当前单词的下一个匹配 -
#
:向上跳转到当前单词的上一个匹配
-
-
跳转到上次编辑位置:
-
''
(两个单引号):跳回上一次跳转前的位置 -
.
(点符号):跳转到上次编辑的位置
-
global 命令 (:g):
-
对匹配特定模式的行执行命令。
-
语法:
:[range]g/pattern/command
-
示例:
-
删除所有空行:
:g/^$/d
(匹配行首^
紧接着行尾$
的行,即空行,执行d
删除)。 -
删除所有包含
DEBUG
的行::g/DEBUG/d
-
将所有包含
TODO
的行复制到文件末尾::g/TODO/t$
(t
是copy
的缩写,$
表示文件末尾)。 -
在包含
function
的行前面添加注释::g/function/normal O// TODO: Implement
-
全局反向操作(:vglobal)
:v/^$/d
:删除所有非空行
寄存器 (") 的高级使用:
寄存器 | 含义 |
---|---|
" | 默认寄存器,存放最近一次的删除或复制 |
0 | 存放最近一次的复制(y 命令) |
1–9 | 最近 9 次删除操作 (滚动存放) |
a–z | 用户自定义寄存器,可用 "ayy 复制到 a |
/: | 存放最近一次的搜索模式 |
-
指定寄存器: 在操作命令前加上
"<register>
。-
"ayy
:复制当前行到寄存器a
。 -
"bdd
:删除当前行到寄存器b
(剪切)。 -
"ap
:粘贴寄存器a
的内容。
-
-
查看寄存器内容:
:reg
或:reg <register>
(如:reg a
)。 -
系统剪贴板 (
"+ / "*
): 设置了clipboard=unnamed
,通常"+
和"*
都指向系统剪贴板。显式使用:-
"+yy
:复制当前行到系统剪贴板。 -
"+p
:粘贴系统剪贴板内容到Vim
。
-
-
只读寄存器:
-
"%
:当前文件名。 -
".
:上次插入的文本。 -
":
:上次执行的命令。 -
"/
:上次搜索的模式。
-
折叠代码
-
zc
:折叠当前代码块(如函数、循环) -
zo
:展开当前折叠块 -
zR
:展开所有折叠 -
zM
:折叠所有代码块
(需先设置折叠方式:set foldmethod=indent
按缩进折叠,或 set foldmethod=syntax
按语法折叠)
显示不可见字符
查看空格、制表符、换行符等:
:set list " 显示不可见字符($表示换行,^I表示制表符)
:set nolist " 关闭显示
标记 (Marks):
-
快速跳转到文件中的特定位置。
-
设置标记:
m + <letter>
(例如ma
设置标记a
)。 -
跳转到标记:
` + <letter>
(反引号,例如 `a 精确跳转到标记 a 的行和列) 或
' + <letter>
(单引号,例如 'a 跳转到标记 a 所在行的行首)。
-
查看标记:
:marks
。 -
特殊标记:
-
``:跳回上次跳转前的位置。
-
'.:上次修改的行。
-
'^:上次插入模式退出的位置。
-
会话管理 (Sessions)
- 保存会话(打开的文件、窗口布局等):
:mksession ~/session.vim
- 恢复会话:
vim -S ~/session.vim
外部命令与管道
- 在
Vim
中执行shell
命令并将结果导入缓冲区:
:r !ls -l
- 对选中区域执行外部命令:
:'<,'>!sort
将选区内内容按 sort
排序。
自动命令 (autocmd):
-
在特定事件发生时自动执行命令,用于高度定制
Vim
行为(如文件类型检测、保存时自动格式化等)。这属于更高级的.vimrc
配置。 -
基本示例 (在
.vimrc
中):
" 当打开或新建 .py 文件时设置缩进
autocmd BufNewFile,BufRead *.py setlocal tabstop=4 shiftwidth=4 expandtab
" 保存 .py 文件前自动删除行尾空白
autocmd BufWritePre *.py :%s/\s\+$//e
窗口和标签页管理:
-
分割窗口:
-
:split / :sp [filename]
:水平分割当前窗口(或打开文件)。 -
:vsplit / :vsp [filename]
:垂直分割当前窗口(或打开文件)。 -
Ctrl-w s
:水平分割。 -
Ctrl-w v
:垂直分割。 -
Ctrl + w + =
:让所有分屏高度 / 宽度相等
-
-
窗口间跳转:
Ctrl-w h/j/k/l
/Ctrl-w w
(循环)。 -
关闭窗口:
:close
/Ctrl-w c
。 -
调整窗口大小:
Ctrl-w +
/Ctrl-w -
(高度),Ctrl-w >
/Ctrl-w <
(宽度)。 -
标签页:
-
:tabnew [filename]
:在新标签页打开文件。 -
:tabclose
:关闭当前标签页。 -
:tabnext / gt
:下一个标签页。 -
:tabprevious / gT
:上一个标签页。 -
:tabm [n]
:移动当前标签页到位置n
(从 0 开始计数)。
-
命令行窗口 (q:):
-
普通模式下按
q:
打开命令行窗口。这里显示命令历史,可以像编辑普通文本一样浏览、修改历史命令,然后按回车执行选中的命令。非常方便修改复杂命令(如带复杂正则的:s
命令)。 -
表达式寄存器 (
=
):- 在插入模式下按
Ctrl-r =
,可以输入一个 Vim 表达式(如2+2
或@a
),计算结果会插入到文本中。高级用法可以结合函数。
- 在插入模式下按
-
normal
命令 (:normal
):-
在命令行模式下执行普通模式的命令序列。
-
示例:
-
在当前行执行宏
a
::normal @a
-
在选中的行(可视模式后)删除行首空白:
:'<,'>normal ^dW
(先跳到行首非空字符^
,然后删除一个单词dW
,这里空白被当作一个单词)。
-
-
-
符号自动补全 (
Ctrl-x
系列):-
在插入模式下:
-
Ctrl-x Ctrl-l
:整行补全。 -
Ctrl-x Ctrl-f
:文件名补全。 -
Ctrl-x Ctrl-o
:全能 (Omni
) 补全(需要文件类型支持,如编程语言)。 -
Ctrl-n / Ctrl-p
:使用当前缓冲区中的单词补全。
-
-
-
自动缩进 (
=
):-
在可视模式下选中代码块,按
=
会自动缩进(根据文件类型和你的indent
设置)。 -
gg=G
:对整个文件进行自动缩进 (gg
到文件头,=
缩进操作,G
到文件尾)。
-
高级配置技巧(需修改.vimrc)
高效搜索
-
set incsearch
:输入搜索词时实时高亮匹配 -
set hlsearch
:高亮所有搜索结果,用:nohl
临时关闭高亮
文件管理
-
set autochdir
:自动切换工作目录到当前文件位置 -
set wildmenu
:增强文件名补全(按Tab
循环选择)
备份与撤销
set undodir=\~/.vim/undo
:持久化撤销历史(支持关闭文件后仍可撤销)
代码格式化
-
filetype indent on
:根据文件类型自动缩进 -
set tabstop=4
:设置Tab
为4空格
插件推荐(进阶工具)
-
多文件搜索:
fzf.vim
(模糊搜索文件/内容) -
批量注释:
vim-commentary
(gc
快速注释) -
环绕编辑:
vim-surround
(cs"'
替换双引号为单引号) -
自动补全:
coc.nvim
(LSP
支持) -
项目目录树浏览、文件管理。
nerdtree
-
实时显示
Git diff
(新增、修改、删除行)vim-gitgutter / signify
其他示例
将项目中的 user_id 改为 user_id_new:
- 精确全文替换:
:%s/\<user_id\>/user_id_new/gc
- 如果涉及多个文件:
:argdo %s/\<user_id\>/user_id_new/ge | update
关键点:
-
\<
和\>
匹配单词边界(避免匹配_user_id_old
) -
/e
屏蔽未匹配时的报错 -
| update
只保存修改过的文件