Как автоматически обновить файл тега в vim? - PullRequest
35 голосов
/ 21 июля 2009

Я использую файл тега vim C ++ для навигации по Ctrl-]. Проблема в том, что всякий раз, когда какой-либо файл изменяется, ссылки больше не действительны, и мне приходится повторно запускать ctags и обновлять файл тегов. Наша кодовая база огромна, и генерация файла тегов занимает много времени.

Существует ли какой-либо инструмент, который периодически обновляет файл тега в фоновом режиме? Могу ли я настроить VIM так же?

Я использую gvim под Windows.

Ответы [ 7 ]

26 голосов
/ 21 июля 2009

В дополнение к ответу Blixtor вам нужно немного подумать о дизайне сценария. Я бы рекомендовал разделить дизайн так, чтобы автокоманда использовала команду Windows «Пуск» или аналогичную для запуска внешнего сценария в фоновом режиме : таким образом, предотвращая перехват Vim во время создания файла тегов.

Затем этот сценарий может сгенерировать файл тегов, используя другое имя файла (т.е. не «теги»: ctags -R -o newtags .), и, когда ctags завершится, удалить tags и переименовать newtags в tags. Это предотвратит недоступность файла тегов в Vim во время генерации.

20 голосов
/ 15 января 2012

Я написал плагин vim-easytags , чтобы сделать именно это. Я инициализирую файл тегов один раз, сканируя весь проект (например, с помощью команды :UpdateTags **/*.[hc]), а затем плагин автоматически обновляет файл тегов при редактировании и :update мои файлы исходного кода в Vim. Обновляя файл тегов, он блокирует Vim, но, поскольку он сканирует только текущий файл, это не займет много времени.

Обновление (2014-07-30): Все еще работает над плагином vim-easytags :-). В настоящее время он поддерживает асинхронный режим, чтобы избежать блокировки Vim. В то время, когда я пишу это, асинхронный режим еще не является режимом по умолчанию, но после некоторой обратной связи я, вероятно, переключу режим по умолчанию.

11 голосов
/ 18 апреля 2012

Я уже написал плагин для выполнения всей тяжелой работы с 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

  • Windows XP

  • Mac OS X Lion

9 голосов
/ 21 июля 2009

Идея:

Используйте автокоманды Vim (: help autocommand), чтобы запускать скрипт при каждом сохранении буфера с помощью события BufWritePost.

Этот скрипт запускает генерацию ctags и содержит некоторую дополнительную небольшую логику, которая не запускается, пока она уже запущена (или запускается не чаще, чем каждые 10 минут и т.

Edit:

Нечто подобное было задано здесь заранее, см. Vim, автоматически генерирующий ctags

3 голосов
/ 15 апреля 2018

Из своего репозитория: vim-gutentags - это плагин, который заботится о столь необходимом управлении файлами тегов в Vim. Он будет (повторно) генерировать файлы тегов, пока вы работаете, оставаясь при этом полностью в стороне. Он даже сделает все возможное, чтобы эти файлы тегов не попали на ваш путь. Он не имеет зависимостей и просто работает.

Вы можете попробовать на https://github.com/ludovicchabant/vim-gutentags.

1 голос
/ 25 июля 2013

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()
1 голос
/ 20 февраля 2010

Эта логика работает в большинстве случаев: при открытии нового файла в 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()
...