如何在vim中自动更新标签文件?

发布于 2024-07-27 23:58:35 字数 195 浏览 4 评论 0原文

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

有没有什么工具可以在后台定期更新标签文件? 我可以配置 VIM 来执行相同的操作吗?

我在Windows下使用gvim。

I use vim C++ tag file for navigation using Ctrl-]. The problem is whenever some file gets modified, the links are no longer valid and I have to re-run ctags and update the tag file. Our code base is huge and it takes quite a while for generating tag file.

Is there any tool which periodically updates the tag file in background? Can I configure VIM to do the same?

I use gvim under Windows.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

智商已欠费 2024-08-03 23:58:35

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

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

Further to Blixtor's answer, you'll need to think a little carefully about the design of the script. I'd recommend segregating the design such that the autocommand uses the Windows "start" command or similar to run an external script in the background: thereby preventing Vim from being unresponsive while the tag file is generated.

That script could then generate the tag file using a different file name (i.e. not "tags": ctags -R -o newtags .) and, when ctags is complete, delete tags and rename newtags to tags. This will prevent the tag file from being unavailable in Vim while the generation is done.

梦魇绽荼蘼 2024-08-03 23:58:35

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

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

I wrote the vim-easytags plug-in to do exactly this. I initialize my tags file once by scanning a whole project (using the command :UpdateTags **/*.[hc] for example) and afterwards the plug-in will automatically update the tags file as I edit and :update my source code files in Vim. While it updates the tags file it will block Vim, but because it only scans the current file it doesn't take long.

Update (2014-07-30): Still working on the vim-easytags plug-in :-). Nowadays it supports an asynchronous mode to avoid blocking Vim. At the time I write this the asynchronous mode is not the default mode yet, but after some more feedback I'll probably switch the default mode.

可爱咩 2024-08-03 23:58:35

我已经编写了一个插件来使用 ctags 完成所有艰苦的工作:索引器

它为整个项目提供轻松的自动标签生成,并保持标签最新。 标签是在后台生成的,因此,您无需等待 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

  • Windows XP

  • Mac OS X狮子

I already wrote a plugin to do all the hard job with ctags: Indexer.

It provides painless automatic tags generation for the whole project(s) and keeps tags up-to-date. Tags is generated in background, so, you do not have to wait while ctags generates tags. You can use it independently or as an add-on for another plugin project.tar.gz.

In the first way, you can declare your projects in ~/.indexer_files like this:

[CoolProject]

/home/user/cool_project

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

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

And then, when you open any file from /home/user/cool_project , all this project will be indexed by ctags. When you open tags from another project, tags is generated for it too. Tags from different projects is never mixed. When you save file from project, tags is silently updated. You do not have to care about it, it just works.

For detailed information, see the article: Vim: convenient code navigation for your projects, which explains the usage of Indexer + Vimprj thoroughly.

It is successfully tested on Vim 7.3, on the following systems:

  • Archlinux

  • Ubuntu 10.4

  • Windows XP

  • Mac OS X Lion

你怎么这么可爱啊 2024-08-03 23:58:35

一个想法:

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

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

编辑:

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

An idea:

Use Vim autocommands (:help autocommand) to trigger running of a script every time a buffer is saved using the BufWritePost event.

This script starts the ctags generation and contains some additional small logic to not run while it's already running (or to run at most every 10 minutes, etc.).

Edit:

Something similar was asked here beforehand, see Vim auto-generate ctags

半暖夏伤 2024-08-03 23:58:35

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

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

From its repository: vim-gutentags is a plugin that takes care of the much needed management of tags files in Vim. It will (re)generate tag files as you work while staying completely out of your way. It will even do its best to keep those tag files out of your way too. It has no dependencies and just works.

You can give it a try at https://github.com/ludovicchabant/vim-gutentags.

川水往事 2024-08-03 23:58:35

此逻辑适用于大多数情况:在 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()

This logic works for most cases: When opening a new file in vim, change to the directory of that file and generate a tags file there if it does not already exist. When saving a changed buffer, generate a tags file in the directory of the file being saved:


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()
梨涡 2024-08-03 23:58:35

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()

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()
原来分手还会想你 2024-08-03 23:58:35

我发现这非常简单且有用:

  1. cd 进入代码目录。
  2. ctags -R

I found this really simple and useful:

  1. cd into the code directory.
  2. ctags -R
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文