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

时间:2009-07-21 05:13:22

标签: vim ctags

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

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

我在Windows下使用gvim。

7 个答案:

答案 0 :(得分:26)

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

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

答案 1 :(得分:20)

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

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

答案 2 :(得分:11)

我已经用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,它详细解释了Indexer + Vimprj的用法。

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

  • 的Archlinux

  • Ubuntu 10.4

  • Windows XP

  • Mac OS X Lion

答案 3 :(得分:9)

一个想法:

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

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

编辑:

事先在此处询问了类似的内容,请参阅Vim auto-generate ctags

答案 4 :(得分:3)

从其存储库:________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv1d_1 (Conv1D) (None, 64, 60) 1980 _________________________________________________________________ conv1d_2 (Conv1D) (None, 64, 80) 48080 _________________________________________________________________ dropout_1 (Dropout) (None, 64, 80) 0 _________________________________________________________________ conv1d_3 (Conv1D) (None, 64, 100) 40100 _________________________________________________________________ max_pooling1d_1 (MaxPooling1 (None, 64, 100) 0 _________________________________________________________________ dropout_2 (Dropout) (None, 64, 100) 0 _________________________________________________________________ dense_1 (Dense) (None, 64, 300) 30300 _________________________________________________________________ dense_2 (Dense) (None, 64, 1) 301 ================================================================= Total params: 120,761 Trainable params: 120,761 Non-trainable params: 0 _________________________________________________________________ None Traceback (most recent call last): File "processing_2a_1.py", line 125, in <module> history=model.fit(X_train, Y_train, batch_size=batch_size, validation_data=(X_val,Y_val), epochs=nr_of_epochs,verbose=2) File "build/bdist.linux-x86_64/egg/keras/models.py", line 871, in fit File "build/bdist.linux-x86_64/egg/keras/engine/training.py", line 1524, in fit File "build/bdist.linux-x86_64/egg/keras/engine/training.py", line 1382, in _standardize_user_data File "build/bdist.linux-x86_64/egg/keras/engine/training.py", line 132, in _standardize_input_data ValueError: Error when checking target: expected dense_2 to have 3 dimensions, but got array with shape (1496000, 1) 是一个插件,负责管理Vim中标签文件的急需管理。它将(重新)生成标记文件,同时保持完全不受影响。它甚至会尽力保持这些标记文件不受影响。它没有依赖关系,只是起作用。

您可以尝试https://github.com/ludovicchabant/vim-gutentags

答案 5 :(得分: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()

答案 6 :(得分: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()
相关问题