`Leaderf gtags`:模糊匹配與最強靜態符號索引工具的完美結合

Gtags

Gtags也就是GNU GLOBAL,是一個很是強大的源碼符號索引工具。它經過創建索引數據庫,不但能夠查找函數的定義,還能夠查找函數的全部引用(被調用的地方);並且它還能夠增量地更新索引數據庫,當代碼有所改變時,它能夠在很短的時間內更新索引數據庫,保持索引數據庫和代碼同步。
韋大的 Vim 8 中 C/C++ 符號索引:GTags 篇 對 gtags 有比較詳細的介紹,本文再作一些補充。html

  1. GLOBAL-6.6.3 released Gtags的最新版本已是6.6.3,該版本 fix了韋大文中提到的 Windows下面文件名大小寫的 bug。
  2. 在 Linux上,不配置let $GTAGSCONF = '/path/to/share/gtags/gtags.conf'也能夠正常工做。
  3. 當項目文件的路徑包含非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 數據庫依然能夠自動更新。linux

Leaderf gtags 使用介紹

具體使用方法能夠用:Leaderf gtags -h來查看。git

usage:
Leaderf[!] gtags [-h] [--remove] [--recall]
Leaderf[!] gtags --update [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [--accept-dotfiles]
                 [--skip-unreadable] [--skip-symlink [<TYPE>]] [--gtagslibpath <PATH> [<PATH> ...]]
Leaderf[!] gtags [--current-buffer | --all-buffers | --all] [--result <FORMAT>] [COMMON_OPTIONS]
Leaderf[!] gtags -d <PATTERN> [--auto-jump [<TYPE>]] [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>]
                 [--append] [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -r <PATTERN> [--auto-jump [<TYPE>]] [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>]
                 [--append] [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -s <PATTERN> [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>] [--append]
                 [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -g <PATTERN> [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>] [--append]
                 [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags --by-context [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>] [--append]
                 [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]

[COMMON_OPTIONS]: [--reverse] [--stayOpen] [--input <INPUT> | --cword]
                  [--top | --bottom | --left | --right | --belowright | --aboveleft | --fullScreen]
                  [--nameOnly | --fullPath | --fuzzy | --regexMode] [--nowrap]
 

optional arguments:
  -h, --help            show this help message and exit

specific arguments:
  --update              Create tag files if tag files do not exist, update the tag files otherwise.
  --remove              Remove the tag files generated.
  --accept-dotfiles     Accept files and directories whose names begin with a dot. By default, gtags
                        ignores them.
  --skip-unreadable     Skip unreadable files.
  --gtagsconf <FILE>    Set environment variable GTAGSCONF to <FILE>.
  --gtagslabel <LABEL>  Set environment variable GTAGSLABEL to <LABEL>.
  --skip-symlink [<TYPE>]
                        Skip symbolic links. If type is 'f' then skip only symbolic links for file, else
                        if 'd' then skip only symbolic links for directory. The default value of type is
                        'a' (all symbolic links).
  --gtagslibpath <PATH> [<PATH> ...]
                        Specify the paths to search for library functions.
  -d <PATTERN>, --definition <PATTERN>
                        Show locations of definitions.
  -r <PATTERN>, --reference <PATTERN>
                        Show reference to a symbol which has definitions.
  -s <PATTERN>, --symbol <PATTERN>
                        Show reference to a symbol which has no definition.
  -g <PATTERN>, --grep <PATTERN>
                        Show all lines which match to the <PATTERN>.
  --by-context          Decide tag type by context at cursor position. If the context is a definition of
                        the pattern then use -r, else if there is at least one definition of the pattern
                        then use -d, else use -s. Regular expression is not allowed for pattern.
  -i, --ignore-case     Ignore case distinctions in the pattern.
  --literal             Execute literal search instead of regular expression search.
  --path-style <FORMAT>
                        Show path names using <FORMAT>, which may be one of: `relative`, `absolute`,
                        `shorter`, `abslib` or `through`. `relative` means relative path. `absolute`
                        means absolute path. `shorter` means the shorter one of relative and absolute
                        path. `abslib` means absolute path for libraries (GTAGSLIBPATH) and relative path
                        for the rest. `through` means the relative path from the project root directory
                        (internal format of GPATH). The default is `relative`.
  -S <DIR>, --scope <DIR>
                        Show only tags which exist under <DIR> 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 <FORMAT>     Show result using format, which may be one of: `ctags`(default), `ctags-x`,
                        `ctags-mod`.
  --auto-jump [<TYPE>]  Jump to the tag directly when there is only one match. <TYPE> can be 'h', 'v' or
                        't', which mean jump to a horizontally, vertically split window, or a new tabpage
                        respectively. If <TYPE> 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 <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鍵在兩個模式間來回切換。github

手動生成gtags數據庫

Leaderf[!] gtags --update [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [--accept-dotfiles]
                 [--skip-unreadable] [--skip-symlink [<TYPE>]] [--gtagslibpath <PATH> [<PATH> ...]]
複製代碼

此命令徹底異步,不會卡住你的UI。正則表達式

  1. --gtagsconf <FILE>數據庫

    用來指定 gtags.conf 文件的路徑,通常狀況下不須要指定,默認值就能夠很好地工做。對於Windows上,若是相對於gtags.exe所在路徑有../share/gtags/gtags.conf,也不須要指定該選項。若是須要用戶本身特有的針對 gtags 的配置,能夠指定用戶的配置文件。express

    也能夠在vimrc裏設置g:Lf_Gtagsconf達到一樣的目的。vim

  2. --gtagslabel <LABEL>bash

    用來指定gtagslabel,若是不指定,默認值是 'default'<LABEL>gtags.conf 中的:app

    • 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達到一樣的目的。

  3. --gtagslibpath <PATH> [<PATH> ...]

    用來指定項目所用 library 的 Paths,這樣就能夠生成 library 的索引,查找定義或引用時能夠跳轉到 library 代碼中去。後面指定的路徑還能夠是一個或多個其餘項目路徑,跳轉時能夠跳到其餘項目中的文件。

查找tags

Leaderf[!] gtags [--current-buffer | --all-buffers | --all] [--result <FORMAT>] [COMMON_OPTIONS]
複製代碼

此命令能夠列出當前buffer、全部打開的buffer或者整個項目的tags。

  1. Leaderf[!] gtags等同於Leaderf[!] gtags --all,列出整個項目的tags。
  2. --result <FORMAT> 指定顯示格式,能夠是ctags(default), ctags-x或者ctags-mod
    • ctags格式
      ctags格式
    • ctags-x格式
      ctags-x格式
    • ctags-mod格式
      ctags-mod格式

查找定義、引用

Leaderf[!] gtags -d <PATTERN> [--auto-jump [<TYPE>]] [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>]
                 [--append] [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
Leaderf[!] gtags -r <PATTERN> [--auto-jump [<TYPE>]] [-i] [--literal] [--path-style <FORMAT>] [-S <DIR>]
                 [--append] [--match-path] [--gtagsconf <FILE>] [--gtagslabel <LABEL>] [COMMON_OPTIONS]
複製代碼
  1. <PATTERN>能夠是正則表達式。
  2. --auto-jump [<TYPE>] 意思是若是隻有一個結果直接跳過去。

其餘

  1. Leaderf[!] gtags -g <PATTERN>功能已被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 <leader>fr :<C-U><C-R>=printf("Leaderf! gtags -r %s --auto-jump", expand("<cword>"))<CR><CR>
noremap <leader>fd :<C-U><C-R>=printf("Leaderf! gtags -d %s --auto-jump", expand("<cword>"))<CR><CR>
noremap <leader>fo :<C-U><C-R>=printf("Leaderf! gtags --recall %s", "")<CR><CR>
noremap <leader>fn :<C-U><C-R>=printf("Leaderf gtags --next %s", "")<CR><CR>
noremap <leader>fp :<C-U><C-R>=printf("Leaderf gtags --previous %s", "")<CR><CR>
複製代碼
相關文章
相關標籤/搜索