Gtags
Gtags也就是GNU GLOBAL,是一个非常强大的源码符号索引工具。它通过建立索引数据库,不但可以查找函数的定义,还可以查找函数的所有引用(被调用的地方);而且它还可以增量地更新索引数据库,当代码有所改变时,它可以在很短的时间内更新索引数据库,保持索引数据库和代码同步。
韦大的 Vim 8 中 C/C++ 符号索引:GTags 篇 对 gtags 有比较详细的介绍,本文再做一些补充。
- GLOBAL-6.6.3 released
Gtags的最新版本已经是6.6.3,该版本 fix了韦大文中提到的 Windows下面文件名大小写的 bug。
- 在 Linux上,不配置
let $GTAGSCONF = '/path/to/share/gtags/gtags.conf'
也可以正常工作。
- 当项目文件的路径包含非ASCII字符时,使用pygments会报
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 5-8: ordinal not in range(256)
自动生成Gtags索引数据库
LeaderF 可以自己管理 gtags 数据库(GTAGS,GRTAGS,GPATH),它不会在你的项目目录下生成任何额外的文件或目录。gtags 数据库文件存储在$HOME/.LfCache/gtags/%PATH%OF%YOUR%PROJECT/
下面, %PATH%OF%YOUR%PROJECT
是把你项目路径中的 \
或 /
替换成 %
。
只要设置let g:Lf_GtagsAutoGenerate = 1
, LeaderF 就会在打开第一个文件时自动生成 gtags 数据库。当代码有更改并且已经有 gtags 数据库生成时,更改的代码会自动同步到 gtags 数据库(即使g:Lf_GtagsAutoGenerate
是0)。
只有在项目根目录下有g:Lf_RootMarkers
(默认值是['.git', '.hg', '.svn']
)里面指定的文件或目录时,LeaderF 才会自动生成 gtags 数据库;否则只能手动生成 gtags 数据库:Leaderf gtags --update
,但是当代码有更改时,gtags 数据库依然可以自动更新。
Leaderf gtags 使用介绍
具体使用方法可以用:Leaderf gtags -h
来查看。
usage:
Leaderf[!] gtags [-h] [--remove] [--recall]
Leaderf[!] gtags --update [--gtagsconf ] [--gtagslabel
注意:如果:Leaderf
后面有感叹号,会直接进入normal模式;如果没有感叹号,则是输入模式,此时可以输入字符来进行模糊匹配过滤。可以用tab键在两个模式间来回切换。
手动生成gtags数据库
Leaderf[!] gtags --update [--gtagsconf ] [--gtagslabel ] [--accept-dotfiles]
[--skip-unreadable] [--skip-symlink []] [--gtagslibpath [ ...]]
此命令完全异步,不会卡住你的UI。
-
--gtagsconf
用来指定 gtags.conf 文件的路径,一般情况下不需要指定,默认值就可以很好地工作。对于Windows上,如果相对于gtags.exe
所在路径有../share/gtags/gtags.conf
,也不需要指定该选项。如果需要用户自己特有的针对 gtags 的配置,可以指定用户的配置文件。
也可以在vimrc
里设置g:Lf_Gtagsconf
达到同样的目的。
-
--gtagslabel
用来指定gtagslabel,如果不指定,默认值是 'default'
。
是 gtags.conf 中的:
- default
使用内置parser,只支持 6 种语言(C,C++,Java,PHP4,Yacc,汇编)。
- ctags
使用exuberant-ctags作为语言parser,支持 40+ 种语言,只能生成定义索引不能生成引用索引。
- new-ctags
使用universal-ctags作为语言parser,支持 100+ 种语言,只能生成定义索引不能生成引用索引。虽然貌似universal-ctags已经支持生成引用tags,但是依然不能配合gtags工作(见这里),我也试了各种操作都没成功,也许是因为这个PR没有被merge。
- pygments
使用pygments作为语言parser,号称支持300+种语言。
- native-pygments
对于原生支持的6种语言使用内置parser,其他语言使用pygments作为parser。
- 等等
也可以在`vimrc`里设置`g:Lf_Gtagslabel`达到同样的目的。
-
--gtagslibpath [ ...]
用来指定项目所用 library 的 Paths,这样就可以生成 library 的索引,查找定义或引用时可以跳转到 library 代码中去。后面指定的路径还可以是一个或多个其他项目路径,跳转时可以跳到其他项目中的文件。
查找tags
Leaderf[!] gtags [--current-buffer | --all-buffers | --all] [--result ] [COMMON_OPTIONS]
此命令可以列出当前buffer、所有打开的buffer或者整个项目的tags。
-
Leaderf[!] gtags
等同于Leaderf[!] gtags --all
,列出整个项目的tags。
-
--result
指定显示格式,可以是ctags
(default), ctags-x
或者ctags-mod
。
- ctags格式
- ctags-x格式
- ctags-mod格式
查找定义、引用
Leaderf[!] gtags -d [--auto-jump []] [-i] [--literal] [--path-style ] [-S ]
[--append] [--match-path] [--gtagsconf ] [--gtagslabel ] [COMMON_OPTIONS]
Leaderf[!] gtags -r [--auto-jump []] [-i] [--literal] [--path-style ] [-S ]
[--append] [--match-path] [--gtagsconf ] [--gtagslabel ] [COMMON_OPTIONS]
-
可以是正则表达式。
-
--auto-jump []
意思是如果只有一个结果直接跳过去。
其他
-
Leaderf[!] gtags -g
功能已被Leaderf rg
包含。
-
Leaderf gtags --next
和 Leaderf gtags --previous
相当于quickfix的:cnext
和:cprevious
命令,在LeaderF结果窗口关闭的情况下也可以使用。
- 更多内容请参考
:Leaderf gtags -h
和 doc。
使用示例
let g:Lf_GtagsAutoGenerate = 1
let g:Lf_Gtagslabel = 'native-pygments'
noremap fr :=printf("Leaderf! gtags -r %s --auto-jump", expand(""))
noremap fd :=printf("Leaderf! gtags -d %s --auto-jump", expand(""))
noremap fo :=printf("Leaderf! gtags --recall %s", "")
noremap fn :=printf("Leaderf gtags --next %s", "")
noremap fp :=printf("Leaderf gtags --previous %s", "")