轉載: https://zhuanlan.zhihu.com/p/43671939
一、概述
在常規的使用ctags生成tag標簽文件實現跳轉的方式下,每次需要更新tags文件時都需要手工運行 ctags -R
生成當前項目所有源文件對應的tag標簽文件。
當工程文件多、文件更新頻繁時,上述生成tags文件的方法顯得笨拙、低效。
得益於 Vim 8 提供的異步機制,vim插件vim-gutentags能夠自動異步生成 tags 文件,當檢測到同一個工程下面的文件有修改時,gutentags能自動增量更新對應工程的 tags 文件,而不用全部重新生成tags文件,是一個非常高效的tags生成工具。
二、安裝
2.1 軟件依賴
vim-gutentags的本質仍然是使用ctags生成tag標簽來實現函數跳轉等功能,只是在ctags的基礎上進行了封裝和簡化(具體封裝方式在后文有簡單分析),方便用戶在vim中使用。
由於vim-gutentags依賴ctags工具,因此在使用vim-gutentags插件的系統中必須安裝ctags軟件,否則會報錯"Excutable 'ctags' can't be found."。
關於ctags的介紹和安裝方法,可以參考vim教程網上的文章Vim使用ctags實現函數跳轉。
其次,vim-gutentags需要在vim8.0以上版本才能正常工作,因為vim-gutentags實現的是增量更新tags的方式,依賴於vim8提供的異步機制。
在低於vim8.0的版本是運行vim-gutentags插件,會報錯"this plugin requires the job API from Vim8 or Neovim"。
關於vim8的編譯和安裝,可以參考vim教程網上的文章vim安裝教程。
2.2 gutentags安裝方法
本文介紹使用插件管理器vim-plug安裝vim-gutentags插件。
在配置文件 ~/.vimrc
中增加配置項 Plug 'ludovicchabant/vim-gutentags'
后再在vim命令行模式下執行命令 :PlugInstall
即可完成vim-gutentags插件的安裝。
三、vim-gutentags配置介紹和原理分析
vim-gutentags插件的基本工作原理可以這么理解:首先確定vim當前打開的文件是否需要自動生成tags標簽,若需要則通過某種方式確定tag文件的路徑,再基於tag標簽文件完成函數跳轉、結構體定義跳轉等功能。
因此,vim-gutentags需要確定是否需要生成tags標簽文件,又需要告訴ctags軟件自身生成的tags文件的具體路徑信息 (因為從Vim使用ctags實現函數跳轉一文已知,默認情況下,生成的tags文件必須在vim運行的當前目錄才能在vim里面正確跳轉)。
3.1 gutentags配置
為了提供上述信息給vim-gutentags,安裝完gutentags后,需要在vim配置文件中增加以下必要的配置項。
" gutentags搜索工程目錄的標志,碰到這些文件/目錄名就停止向上一級目錄遞歸 " let g:gutentags_project_root = ['.root', '.svn', '.git', '.project'] " 所生成的數據文件的名稱 " let g:gutentags_ctags_tagfile = '.tags' " 將自動生成的 tags 文件全部放入 ~/.cache/tags 目錄中,避免污染工程目錄 " let s:vim_tags = expand('~/.cache/tags') let g:gutentags_cache_dir = s:vim_tags " 檢測 ~/.cache/tags 不存在就新建 " if !isdirectory(s:vim_tags) silent! call mkdir(s:vim_tags, 'p') endif " 配置 ctags 的參數 " let g:gutentags_ctags_extra_args = ['--fields=+niazS', '--extra=+q'] let g:gutentags_ctags_extra_args += ['--c++-kinds=+pxI'] let g:gutentags_ctags_extra_args += ['--c-kinds=+px']
- 變量
gutentags_project_root
是vim-gutentags提供的用於搜索工程目錄的標志,gutentags插件啟動后,會從文件當前路徑遞歸往上查找gutentags_project_root
中指定的文件或目錄名,直到第一次找到對應目標文件或目錄名停止。若沒有找到gutentags_project_root
變量指定的文件或目錄名,則gutentags不會生成tag文件。
- 變量
gutentags_ctags_tagfile
和gutentags_cache_dir
分別用於告訴ctags要使用的tag文件目錄和tag文件名后綴,tag文件名的生成規則默認是根據生成tag文件的工程絕對路徑按 - 分割而成。
- 變量
gutentags_ctags_extra_args
用於配置ctags生成tag標簽的參數,具體參數含義可參考文章ctags參數介紹
所以,上面的gutentags配置指定了從當前路徑向上遞歸查找是否有 .root
、.svn
、 .git
、.project
等標志性文件來確定當前文檔所屬的工程目錄;而ctags要使用的tag標簽文件的路徑為 ~/.cache/tags
,文件后綴為 .tags
。
ctags 軟件需要使用命令 :set tags+=tags文件路徑
顯式地指定tag文件路徑,從文件 ~/plugged/vim-gutentags/autoload/gutentags/ctags.vim
可以看出,gutentags執行了命令 setlocal tags+=
來添加變量 gutentags_ctags_tagfile
指定的tag文件到局部 tags 搜索列表中。
3.2 gutentags示例
安裝了gutentags並且進行了上面的設置后,平時打開vim編輯文件基本感覺不到 tags 文件的生成過程了,只要文件修改過,gutentags 都在后台默默分析是否需要更新數據文件,還會幫你:setlocal tags+=... 添加到局部 tags 搜索列表中。得益於 Vim 8 的異步機制,你可以任意隨時使用 ctags 相關功能,並且數據庫都是最新的。
就像下面的vim視頻教程一樣,假設已經在vim配置文件中添加了上面的配置項,在當前目錄新建文件 .project
后再打開當前目錄下的任意文件,再退出vim后可以看到,gutentags已經為當前目錄生成了tags文件 ~/.cache/tags/home-vim-vim.ink-libevent-.tags
。
需要注意的是,gutentags 需要靠上面定義的 gutentags_project_root
判斷文件所在的工程,如果一個文件沒有保存在包含 .git
、.svn
、.root
等 定義在 gutentags_project_root
中的文件,gutentags就不會為該野文件生成 tags。
想要避免的話,你可以在你的野文件目錄中放一個名字為 .root
的空白文件,主動告訴 gutentags 這里就是工程目錄。
3.3 基於gutentags實現跳轉
在為當前目錄生成tags文件后,可以通過按鍵 Ctrl + ]
跳轉到對應的定義位置,再使用命令 Ctrl + o
回退到原來的位置。關於跳轉的具體應用,可以參考Vim使用ctags實現函數跳轉

另外,建議多使用 Ctrl - W + ]
用新窗口打開並查看光標下符號的定義,或者 Ctrl -W }
使用 preview 窗口預覽光標下符號的定義。
PS:本文首發於我的個人博客:Vim自動生成tags插件vim-gutentags安裝和自動跳轉方法-Vim插件(10),部分內容參考了
的回答,感謝。