37

我使用 vim C++ 标记文件使用 Ctrl-] 进行导航。问题是每当修改某些文件时,链接不再有效,我必须重新运行 ctags 并更新标记文件。我们的代码库很大,生成标签文件需要很长时间。

是否有任何工具可以在后台定期更新标签文件?我可以配置 VIM 来做同样的事情吗?

我在 Windows 下使用 gvim。

4

7 回答 7

26

除了 Blixtor 的回答之外,您还需要仔细考虑脚本的设计。我建议分离设计,以便自动命令使用 Windows“启动”命令或类似命令在后台运行外部脚本:从而防止 Vim 在生成标记文件时无响应。

然后,该脚本可以使用不同的文件名(即不是“tags”:)生成标记文件ctags -R -o newtags .,并且当 ctags 完成时,删除tags并重命名newtagstags. 这将防止标签文件在生成完成时在 Vim 中不可用。

于 2009-07-21T07:18:52.843 回答
24

我编写了vim-easytags插件就是为了做到这一点。我通过扫描整个项目(:UpdateTags **/*.[hc]例如使用命令)初始化我的标签文件一次,然后插件将在我编辑时自动更新标签文件和:update我在 Vim 中的源代码文件。虽然它会更新标签文件,但它会阻止 Vim,但因为它只扫描当前文件,所以不会花很长时间。

更新 (2014-07-30):仍在使用 vim-easytags 插件:-)。现在它支持异步模式以避免阻塞 Vim。在我写这篇文章的时候,异步模式还不是默认模式,但经过更多反馈后,我可能会切换默认模式。

于 2012-01-15T00:32:45.957 回答
12

我已经编写了一个插件来使用 ctags 完成所有艰巨的工作:Indexer

它为整个项目提供了无痛的自动标签生成,并使标签保持最新。标签是在后台生成的,因此您不必等待 ctags 生成标签。您可以独立使用它,也可以作为另一个插件project.tar.gz的附加组件。

在第一种方式中,您可以~/.indexer_files像这样声明您的项目:

[CoolProject]

/home/user/cool_project

[AnotherProject]
option:ctags_params = "--languages=c++"

/home/user/another_project/src
/home/user/another_project/lib 

然后,当您从 中打开任何文件时/home/user/cool_project,所有该项目都将被 ctags 索引。当您从另一个项目打开标签时,也会为其生成标签。来自不同项目的标签永远不会混合。当您从项目中保存文件时,标签会静默更新。你不必关心它,它只是工作。

有关详细信息,请参阅文章:Vim:为您的项目提供方便的代码导航,其中详细解释了 Indexer + Vimprj 的用法。

它在 Vim 7.3 上成功测试,在以下系统上:

  • Archlinux

  • Ubuntu 10.4

  • 视窗

  • Mac OS X 狮子

于 2012-04-18T06:03:16.237 回答
9

一个想法:

每次使用 BufWritePost 事件保存缓冲区时,使用 Vim 自动命令 (:help autocommand) 触发脚本运行。

该脚本启动 ctags 生成并包含一些额外的小逻辑,在它已经运行时不运行(或最多每 10 分钟运行一次,等等)。

编辑:

事先在这里问过类似的问题,请参阅Vim auto-generate ctags

于 2009-07-21T06:22:05.453 回答
5

来自它的存储库:vim-gutentags是一个插件,负责管理 Vim 中非常需要的标签文件。它会在您工作时(重新)生成标签文件,同时完全不妨碍您。它甚至会尽最大努力让这些标签文件远离你。它没有依赖关系并且可以正常工作。

您可以在https://github.com/ludovicchabant/vim-gutentags尝试一下。

于 2018-04-15T10:38:49.383 回答
1

这个逻辑适用于大多数情况:当在 vim 中打开一个新文件时,切换到该文件的目录并在那里生成一个标签文件,如果它不存在的话。保存更改的缓冲区时,在正在保存的文件的目录中生成标签文件:


function! GenerateTagsFile()
  if (!filereadable("tags"))
    exec ":!start /min ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --sort=foldcase ."
  endif
endfunction

" Always change to directory of the buffer currently in focus.
autocmd! bufenter *.* :cd %:p:h
autocmd! bufread  *.* :cd %:p:h

" Generate tags on opening an existing file.
autocmd! bufreadpost *.cpp :call GenerateTagsFile()
autocmd! bufreadpost *.c   :call GenerateTagsFile()
autocmd! bufreadpost *.h   :call GenerateTagsFile()

" Generate tags on save. Note that this regenerates tags for all files in current folder.
autocmd! bufwritepost *.cpp :call GenerateTagsFile()
autocmd! bufwritepost *.c   :call GenerateTagsFile()
autocmd! bufwritepost *.h   :call GenerateTagsFile()
于 2010-02-20T09:45:11.853 回答
1

http://vim.wikia.com/wiki/Autocmd_to_update_ctags_file

function! DelTagOfFile(file)
  let fullpath = a:file
  let cwd = getcwd()
  let tagfilename = cwd . "/tags"
  let f = substitute(fullpath, cwd . "/", "", "")
  let f = escape(f, './')
  let cmd = 'sed -i "/' . f . '/d" "' . tagfilename . '"'
  let resp = system(cmd)
endfunction

function! UpdateTags()
  let f = expand("%:p")
  let cwd = getcwd()
  let tagfilename = cwd . "/tags"
  let cmd = 'ctags -a -f ' . tagfilename . ' --c++-kinds=+p --fields=+iaS --extra=+q ' . '"' . f . '"'
  call DelTagOfFile(f)
  let resp = system(cmd)
endfunction
autocmd BufWritePost *.cpp,*.h,*.c call UpdateTags()
于 2013-07-24T23:37:48.197 回答