代码之家  ›  专栏  ›  技术社区  ›  Canopus

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

  •  34
  • Canopus  · 技术社区  · 15 年前

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

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

    我用玻璃窗下的玻璃。

    7 回复  |  直到 6 年前
        1
  •  26
  •   DrAl    15 年前

    对于Blixtor的答案,您需要仔细考虑一下脚本的设计。我建议分离设计,这样自动命令使用Windows“Start”命令或类似命令来运行外部脚本 在背景中 :从而防止在生成标记文件时VIM没有响应。

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

        2
  •  20
  •   xolox    10 年前

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

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

        3
  •  11
  •   Dmitry Frank    9 年前

    我已经写了一个插件来完成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: convenient code navigation for your projects 这充分解释了索引器+VIMPRJ的用法。

    它在以下系统的VIM 7.3上成功测试:

    • 古Linux

    • Ubuntu 10.4

    • 视窗XP

    • 狮子系统

        4
  •  9
  •   Community basarat    7 年前

    一个想法:

    每次使用bufWritePost事件保存缓冲区时,使用vim autocommands(:help autocommand)触发脚本运行。

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

    编辑:

    之前这里也有类似的问题,请看 Vim auto-generate ctags

        5
  •  2
  •   Huy Vo    6 年前

    从其存储库中: vim-gutentags 是一个插件,它负责管理VIM中非常需要的标记文件。它会在你工作的时候重新生成标签文件,同时完全不妨碍你的工作。它甚至会尽最大努力让这些标签文件远离你的方式。它没有依赖性,只起作用。

    你可以试试看 https://github.com/ludovicchabant/vim-gutentags .

        6
  •  1
  •   user15071    14 年前

    这种逻辑适用于大多数情况:当在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()
    
        7
  •  1
  •   Sergei Struk    11 年前

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