Vim配置与技巧:语法高亮、折叠、宏、多文件

2935 字
15 分钟
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-8
set 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 语法高亮#

" 加到 ~/.vimrc
augroup fasta_highlight
autocmd!
autocmd BufRead,BufNewFile *.fa,*.fasta,*.fna set filetype=fasta
augroup END

然后创建 ~/.vim/syntax/fasta.vim

" fasta.vim - FASTA 语法高亮
if exists("b:current_syntax")
finish
endif
" 序列头(>开头)→ 蓝色粗体
syntax match fastaHeader /^>.*/
highlight fastaHeader ctermfg=Blue cterm=bold
" A → 绿色
syntax match fastaA /A/ containedin=fastaSequence
highlight fastaA ctermfg=Green
" T → 红色
syntax match fastaT /T/ containedin=fastaSequence
highlight fastaT ctermfg=Red
" G → 黄色
syntax match fastaG /G/ containedin=fastaSequence
highlight fastaG ctermfg=Yellow
" C → 青色
syntax match fastaC /C/ containedin=fastaSequence
highlight fastaC ctermfg=Cyan
" N → 灰色(表示不确定碱基)
syntax match fastaN /N/ containedin=fastaSequence
highlight 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.vim
syntax 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=Red

3. 折叠代码——超长脚本的救星#

Shell 脚本超过 200 行,R 脚本超过 500 行,在终端里滚来滚去找函数是噩梦。Vim 的代码折叠功能可以把函数定义折叠成一行:

" ~/.vimrc 加
set foldmethod=marker " 用{{{ }}}标记折叠
set foldlevel=0 " 默认全部折叠
set foldcolumn=1 " 左侧显示折叠列

在你的脚本里手动加标记:

Terminal window
# 数据处理 {{{1
process_data() {
...
}
# 1}}}
# 质量控制 {{{1
run_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 " 开始录制宏到寄存器 a
2. 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 " 关闭当前buffer

6. 查找与替换——正则替换实战#

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/^$/d

6.3 Vim 正则 vs Perl 正则的差异#

Vim 的正则需要转义的元字符更多,这点比较反直觉:

含义Perl/PCREVim
一个或多个+\+
零个或一个?\?
分组()\(\)
||(相同)
数字\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 了。

Terminal window
# 回到 Vim
fg
# 查看所有后台任务
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——文件浏览器#

Terminal window
# 安装(用 vim-plug 或手动)
mkdir -p ~/.vim/pack/plugins/start
cd ~/.vim/pack/plugins/start
git clone https://github.com/preservim/nerdtree.git

使用:

:NERDTreeToggle " 开关文件树
:NERDTreeFind " 在文件树中定位当前文件

实用快捷键:

  • o 打开文件 / 展开目录
  • m 打开菜单(新建/删除/移动文件)
  • ? 帮助

vim-airline——状态栏美化#

纯视觉增强,但显示的信息很实用:当前 Git 分支、文件类型、行列位置。

Terminal window
cd ~/.vim/pack/plugins/start
git clone https://github.com/vim-airline/vim-airline.git

11. 总结#

技能Vim 命令生信场景
相对行号跳转12j / 5k快速定位脚本中的某一行
批量替换:%s/\vold/new/g改样本名前缀、修路径
宏录制qa ... q@a50 个样本文件名格式统一
分屏编辑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,所有配置和命令均在生产服务器上验证可用。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Vim配置与技巧:语法高亮、折叠、宏、多文件
https://fg.ink/posts/vim-bioinfo-config/
作者
风观
发布于
2024-09-01
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
风观
风有来路,观有所思
分类
标签
站点统计
文章
50
分类
1
标签
29
总字数
61,837
运行时长
0
最后活动
0 天前

文章目录