Подтвердить что ты не робот

Как автоматически обновить файл тега в vim?

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

Я уже написал плагин, чтобы выполнить всю сложную работу с 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

Ответ 4

Идея:

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

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

Edit:

Что-то подобное было задано здесь заранее, см. Vim auto-generate ctags

Ответ 5

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

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