Vim 使用总结
因为工作比较忙,很久没有更新博客了,今天水一篇
2023 年 8 月 3 日,Vim 创始人 Bram Moolenaar 离世,时隔年余,他和好友相聚于天堂,愿天堂有他们喜欢的项目
命令速查
- VIM 常用快捷键汇总:https://vim.rtorr.com/
- code block 跳转快捷键:https://vim.fandom.com/wiki/Jumping_to_the_start_and_end_of_a_code_block
- vim -U NONE -N gargantuan.txt,打开大文件
- vertical resize 70,设置列宽度;only,仅保留当前窗口;Ve 显示目录;}} {{ 连续文本块跳转
- 显示当前 buffer 文件的路径:1 Ctrl-G
对编辑器的诉求
随着使用 Vim 的时间愈久,还在使用的 Vim 插件慢慢就只剩下几个小巧简单的。对我而言,编码所使用的编辑器需要满足如下几个功能,插件的选择,也会围绕这几个功能展开。使用下面 Vim 插件的配置有个前提,就是你主要依赖大脑记忆项目结构,插件只是辅助工具
- 脱离鼠标编辑,这是 Vimer 的必备技能
- 打开文件要快。终端的 Vim 不需要 GUI,所以响应速度够快,对于大一些的文件可以在不载入 .vimrc 配置的时候加速打开过程(
vim -u NONE -N /path/to/file
)。更大的文件,可以尝试命令 less 或者 more 进行查看 - 支持正则表达式的关键字和文件路径搜索:Universal Ctags、GNU Global、Pygments
- 简单的包管理:plug.vim
- 简单的界面:nerdtree、airline、vim-colors-solarized、vim-markdown
- 快速的跳转:vim-easymotion、a.vim、vim-markbar
- 简洁的代码格式化工具:neoformat。系统工具依赖:clang-format(c/c++/python 等)、cmakelang(CMake file)、verible(HDL, e.g. verilog, VHDL)
功能实现
搜索
Universal ctags
Universal Ctags (abbreviated as u-ctags) is a maintained implementation of
ctags
.ctags
generates an index (or tag) file of language objects found in source files for programming languages.
可以使用源码安装,或者 apt、brew 等系统工具进行安装(snap install universal-ctags
),tags 工具这里不做介绍。为了区别旧的 ctags 工具,安装完 universal ctags 后,我会将其命令修改为 utags
Global&Pygments
GNU Global 为源文件构建索引,所以可以实现快速的函数、单词和文件查找,且 Global 默认支持正则表达式。Global 的安装和使用细节可以参考官网,这里只介绍我常用的功能
安装完 Global 后,系统会多出两个命令,gtags 和 global。gtags 命令用于给项目源文件创建索引,为减少索引文件对项目的影响,可以将索引文件置于系统目录,或者将索引文件写到 .gitignore 中;另一个命令是 global,global 接受正则字符串,并搜索 gtags 创建的索引文件。使用 gtags 为指定项目创建索引的方式可以参考下面:
# Linux, ~/.bashrc
alias tags_update="find . -regextype posix-egrep -iregex '.*\.(H|HH|HPP|HXX|H\+\+|INC|DEF|C|CC|CPP|CXX|PY)$' -type f > global_file_list.bak && gtags -f global_file_list.bak -i && utags -R --languages=C,C++,Python"
# Macos, ~/.zshrc
alias tags_update="find -E . -iregex '.*\.(H|HH|HPP|HXX|H\+\+|INC|DEF|C|CC|CPP|CXX|PY|V)$' -type f > global_file_list.bak && gtags -f global_file_list.bak -i && utags -R --languages=C,C++,Python,Verilog"
新增需要解析的文件后缀,可以修改上面小括号中的内容
gtags 命令支持配置文件,将 global 源码目录下的 gtags.conf 文件拷贝到 ~/.globalrc,修改 ~/.globalrc 文件可以调整 gtags 的功能。例如 gtags 默认解析的语言不包含 tcl 和 python,修改配置文件中的 langmap,可以新增 tcl/python 的解析
builtin-parser:\
:langmap=c\:.c.h.i,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.hh.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml,Tcl\:.tcl.tk.wish.itcl:
gtags 默认使用内置(build-in)的解析器解析源文件,但内置的解析器支持的语言有限,此时可以考虑使用 pygments 实现更多语言的解析
- 安装 pygments:pip3 install pygments
- 设置环境变量:export GTAGSLABEL=pygments,Linux 可以将环境变量写入 ~/.bashrc,Mac 可以写入 ~/.zshrc
- 验证:
gtags --explain
拷贝如下文件到 Vim 配置目录,给 Vim 添加 Gtags 搜索命令:
# locate -b gtags.vim # 确认 gtags 配置到位置
# /usr/share/vim/addons/plugin/gtags.vim
cp /usr/share/vim/addons/plugin/gtags.vim ~/.vim/plugin/
cp /usr/share/vim/addons/plugin/gtags-cscope.vim ~/.vim/plugin/
完成上述任务,且确定当前目录下包含 Gloabl 的索引文件(GTAGS、GPATH 等),进入 Vim 命令模式即可进行搜索,例如:Gtags -gi hell.*ord
。Gtags 支持的 flag 不多,但已经足够使用,细节请参考官网教程。下面给出一些使用示例:
Gtags -g hello\(\w # 使用 grep like 正则表达式搜索 tag
Gtags -gi hello\(\w # 使用正则表达式搜索 tag,-i 表示忽略大小写
Gtags -Pi tim.*ser # 使用正则表达式搜索源文件名
gtags -r initia.* # 使用正则表达式搜索函数的引用(reference)
gtags -f DIR2/fileC.c # 显示指定文件中包含的 tags
为减少开发时字符的输入量,可以在 vimrc 中添加如下自定义命令。Vim 添加下面的配置后,命令模式输入 Gp 就相当于输入了 Gtags -Pi
command -nargs=* Gf Gtags -gi <args>
command -nargs=* Gp Gtags -Pi <args>
Quckfix&Cfilter
当项目比较大的时候,Gtags 输出到 quickfix 窗口的内容会比较多,可以使用 Cfilter 命令过滤。因为 Cfilter 是 Vim 8.0 后新增的自定义命令,所以需要手动开启。在 .vimrc 文件中添加如下配置即可引入 Cfilter 命令
packadd cfilter
Cfilter 使用示例:
Cfilter /pat/ # 筛选满足搜索模式的条目
Cfilter! /pat/ # 筛选不满足搜索模式的条目
colder # 前一个 quickfix
cnewer # 后一个 quickfix
Lfilter # 应用于 location list (quickfix 的 buffer 局部版本)
# lolder / lnewer 前/后一个 location list
正则搜索
https://regexr.com/ / VIM 搜索默认支持正则表达式 / VIM 搜索默认考虑大小写,搜索字符串最后输入\c
可以促使 VIM 不检查大小写
特性 | 示例 | ||
---|---|---|---|
匹配一个字符(2) | . |
\. |
|
匹配一组字符(3) | [f-g]a. |
[^f-g]a. |
|
元字符(4) | \d \D |
\w \W |
附表参考 |
重复次数(5) | + / * |
? |
换行符 [\r]?\n |
重复区间(5) | \d{3,}\.\d{2} |
<[Bb]>.*<\/[Bb]> |
<[Bb]>.*?<\/[Bb]> |
位置(边界)匹配(6) | \b \B |
^ $ |
附表参考 |
子表达式(7) | ( ){2,} |
`(19 | 20)\d{2}` |
引用子表达式(8) | h([1-6]).*?h\1 |
||
环视 / 消耗(9) | .+(?=:) |
条件(10)、常用正则(11) | \d{5}(?(?=-)-\d{4}) |
跳转
Vim Marks
'< \& '> start/end of visual selection
'[ \& '] start/end of last change or yank
'. position of where last change was made
'^ position of cursor when last Vim last left insert mode - This is how gi command works
'' position before last jump (Super useful!). See h ''
Ctrl-O to jump back to the previous (older) location.
Ctrl-I (same as Tab) to jump forward to the next (newer) location
Vim 跳转,我主要使用 Vim 内置的 Marks,结合 Vim 插件 vim-markbar 可以快速查看已经标记的内容。其他 Marks 相关命令示例:
# 命令模式
marks # 显示所有 marks
delmarks A-Z # 删除全局文件 mark
delmarks a-z # 删除文件内部 mark
Vim Marks 大写字符是跨项目的,即默认情况下,项目 Z 中标记的 A 在项目 Y 中也能看下,如果在项目 Y 中也设置了标记 A,那么项目 Z 中的 A 将被覆盖。为了避免这类问题,我使用的方法比较简单,将不同项目的 viminfo 文件保存在不同的文件中(默认的 viminfo 路径是空 set viminfo=
,可以通过命令设置位置 set viminfofile=/path/to/file
),每次切换项目的时候重新读入(rviminfo path/to/viminfo
),退出项目时手动保存(wviminf path/to/viminfo
)
jumps
Vim 的跳转列表也是一个非常不错的工具,命令模式输入 ju[mps]
可以查看跳转列表历史,确认前进或者后退的数值后,可以直接跳转到对应的位置,例如:17 CTRL-O
、13 Tab
vim-easymotion
有些时候我们需要快速跳转到当前文件中的某个位置,使用 Vim 内置的方法可以考虑先跳转到某一行(100 Shift-G)然后跳到对应的行位置。利用 Vim 插件 vim-easymotion,可以快速跳转到指定的位置,使用方法请参考 github
vim-bookmarks
阅读代码时经常需要在不同文件中跳转,大型仓库使用 vim mark,容易忘记标记的意义。可以考虑使用 vim-bookmarks 辅助记忆,vim-bookmarks 插件支持为不同目录中的文件设置书签功能,如此可以通过书签记忆代码结构
Buffer&Jumplist
Buffer 参考这里
:ls # show all buffer, files / buffers
:b3 # open buffer 3
:bd3 # del buffer 3
:1,32bd # del buffer from 1 to 32
:3,$bd # del buffer from 3 to last, using vim range commands
格式化
clang-format&neoformat
我不喜欢编辑器自动格式化文件,所以我使用 Vim 插件 neoformat 并设置了快捷键触发格式化功能
默认格式化工具我使用的是 clang-format,其他 clang-format 还不支持的语言,可以考虑其他工具,例如:cmakelang(cmake)、verible(HDL, e.g. verilog, VHDL 等)。下面示例为 neoformat 添加自定义的 verilog 格式化方法
首先安装 veribble 工具,并确认系统中可以找到 verible-verilog-format 命令。随后在 neoformat 插件目录中(autoload/neoformat/formatters)新增 verilog.vim 文件,并写入如下内容:
function! neoformat#formatters#verilog#enabled() abort
return ['verible']
endfunction
function! neoformat#formatters#verilog#verible() abort
return {
\ 'exe': 'verible-verilog-format',
\ }
endfunction
界面
- 布局:nerdtree、airline
- 常见代码高亮插件:vim-colors-solarized
- 特殊文件语法高亮
.vimrc 示例
VIM 示例可以参考这里:https://boardmix.cn/app/editor/jTD6en79Nmf3ciWxHYr3vA