`Leaderf gtags`:模糊匹配与最强静态符号索引工具的完美结合

Gtags

Gtags也就是GNU GLOBAL,是一个非常强大的源码符号索引工具。它通过建立索引数据库,不但可以查找函数的定义,还可以查找函数的所有引用(被调用的地方);而且它还可以增量地更新索引数据库,当代码有所改变时,它可以在很短的时间内更新索引数据库,保持索引数据库和代码同步。
韦大的 Vim 8 中 C/C++ 符号索引:GTags 篇 对 gtags 有比较详细的介绍,本文再做一些补充。

  1. GLOBAL-6.6.3 released

Gtags的最新版本已经是6.6.3,该版本 fix了韦大文中提到的 Windows下面文件名大小写的 bug。

  1. 在 Linux上,不配置let $GTAGSCONF = '/path/to/share/gtags/gtags.conf'也可以正常工作。
  2. 当项目文件的路径包含非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 ]
                 [--append] [--match-path] [--gtagsconf ] [--gtagslabel ]
                 [--append] [--match-path] [--gtagsconf ] [--gtagslabel ] [--append]
                 [--match-path] [--gtagsconf ] [--gtagslabel ] [--append]
                 [--match-path] [--gtagsconf ] [--gtagslabel ] [--append]
                 [--match-path] [--gtagsconf ] [--gtagslabel , --scope 
                        Show only tags which exist under  directory.
  --recall              Recall last search. If the result window is closed, reopen it.
  --match-path          Match the file path when fuzzy searching.
  --append              Append to the previous search results.
  --current-buffer      Show tags in current buffer.
  --all-buffers         Show tags in all listed buffers.
  --all                 Show tags in the whole project.
  --result      Show result using format, which may be one of: `ctags`(default), `ctags-x`,
                        `ctags-mod`.
  --auto-jump []  Jump to the tag directly when there is only one match.  can be 'h', 'v' or
                        't', which mean jump to a horizontally, vertically split window, or a new tabpage
                        respectively. If  is omitted, jump to a position in current window.

common arguments:
  --reverse             show results in bottom-up order
  --stayOpen            don't quit LeaderF after accepting an entry
  --input        specifies INPUT as the pattern inputted in advance
  --cword               current word under cursor is inputted in advance
  --top                 the LeaderF window is at the top of the screen
  --bottom              the LeaderF window is at the bottom of the screen
  --left                the LeaderF window is at the left of the screen
  --right               the LeaderF window is at the right of the screen
  --belowright          the LeaderF window is at the belowright of the screen
  --aboveleft           the LeaderF window is at the aboveleft of the screen
  --fullScreen          the LeaderF window takes up the full screen
  --nameOnly            LeaderF is in NameOnly mode by default
  --fullPath            LeaderF is in FullPath mode by default
  --fuzzy               LeaderF is in Fuzzy mode by default
  --regexMode           LeaderF is in Regex mode by default
  --nowrap              long lines in the LeaderF window won't wrap
  --next                Jump to the next result.
  --previous            Jump to the previous result.

If [!] is given, enter normal mode directly.

注意:如果:Leaderf后面有感叹号,会直接进入normal模式;如果没有感叹号,则是输入模式,此时可以输入字符来进行模糊匹配过滤。可以用tab键在两个模式间来回切换。

手动生成gtags数据库

Leaderf[!] gtags --update [--gtagsconf ] [--gtagslabel 

此命令完全异步,不会卡住你的UI。

  1. --gtagsconf

    用来指定 gtags.conf 文件的路径,一般情况下不需要指定,默认值就可以很好地工作。对于Windows上,如果相对于gtags.exe所在路径有../share/gtags/gtags.conf,也不需要指定该选项。如果需要用户自己特有的针对 gtags 的配置,可以指定用户的配置文件。

    也可以在vimrc里设置g:Lf_Gtagsconf达到同样的目的。

  2. --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`达到同样的目的。
  1. --gtagslibpath [ ...]

    用来指定项目所用 library 的 Paths,这样就可以生成 library 的索引,查找定义或引用时可以跳转到 library 代码中去。后面指定的路径还可以是一个或多个其他项目路径,跳转时可以跳到其他项目中的文件。

查找tags

Leaderf[!] gtags [--current-buffer | --all-buffers | --all] [--result ] [COMMON_OPTIONS]

此命令可以列出当前buffer、所有打开的buffer或者整个项目的tags。

  1. Leaderf[!] gtags等同于Leaderf[!] gtags --all,列出整个项目的tags。
  2. --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 ]
                 [--append] [--match-path] [--gtagsconf ] [--gtagslabel 
  1. 可以是正则表达式。
  2. --auto-jump [] 意思是如果只有一个结果直接跳过去。

其他

  1. Leaderf[!] gtags -g 功能已被Leaderf rg包含。
  2. Leaderf gtags --nextLeaderf gtags --previous相当于quickfix的:cnext:cprevious命令,在LeaderF结果窗口关闭的情况下也可以使用。
  3. 更多内容请参考: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", "")

你可能感兴趣的:(模糊搜索,gtags,vim插件,vim)