Vim 的高级功能不应该理解成“更多快捷键”。它们的价值在于把重复文本操作变成可组合、可回放、可自动化的编辑流程。正则、宏、批量替换、Quickfix、FZF、tmux 这些能力,真正服务的是工程现场里的重复修改、批量排查和远程编辑。
1. 高级技巧
高级文本操作
正则表达式
| 功能 | 命令或表达式 | 说明 |
|---|---|---|
| 向前搜索 | /pattern | 向前搜索匹配的模式 |
| 向后搜索 | ?pattern | 向后搜索匹配的模式 |
| 全文替换 | :%s/pattern/replacement/g | 全文替换所有匹配的模式 |
| 当前行替换 | :s/pattern/replacement/g | 替换当前行所有匹配的模式 |
| 删除行首空白 | :%s/^\s\+//g | 删除每行开头的空白字符 |
| 删除行尾空白 | :%s/\s\+$//g | 删除每行结尾的空白字符 |
| 匹配任意字符 | . | 匹配任意字符 |
| 匹配数字字符 | \d | 匹配数字字符 |
| 匹配非数字字符 | \D | 匹配非数字字符 |
| 匹配字母或数字字符 | \w | 匹配字母或数字字符 |
| 匹配非字母或数字字符 | \W | 匹配非字母或数字字符 |
| 匹配行首 | ^ | 匹配行首 |
| 匹配行尾 | $ | 匹配行尾 |
多行编辑
| 功能 | 命令 | 说明 |
|---|---|---|
| 行可视模式 | V | 进入行可视模式 |
| 字符可视模式 | v | 进入字符可视模式 |
| 块可视模式 | Ctrl+v | 进入块可视模式 |
| 在每行开头添加 | :%s/^/#/ | 使用正则表达式在每行开头添加 # |
| 在每行结尾添加 | :%s/$/;/ | 使用正则表达式在每行结尾添加 ; |
宏录制与播放
| 功能 | 命令 | 说明 |
|---|---|---|
| 录制宏 | qx ... q | 开始录制宏,x 是寄存器名,执行一系列命令后停止录制 |
| 播放宏 | @x | 播放寄存器 x 中的宏 |
| 重复播放宏 | @@ | 重复播放上一个宏 |
| 多次播放宏 | 10@x | 播放寄存器 x 中的宏 10 次 |
VimScript
ℹ️ 如果使用 Neovim,推荐优先使用 Lua 而非 VimScript 编写配置。
基本语法
VimScript 是 Vim 的脚本语言,用于扩展和定制 Vim 的功能。它适合维护传统 Vim 配置和轻量自动化;如果主要使用 Neovim,新配置优先考虑 Lua。以下语法用于读懂既有配置,而不是鼓励无限扩写脚本:
" 这是一个注释
" 变量
let myvar = 42 " 整数变量
let mystr = "Hello" " 字符串变量
" 条件语句
if myvar > 0
echo "Positive"
elseif myvar == 0
echo "Zero"
else
echo "Negative"
endif
" 循环语句
let i = 0
while i < 5
echo i
let i += 1
endwhile
for item in [1, 2, 3, 4, 5]
echo item
endfor函数和变量
" 定义函数
function! MyFunction(arg)
echo a:arg
endfunction
" 调用函数
call MyFunction("Hello")
" 局部变量
function! MyFunction()
let l:localVar = "I am local"
echo l:localVar
endfunction
" 全局变量
let g:globalVar = "I am global"
echo g:globalVar编写和调试简单的 VimScript 脚本
编写脚本:
将 VimScript 代码写入 .vim 文件,例如 myplugin.vim:
" myplugin.vim
function! SayHello()
echo "Hello, Vim!"
endfunction
command! SayHello call SayHello()加载脚本:
将脚本放入 Vim 的 plugin 目录,启动 Vim 自动加载:
mkdir -p ~/.vim/plugin
cp myplugin.vim ~/.vim/plugin/调试脚本:
使用 echo 命令输出调试信息:
echo "Debug info: " . someVar使用 :messages 查看所有输出信息。
自动化
使用自动命令
自动命令(autocommand)允许在特定事件发生时自动执行命令,例如文件保存、打开等。
augroup MyAutoCmd
autocmd!
autocmd BufWritePost *.txt :echo "Text file saved!"
augroup END| 事件 | 说明 | 权重 |
|---|---|---|
BufReadPost | 文件读取后 | 5 |
BufWritePost | 文件写入后 | 5 |
BufNewFile | 新建文件 | 4 |
FileType | 文件类型检测 | 5 |
BufEnter | 缓冲区进入 | 4 |
BufLeave | 缓冲区离开 | 4 |
VimEnter | Vim 启动后 | 5 |
VimLeave | Vim 退出前 | 5 |
WinEnter | 窗口进入 | 3 |
WinLeave | 窗口离开 | 3 |
配置文件模板
在 ~/.vim/templates/ 目录中创建模板文件,例如 python_template.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on <++>
@author: <++>
"""
def main():
pass
if __name__ == "__main__":
main()使用自动命令应用模板:
augroup MyTemplates
autocmd!
autocmd BufNewFile *.py 0r ~/.vim/templates/python_template.py
augroup END2. 高效工作流
版本控制集成
使用 Vim-fugitive
安装 vim-fugitive:
在 vimrc 文件中添加以下内容(以 vim-plug 为例):
call plug#begin('~/.vim/plugged')
Plug 'tpope/vim-fugitive'
call plug#end()基本用法:
| 功能 | 命令 | 说明 |
|---|---|---|
| 查看 Git 状态 | :Gstatus | 打开一个新窗口显示当前 Git 仓库的状态。可以在该窗口中导航和操作。 |
| Git 添加 | - | 在 :Gstatus 窗口中,将光标移动到文件名上,按 - 号将文件添加到索引。 |
| Git 提交 | :Gcommit | 打开一个新的缓冲区输入提交信息,完成后保存并关闭缓冲区即可提交。 |
| Git 推送 | :Gpush | 将本地提交推送到远程仓库。 |
| Git 拉取 | :Gpull | 从远程仓库拉取最新的代码。 |
| Git 日志 | :Glog | 显示 Git 提交日志,可以在日志中导航和查看每个提交的详细信息。 |
| Git 分支 | :Gbranch | 显示和管理 Git 分支。 |
常用 Git 命令
在 Vim 中,使用 vim-fugitive 可以执行常见的 Git 命令。同时你也可以在 Vim 外部使用 Git 命令行工具:
| 功能 | 命令 | 说明 |
|---|---|---|
| 克隆仓库 | git clone <repository_url> | 克隆一个远程仓库到本地。 |
| 查看状态 | git status | 查看当前仓库的状态。 |
| 添加文件 | git add <file> | 添加文件到索引。 |
| 提交更改 | git commit -m "Commit message" | 提交已添加的更改。 |
| 推送到远程仓库 | git push | 将本地提交推送到远程仓库。 |
| 拉取最新代码 | git pull | 从远程仓库拉取最新的代码。 |
| 创建新分支 | git checkout -b <new_branch> | 创建一个新的分支并切换到该分支。 |
| 合并分支 | git merge <branch> | 将指定分支合并到当前分支。 |
项目管理
NERDTree
在 vimrc 文件中添加以下内容(以 vim-plug 为例):
call plug#begin('~/.vim/plugged')
Plug 'preservim/nerdtree'
call plug#end()打开/关闭 NERDTree
:NERDTreeToggle或者添加快捷键映射:
nnoremap <C-n> :NERDTreeToggle<CR>在 NERDTree 中导航
- 使用
j和k键上下移动 - 使用
o键打开文件或目录 - 使用
x键关闭目录
显示隐藏文件
:NERDTreeShowHidden配置项目相关设置
项目特定的 vimrc
在项目根目录下创建一个 .vimrc 文件,包含项目特定的 Vim 配置。然后在主 vimrc 中添加以下内容:
if filereadable("path/to/project/.vimrc")
source path/to/project/.vimrc
endif自动切换项目配置
可以使用 vim-rooter 插件自动切换项目根目录并加载项目特定的配置。在 vimrc 中添加以下内容:
call plug#begin('~/.vim/plugged')
Plug 'airblade/vim-rooter'
call plug#end()
let g:rooter_patterns = ['.git', '.hg', '.svn', 'Makefile']代码补全与调试
注意:YouCompleteMe 已停止维护。推荐替代:coc.nvim(Vim/Neovim 通用)或 nvim-cmp(Neovim 专用)。
注意:Deoplete 已停止维护。Neovim 用户推荐使用 nvim-cmp + LSP 配置替代。
Neovim 补全方案:nvim-cmp + LSP
Neovim 的现代补全方案基于内置 LSP 客户端和 nvim-cmp 插件:
安装 nvim-cmp(以 lazy.nvim 为例):
{
"hrsh7th/nvim-cmp",
dependencies = {
"hrsh7th/cmp-nvim-lsp", -- LSP 补全源
"hrsh7th/cmp-buffer", -- 缓冲区补全
"hrsh7th/cmp-path", -- 路径补全
"L3MON4D3/LuaSnip", -- 代码片段引擎
},
config = function()
local cmp = require("cmp")
cmp.setup({
mapping = cmp.mapping.preset.insert({
["<Tab>"] = cmp.mapping.select_next_item(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
}),
sources = {
{ name = "nvim_lsp" },
{ name = "buffer" },
{ name = "path" },
},
})
end,
}配置 LSP 服务器(以 mason.nvim + mason-lspconfig.nvim 为例):
{
"williamboman/mason.nvim",
build = ":MasonUpdate",
},
{
"williamboman/mason-lspconfig.nvim",
config = function()
require("mason-lspconfig").setup({
ensure_installed = { "lua_ls", "pyright", "rust_analyzer", "ts_ls" },
})
end,
},
{
"neovim/nvim-lspconfig",
config = function()
local lspconfig = require("lspconfig")
lspconfig.lua_ls.setup({})
lspconfig.pyright.setup({})
end,
}Vimspector 代码调试
在 vimrc 文件中添加以下内容(以 vim-plug 为例):
call plug#begin('~/.vim/plugged')
Plug 'puremourning/vimspector'
call plug#end()基本配置:
.vimspector.json 文件,定义调试配置,例如:
{
"configurations": {
"Launch": {
"adapter": "debugpy",
"configuration": {
"request": "launch",
"program": "${workspaceFolder}/your_script.py",
"console": "integratedTerminal"
}
}
}
}使用:
-
启动调试会话:
:VimspectorLaunch -
设置断点:将光标移动到需要设置断点的行,按
F9键。 -
继续执行、单步执行和停止调试:使用
F5、F10、F11和F12键进行调试控制。
3. 性能优化
启动优化
延迟加载插件
延迟加载插件可以显著提高 Vim 的启动速度,只在需要时加载插件。
使用 vim-plug 进行延迟加载:
-
在
vimrc中配置延迟加载:call plug#begin('~/.vim/plugged') Plug 'tpope/vim-fugitive', { 'on': 'Gstatus' } Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } call plug#end()以上配置将 vim-fugitive 插件仅在执行
:Gstatus命令时加载,NERDTree 插件仅在执行:NERDTreeToggle命令时加载。
使用 lazy.nvim 插件管理器:
lazy.nvim 是一个专门用于延迟加载插件的插件管理器。
-
安装 lazy.nvim:
git clone https://github.com/folke/lazy.nvim.git ~/.vim/pack/lazy/start/lazy.nvim -
配置延迟加载:
call lazy#load_plugin('nerdtree', { 'on': 'NERDTreeToggle' })
精简配置文件
移除不必要的配置:
定期检查 vimrc 文件,移除不再使用的配置和插件,以减少 Vim 的启动时间和运行负担。
分离插件配置:
将插件的配置分离到独立的文件中,以保持 vimrc 简洁。例如,将 NERDTree 的配置放在 ~/.vim/plugin/nerdtree.vim 中:
" ~/.vim/plugin/nerdtree.vim
nnoremap <C-n> :NERDTreeToggle<CR>使用本地配置:
根据项目需求,在项目根目录下创建 .vimrc 或 .vim/ 目录,存放项目特定的配置文件,以避免在全局配置中添加过多内容。
系统集成
将 Vim 与 Tmux 结合使用
tmux 是一个终端复用器,允许你在一个终端窗口中运行多个会话,与 Vim 结合使用可以大大提高工作效率。
安装 tmux:
在 Linux 或 MacOS 中,可以使用包管理器安装 tmux:
sudo apt install tmux # Debian/Ubuntu
brew install tmux # macOS| 功能 | 命令 | 说明 |
|---|---|---|
| 启动 tmux 会话 | tmux | 启动一个新的 tmux 会话 |
| 新建会话 | tmux new -s session_name | 创建一个名为 session_name 的新会话 |
| 附加会话 | tmux attach -t session_name | 附加到一个名为 session_name 的会话 |
| 列出会话 | tmux ls | 列出所有 tmux 会话 |
| 杀死会话 | tmux kill-session -t session_name | 杀死一个名为 session_name 的会话 |
| 分离会话 | Ctrl-b d | 分离当前会话 |
| 新建窗口 | Ctrl-b c | 创建一个新窗口 |
| 切换窗口 | Ctrl-b n | 切换到下一个窗口 |
| 切换窗口 | Ctrl-b p | 切换到上一个窗口 |
| 重命名窗口 | Ctrl-b , | 重命名当前窗口 |
| 分割窗格 | Ctrl-b % | 垂直分割当前窗格 |
| 分割窗格 | Ctrl-b " | 水平分割当前窗格 |
| 切换窗格 | Ctrl-b o | 切换到下一个窗格 |
| 关闭窗格 | Ctrl-b x | 关闭当前窗格 |
| 同步窗格 | Ctrl-b :setw synchronize-panes on | 在所有窗格中同步输入 |
| 切换会话 | Ctrl-b s | 列出所有会话并切换 |
与 Vim 集成:
在 vimrc 中添加快捷键映射,方便与 tmux 交互:
nnoremap <silent> <Leader>h :TmuxNavigateLeft<CR>
nnoremap <silent> <Leader>j :TmuxNavigateDown<CR>
nnoremap <silent> <Leader>k :TmuxNavigateUp<CR>
nnoremap <silent> <Leader>l :TmuxNavigateRight<CR>需要安装 christoomey/vim-tmux-navigator 插件:
call plug#begin('~/.vim/plugged')
Plug 'christoomey/vim-tmux-navigator'
call plug#end()在终端中使用 Vim
在终端中使用 Vim 可以提高工作效率,特别是当你需要频繁切换编辑器和命令行时。
配置终端:
选择一个支持丰富功能的终端,例如 iTerm2(macOS)、Alacritty(跨平台)、GNOME Terminal(Linux)。
终端快捷键配置:
根据需要配置终端快捷键,方便打开 Vim。例如,在 iTerm2 中,可以设置快捷键快速打开新的终端窗口或标签,并启动 Vim。
Shell 集成:
在 ~/.bashrc 或 ~/.zshrc 中添加别名和函数,提高使用 Vim 的效率:
alias vi="vim"
alias svi="sudo vim"
alias vrc="vim ~/.vimrc"
# 快速打开项目目录中的 Vim
function vproj() {
cd ~/projects/$1 && vim
}使用 FZF 进行文件搜索:
FZF 是一个命令行模糊查找工具,可以与 Vim 集成,快速搜索和打开文件。
-
安装 FZF:
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf ~/.fzf/install -
在
vimrc中配置 FZF:call plug#begin('~/.vim/plugged') Plug 'junegunn/fzf' Plug 'junegunn/fzf.vim' call plug#end() " 使用 FZF 查找文件 nnoremap <Leader>f :Files<CR>
4. Neovim 生态简介
Neovim 在 Vim 基础上提供了更现代化的开发体验:
- LSP(Language Server Protocol):通过
:h lsp了解内置 LSP 支持,实现代码补全、跳转、重构等功能 - Tree-sitter:
:h treesitter提供更精确的语法高亮和代码折叠 - lazy.nvim:现代化的 Lua 配置管理方案,替代传统的 vim-plug
- telescope.nvim:强大的模糊查找器,替代 fzf/NERDTree
可以参考 LazyVim 或 kickstart.nvim 理解现代 Neovim 配置结构。是否采用整套发行版,要看自己是否愿意接受它的默认快捷键、插件边界和升级节奏。
5. 使用原则
高级功能最适合处理“重复但又不值得写正式脚本”的文本问题。
宏适合一次性批量编辑:例如给多行加序号、重复修改相似结构、整理临时数据。只要操作会反复复用,就应该考虑脚本或项目任务,而不是依赖一次性宏。
正则替换要先缩小范围:优先在可视选区、当前文件或明确模式里替换。全局 :%s 很强,也很容易误伤。
插件服务工作流,不服务收藏欲:FZF、Git 集成、tmux 导航、补全和诊断都应该对应明确场景。不能解释使用场景的插件,先不要加入配置。
性能问题从启动路径查起:如果 Vim/Neovim 变慢,先看插件数量、同步加载、外部命令和语言服务器,不要盲目重装。
保留纯文本环境能力:高级 Vim 技巧最大的价值,是在 SSH、容器、最小系统和远程排障里仍然能稳定修改文本。它不替代 IDE,但能让工程师不被 GUI 环境锁死。