Vim配置与技巧:语法高亮、折叠、宏、多文件
服务器上 SSH 环境编辑文件,nano 适合临时改配置,Vim 适合日常开发——改 Shell 脚本、调 R 代码、查看大日志。本文不讲 hjkl 基础操作,聚焦高频实战:语法高亮、代码折叠、宏录制、正则替换、多文件操作、NERDTree。
实测环境:Debian 12,Vim 9.1,终端 SSH 连接。
1. 基础配置——.vimrc
先把 Vim 从”能忍”变成”好用”。在 ~/.vimrc 里加上这几行:
" === 基础设置 ===set number " 显示行号set relativenumber " 相对行号(跳转时有奇效)set cursorline " 高亮当前行set showcmd " 右下角显示正在输入的命令set wildmenu " 命令模式Tab补全增强
" === 缩进(写脚本必备)===set autoindent " 自动缩进set smartindent " 智能缩进set tabstop=4 " Tab显示为4空格set shiftwidth=4 " 自动缩进4空格set expandtab " Tab转空格(Python/R必备!)set softtabstop=4
" === 搜索高亮 ===set hlsearch " 高亮搜索结果set incsearch " 边输入边搜索set ignorecase " 搜索忽略大小写set smartcase " 有大写字母时自动区分大小写
" === 其他 ===set encoding=utf-8 " 文件编码UTF-8set mouse=a " 鼠标可用(SSH下也支持)set clipboard=unnamed " 系统剪贴板syntax on " 语法高亮relativenumber 强烈推荐。它的效果:
3 # 上一行 2 # 上两行 1 # 上一行123 当前行的实际行号 1 # 下一行 2 # 下两行这时候你想跳到下面第 2 行,直接按 2j 就行——不用心算。
2. 生信文件类型的语法高亮
BED、GFF、FASTA、SAM——这些生信格式默认没有语法高亮。文件是纯文本,但有些列有特殊含义,高亮之后一眼能看出问题。
2.1 FASTA 语法高亮
" 加到 ~/.vimrcaugroup fasta_highlight autocmd! autocmd BufRead,BufNewFile *.fa,*.fasta,*.fna set filetype=fastaaugroup END然后创建 ~/.vim/syntax/fasta.vim:
" fasta.vim - FASTA 语法高亮if exists("b:current_syntax") finishendif
" 序列头(>开头)→ 蓝色粗体syntax match fastaHeader /^>.*/highlight fastaHeader ctermfg=Blue cterm=bold
" A → 绿色syntax match fastaA /A/ containedin=fastaSequencehighlight fastaA ctermfg=Green
" T → 红色syntax match fastaT /T/ containedin=fastaSequencehighlight fastaT ctermfg=Red
" G → 黄色syntax match fastaG /G/ containedin=fastaSequencehighlight fastaG ctermfg=Yellow
" C → 青色syntax match fastaC /C/ containedin=fastaSequencehighlight fastaC ctermfg=Cyan
" N → 灰色(表示不确定碱基)syntax match fastaN /N/ containedin=fastaSequencehighlight fastaN ctermfg=DarkGrey
" 序列行(不以>开头)syntax match fastaSequence /^[^>].*/ contains=fastaA,fastaT,fastaG,fastaC,fastaN
let b:current_syntax = "fasta"效果就是 ATGC 分别用了不同颜色。打开一个 fasta 文件,序列组成一目了然——如果全是绿色(A-rich)或者突然出现大量灰色的 N,立刻知道有问题。
2.2 BED 文件按列着色
BED 最关键的坑是第 2、3 列(start/end)的坐标系统。高亮后能快速定位异常的区间长度:
" ~/.vim/syntax/bed.vimsyntax match bedChrom /^chr\w\+/highlight bedChrom ctermfg=Magenta
syntax match bedStart /^\S\+\s\+\zs\d\+/highlight bedStart ctermfg=Yellow
syntax match bedEnd /^\S\+\s\+\d\+\s\+\zs\d\+/highlight bedEnd ctermfg=Red3. 折叠代码——超长脚本的救星
Shell 脚本超过 200 行,R 脚本超过 500 行,在终端里滚来滚去找函数是噩梦。Vim 的代码折叠功能可以把函数定义折叠成一行:
" ~/.vimrc 加set foldmethod=marker " 用{{{ }}}标记折叠set foldlevel=0 " 默认全部折叠set foldcolumn=1 " 左侧显示折叠列在你的脚本里手动加标记:
# 数据处理 {{{1process_data() { ...}# 1}}}
# 质量控制 {{{1run_qc() { ...}# 1}}}然后 zc 关闭折叠,zo 打开折叠,za 切换折叠状态。或者直接用 zM 全部折叠,zR 全部展开。
更推荐的是用折叠方式 indent:
" Sh/Bash 脚本自动按缩进折叠autocmd FileType sh setlocal foldmethod=indent foldlevel=2" Python 同理autocmd FileType python setlocal foldmethod=indent foldlevel=1这样完全不需要手动加标记,脚本的缩进结构就是折叠结构。
4. 宏录制——重复操作的自动化
这是 Vim 最被低估的功能,在生信里频繁用到。
场景: 有 50 个样本的 fastq 路径,你想把它们改成对应的输出文件名。每个文件名从:
/opt/data/raw/Sample_001_R1.fastq.gz改成:
/opt/data/clean/Sample_001_clean_R1.fastq.gz宏操作步骤:
1. qa " 开始录制宏到寄存器 a2. 0 " 跳到行首3. f/ " 找到第一个 / 的位置(光标到 raw 的 /)4. 然后手动编辑该行5. j " 跳到下一行6. q " 停止录制7. 49@a " 对剩余49行执行宏 a更实用的办法——同一个操作记成宏后配合搜索执行:
:g/raw/s//clean/g " 全局替换 raw→clean但宏的优势在于可以录制任何操作序列,不限于替换:移动光标、删除、粘贴、进入插入模式打字、退出——宏全记下来了。
生信中最常见的宏使用场景:
| 场景 | 录制内容 |
|---|---|
| 批量格式化样本名 | 移动→修改→下一行 |
| 从日志提取特定列 | 删除无关列→保存→下一行 |
| 给每行加前缀/后缀 | I前缀 Esc j |
| 拆分行 | f分隔符 r换行 j |
5. 多文件操作——buffer + 分屏
生信项目里经常同时开 4-5 个文件:脚本、输入文件、输出日志、配置文件。
" 分屏打开vim -O script.sh data.txt " 左右分屏(大写O)vim -o script.sh data.txt " 上下分屏(小写o)
" 已有文件内分屏:sp another_file.sh " 水平分屏:vsp another_file.sh " 垂直分屏
" 切换窗口Ctrl-w h " 左Ctrl-w j " 下Ctrl-w k " 上Ctrl-w l " 右
" 调整窗口大小Ctrl-w + " 加大Ctrl-w - " 缩小Ctrl-w = " 等宽打开多个文件时用 :ls 查看缓冲区列表:
:buffers " 列出所有打开的文件:b 2 " 切换到第2号缓冲区:bn " 下一个buffer:bp " 上一个buffer:bd " 关闭当前buffer6. 查找与替换——正则替换实战
6.1 基础查找
/pattern " 向下搜索?pattern " 向上搜索n " 下一个匹配N " 上一个匹配* " 搜索当前光标下的单词(向下)# " 搜索当前光标下的单词(向上)6.2 正则替换——生信高频操作
" 范围语法:[range]s/pattern/replacement/[flags]
" 全文替换(% = 整个文件):%s/raw/clean/g
" 当前行替换:s/foo/bar/
" 第10-20行替换:10,20s/foo/bar/g
" 替换前逐个确认(c = confirm):%s/old/new/gc
" 将 FASTA 序列头的空格转成下划线:%s/^>\(.*\)/\=substitute(submatch(1), ' ', '_', 'g')/生信中几个一行搞定的 Vim 正则替换:
" 1. 删除 FASTA 注释行(以>开头但含额外注释):g/^>.*comment/d
" 2. 每行末尾加文件后缀:%s/$/ .fastq.gz/
" 3. 把 SAM 文件的 @ 头提取到新文件:g/^@/y A " 把所有@开头行追加到寄存器A:new | put A " 新buffer粘贴
" 4. 把以空格分隔的样本ID列转成换行分隔:%s/ /\r/g
" 5. 删除空行:g/^$/d6.3 Vim 正则 vs Perl 正则的差异
Vim 的正则需要转义的元字符更多,这点比较反直觉:
| 含义 | Perl/PCRE | Vim |
|---|---|---|
| 一个或多个 | + | \+ |
| 零个或一个 | ? | \? |
| 分组 | () | \(\) |
| 或 | | | |(相同) |
| 数字 | \d | \d(相同) |
可以用 \v(very magic)模式让 Vim 更接近 Perl:
" 默认(需要转义+和括号):%s/foo\(bar\)\+/baz/g
" \v 模式(+和括号不需要转义):%s/\vfoo(bar)+/baz/g生信中的正则替换建议一律加 \v, 减少转义导致的漏匹配。
7. 查看超长序列——折行与导航
FASTA 文件每行通常 60 或 80 个碱基,但有时会遇到”单行全序列”(整个染色体一行)。这种文件在 Vim 里打开就是一条超长行。
:set wrap " 折行显示(不破坏文件内容):set linebreak " 在单词边界折行:set breakindent " 折行保持缩进
" 快速导航长行g0 " 跳到屏幕行的开头g$ " 跳到屏幕行的末尾gj " 向下一个屏幕行gk " 向上一个屏幕行如果你想真正把长行切成每 60 个碱基一行(即重新格式化 FASTA):
" 对非>开头的行,每60个字符后换行:%s/^[^>].*/\=join(split(submatch(0), '.\{60}'), '\n')/但其实用 seqkit 更快:seqkit seq -w 60 input.fa > output.fa——Vim 里记这个正则主要是为了理解它的字符串处理能力。
8. 踩坑记录
坑1:粘贴代码缩进错乱
从浏览器复制代码,在 Vim 里 Ctrl-v 粘贴,缩进层层叠加——像阶梯一样往右偏。
原因: Vim 的 autoindent 会对粘贴的内容逐行自动缩进,而粘贴的内容本身已经有缩进。
解决: 粘贴前进入粘贴模式:
:set paste " 进入粘贴模式(禁用自动缩进)" 粘贴代码...:set nopaste " 退出粘贴模式或者在 .vimrc 里绑定快捷键:
set pastetoggle=<F2> " F2 切换粘贴模式坑2:用 :wq 保存只读文件
修改了一个没有写权限的文件(比如 /etc/hosts),:wq 才告诉你没权限,改的内容也丢了。
" 正确做法:用 sudo 权限写:w !sudo tee % > /dev/null" 解释:把当前内容通过 sudo tee 写回原文件(% = 当前文件名)坑3:误按 Ctrl-z 后 Vim “卡死”
Ctrl-z 把 Vim 挂到后台了,终端看起来像卡住了。实际上 Vim 还活着,只是被 suspend 了。
# 回到 Vimfg
# 查看所有后台任务jobs如果不小心按了 Ctrl-z,别慌——fg 就回来了。如果不想要这个快捷键,在 .vimrc 里禁掉:
nnoremap <C-z> <Nop> " 禁用Ctrl-z坑4:高亮残留——:noh 是你的朋友
搜索了一个词之后,高亮一直留到下次搜索。看着烦。
:noh " 清除搜索高亮(nohlsearch缩写)也可以在 .vimrc 里绑定到 Esc:
nnoremap <Esc> :noh<CR>坑5:Vim 里的 Undo 只能用一次
默认情况下 u 只能回退一步。要无限回退:
set undofile " 持久化 undo 历史set undodir=~/.vim/undo " undo 文件存放目录创建目录:mkdir -p ~/.vim/undo
之后就算关掉 Vim 再打开,也能 u 回退到昨天的修改。
9. Vim 工作流模板
一个典型的”改脚本→查日志→回脚本”循环:
1. :tabedit script.sh " 新标签页打开脚本2. Ctrl-w s " 水平分屏3. :e logs/today.log " 下方打开日志4. Ctrl-w k " 切回上方5. /ERROR " 搜索脚本里ERROR的处理逻辑6. Ctrl-w j " 切到日志看实际报错7. Ctrl-w k " 回去修改8. :w " 保存9. :!bash script.sh " 不退出Vim直接运行脚本如果你一天做 20 次这个循环,每次比用 nano+grep+less 省 30 秒——一天省 10 分钟,一个月省 3 小时。
10. 推荐插件(最小化原则)
插件太多会让 Vim 启动慢,而且在服务器上不适合装一堆东西。我只推荐两个:
NERDTree——文件浏览器
# 安装(用 vim-plug 或手动)mkdir -p ~/.vim/pack/plugins/startcd ~/.vim/pack/plugins/startgit clone https://github.com/preservim/nerdtree.git使用:
:NERDTreeToggle " 开关文件树:NERDTreeFind " 在文件树中定位当前文件实用快捷键:
o打开文件 / 展开目录m打开菜单(新建/删除/移动文件)?帮助
vim-airline——状态栏美化
纯视觉增强,但显示的信息很实用:当前 Git 分支、文件类型、行列位置。
cd ~/.vim/pack/plugins/startgit clone https://github.com/vim-airline/vim-airline.git11. 总结
| 技能 | Vim 命令 | 生信场景 |
|---|---|---|
| 相对行号跳转 | 12j / 5k | 快速定位脚本中的某一行 |
| 批量替换 | :%s/\vold/new/g | 改样本名前缀、修路径 |
| 宏录制 | qa ... q → @a | 50 个样本文件名格式统一 |
| 分屏编辑 | Ctrl-w s/v | 边看日志边改脚本 |
| 代码折叠 | zc / zo | 浏览 500 行 Shell 脚本 |
| 粘贴模式 | :set paste | 从网页复制命令到脚本 |
| 正则替换增强 | \v 前缀 | 避免转义地狱 |
最后一条建议: 别试图一天学会 Vim。先学会 5 个命令(i 插入、Esc 退出、:w 保存、:q 退出、/ 搜索),然后用这 5 个命令干两天活。两天后再加 5 个命令。两周之后你就回不去 nano 了。
本文于 2026-01-20 在 Debian 12 上实测完成。Vim 9.1,所有配置和命令均在生产服务器上验证可用。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!