如果Vim 8.0
只能使用两个插件,那么我的选择是LeaderF
和gutentags
:
LeaderF
是一种异步模糊查找器,用于在大型项目中快速定位文件,缓冲区,MRUS
(Most Recently Used Files),标签等,最大的特点就是快和准确。gutentags
是一个用于管理tags
的Vim插件,最大的特点是使用Vim
打开一个项目后,它就会在后台自动生成该项目所有的tags
,每次保存时,它都会在后台静默更新该文件的tags
。
接下来本文会详细介绍这两个插件的安装,配置和使用方法。
LeaderF
LeaderF
插件主要用于在大型项目中查找文件,缓冲区,MRUS
和标签,它具有如下特点:
- 用Python编写。
- 支持模糊和正则表达式搜索。
- 管理缓冲区和
MRUS
。
安装和配置
安装之前首先确保您的python2
版本是Python 2.7
或更高版本:
$ python --version
Python 2.7.12
前一篇文章已经介绍了我们使用的vim-plug
插件管理器,所以安装LeaderF
非常简单,只需要在.vimrc
的vim-plug
插件管理代码处添加即可:
call plug#begin('~/.vim/plugged')
Plug 'Yggdroot/LeaderF'
call plug#end()
重新加载.vimrc
并:PlugInstall
安装插件。新的插件安装在~/.vim/plugged
目录,然后我们可以在.vimrc
添加LeaderF
相关的常用配置代码:
" LeaderF
let g:Lf_ShortcutF = '<m-f>'
noremap <m-m> :LeaderfMru<cr>
noremap <m-n> :LeaderfFunction!<cr>
noremap <m-b> :LeaderfBuffer<cr>
noremap <m-g> :LeaderfTag<cr>
let g:Lf_StlSeparator = { 'left': '', 'right': '', 'font': '' }
let g:Lf_RootMarkers = ['.project', '.root', '.svn', '.git']
let g:Lf_WorkingDirectoryMode = 'Ac'
let g:Lf_WindowHeight = 0.30
let g:Lf_CacheDirectory = expand('~/.vim/cache')
let g:Lf_ShowRelativePath = 0
let g:Lf_HideHelp = 1
let g:Lf_StlColorscheme = 'powerline'
let g:Lf_PreviewResult = {'Function':0, 'BufTag':0}
这些配置我们基本只需要了解配置的5个快捷键命令(<m-f>
其实是ALT
+f
的组合,其他命令同理),具体使用方法下面会详细描述:
命令 | 描述 |
---|---|
<m-f> |
进入当前工作目录搜索文件模式,默认是完整路径(FullPath )搜索模式 |
<m-m> |
列出最近使用文件列表以供搜索 |
<m-n> |
列出当前文件所有的函数列表以供搜索 |
<m-b> |
列出buffer 中的文件以供搜索 |
<m-g> |
列出当前工作目录所有的tags 以供搜索,可以部分替代ctags 和gtags 的功能 |
用法
我们以<m-f>
命令(<m-f>
其实是ALT
+f
的组合,其他命令同理)用法举例,使用vim
打开工作目录任意文件(空文件也行)后,使用ALT
+f
进入当前工作目录搜索文件模式,默认是完整路径(FullPath
)搜索模式,接下来我们可以输入相关字符串来查找具体文件:
查找到相关的文件后,除了直接回车打开外,还有如下命令值得尝试:
命令 | 描述 |
---|---|
<ESC> |
退出LeaderF |
<C-F> |
在完整路径搜索模式和仅名称搜索模式之间切换 |
<C-J> |
在结果窗口中向下移动光标 |
<C-K> |
在结果窗口中向上移动光标 |
<Up> /<Down> |
从历史回忆起上一个/下一个输入模式 |
<C-X> |
在水平分割窗口打开 |
<C-]> |
在垂直分割窗口打开 |
<C-T> |
在新标签页中打开 |
我最常用的是<C-]>
和<C-T>
两个命令。
Gutentags
Gutentags
是一个插件,负责管理Vim
中标签文件的管理。它将(重新)生成标记文件,同时保持它们完全不受影响。它有如下特点:
- 除了运行
Vim
之外没有其他依赖:没有Python
,Ruby
或其他任何东西。 - 增量标签生成:不要一直重新生成整个项目。对于小型项目来说这可能没问题,但它不能扩展。
- 保持标记文件的一致性:不要只将当前文件的标记附加到标记文件,否则您仍将“看到”已删除或重命名的类和函数的标记。
- 自动创建标记文件:您从一个新分叉的项目中打开一些东西,它应该开始自动索引它,就像在
Sublime Text
或Visual Studio
或任何其他IDE中一样。
安装和配置
首先确保系统已经安装了ctags
和最新的gnu global
(主要使用其中的gtags
和gtags-cscope
):
$ ctags --version
Exuberant Ctags 5.9~svn20110310, Copyright (C) 1996-2009 Darren Hiebert
$ global --version
global (GNU GLOBAL) 6.6.2
在.vimrc
的vim-plug
插件管理代码处添加一组gutentags
相关的插件:
call plug#begin('~/.vim/plugged')
Plug 'ludovicchabant/vim-gutentags'
Plug 'skywind3000/gutentags_plus'
Plug 'skywind3000/vim-preview'
call plug#end()
gutentags_plus
插件与gutentags
一起使用,并提供无缝的数据库切换。它定义GscopeFind
执行cscope
搜索的命令gtags-cscope
。而vim-preview
则是在你按下p
时,从quickfix窗口预览结果。
重新加载.vimrc
并:PlugInstall
安装插件,新的插件安装在~/.vim/plugged
目录。然后我们可以在.vimrc
添加gutentags
相关的常用配置代码:
" gutentags 搜索工程目录的标志,碰到这些文件/目录名就停止向上一级目录递归
let g:gutentags_project_root = ['.root', '.svn', '.git', '.hg', '.project']
" 所生成的数据文件的名称
let g:gutentags_ctags_tagfile = '.tags'
" 同时开启 ctags 和 gtags 支持:
let g:gutentags_modules = []
if executable('ctags')
let g:gutentags_modules += ['ctags']
endif
if executable('gtags-cscope') && executable('gtags')
let g:gutentags_modules += ['gtags_cscope']
endif
" 将自动生成的 tags 文件全部放入 ~/.cache/tags 目录中,避免污染工程目录
let s:vim_tags = expand('~/.cache/tags')
let g:gutentags_cache_dir = s:vim_tags
" 配置 ctags 的参数
let g:gutentags_ctags_extra_args = ['--fields=+niazS', '--extra=+q']
let g:gutentags_ctags_extra_args += ['--c++-kinds=+px']
let g:gutentags_ctags_extra_args += ['--c-kinds=+px']
" 检测 ~/.cache/tags 不存在就新建
if !isdirectory(s:vim_tags)
silent! call mkdir(s:vim_tags, 'p')
endif
" 禁用 gutentags 自动加载 gtags 数据库的行为
let g:gutentags_auto_add_gtags_cscope = 0
" gtags-cscope
"s:查找C代码符号
"g:查找本定义
"c:查找调用本函数的函数
"t:查找本字符串
"e:查找本egrep模式
"f:查找本文件
"i:查找包含本文件的文件
"d:查找本函数调用的函数
let g:gutentags_plus_nomap = 1
noremap <silent> <c-\>s :GscopeFind s <C-R><C-W><cr>
noremap <silent> <c-\>g :GscopeFind g <C-R><C-W><cr>
noremap <silent> <c-\>c :GscopeFind c <C-R><C-W><cr>
noremap <silent> <c-\>t :GscopeFind t <C-R><C-W><cr>
noremap <silent> <c-\>e :GscopeFind e <C-R><C-W><cr>
noremap <silent> <c-\>f :GscopeFind f <C-R>=expand("<cfile>")<cr><cr>
noremap <silent> <c-\>i :GscopeFind i <C-R>=expand("<cfile>")<cr><cr>
noremap <silent> <c-\>d :GscopeFind d <C-R><C-W><cr>
noremap <silent> <c-\>a :GscopeFind a <C-R><C-W><cr>
" preview
autocmd FileType qf nnoremap <silent><buffer> p :PreviewQuickfix<cr>
autocmd FileType qf nnoremap <silent><buffer> P :PreviewClose<cr>
查看相关注释即可理解相关快捷键配置的含义。
用法
除了常用的<c-]>
命令来查找本定义外,我们还可以用如下命令来查找更多的内容(<c-\>s
是先同时按住Ctrl
+\
键,之后单独按s
键):
命令 | 描述 |
---|---|
<c-\>s |
查找C代码符号 |
<c-\>g |
查找本定义 |
<c-\>c |
查找调用本函数的函数 |
<c-\>t |
查找本字符串 |
<c-\>e |
查找本egrep模式 |
<c-\>f |
查找本文件 |
<c-\>i |
查找包含本文件的文件 |
<c-\>d |
查找本函数调用的函数 |
<c-\>a |
查找此符号被赋值的位置 |
查找到相关文件后,按下p
,从quickfix窗口可以打开预览文件,按下P
,从quickfix窗口关闭预览文件。在linux
内核等大型项目中搜索定义/引用时,gutentags_plus
非常有效: