web-dev-qa-db-ja.com

vimでタグファイルを自動的に更新する方法

Ctrl-]を使用したナビゲーションには、vim C++タグファイルを使用します。問題は、一部のファイルが変更されるたびにリンクが無効になり、ctagsを再実行してタグファイルを更新する必要があることです。私たちのコードベースは巨大で、タグファイルを生成するのにかなり時間がかかります。

バックグラウンドでタグファイルを定期的に更新するツールはありますか? VIMを同じように構成できますか?

Windowsではgvimを使用しています。

35
Canopus

Blixtorの答えに加えて、スクリプトのデザインについて少し慎重に考える必要があります。自動コマンドがWindowsの「開始」コマンドなどを使用して外部スクリプトを実行するように、デザインを分離することをお勧めします バックグラウンドで:タグファイルの生成中にVimが応答しなくなるのを防ぎます。

そのスクリプトは、別のファイル名を使用してタグファイルを生成できます(つまり、「タグ」ではありません:ctags -R -o newtags .)そして、ctagsが完了したら、tagsを削除し、newtagstagsに名前変更します。これにより、生成が完了する間、Vimでタグファイルが使用できなくなります。

26
DrAl

これを正確に行うために vim-easytags プラグインを作成しました。プロジェクト全体をスキャンして(たとえば、コマンド:UpdateTags **/*.[hc]を使用して)タグファイルを一度初期化します。その後、プラグインは、編集時にタグファイルを自動的に更新し、Vimでソースコードファイルを:update更新します。タグファイルを更新している間はVimをブロックしますが、現在のファイルをスキャンするだけなので、それほど時間はかかりません。

更新(2014-07-30):vim-easytagsプラグインで作業中です:-)。今日では、Vimのブロックを回避するために非同期モードをサポートしています。これを書いている時点では、非同期モードはまだデフォルトモードではありませんが、さらにフィードバックがあったら、おそらくデフォルトモードに切り替えます。

21
xolox

私はすでに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:プロジェクトの便利なコードナビゲーション を参照してください。これは、インデクサー+ Vimprjの使用方法を完全に説明しています。

次のシステムのVim 7.3で正常にテストされています。

  • Archlinux

  • Ubuntu 10.4

  • Windows XP

  • Mac OS X Lion

11
Dmitry Frank

アイデア:

Vim自動コマンド(:help autocommand)を使用して、BufWritePostイベントを使用してバッファーが保存されるたびにスクリプトの実行をトリガーします。

このスクリプトはctags生成を開始し、すでに実行中(または最大10分ごとなど)に実行されないようにいくつかの小さなロジックを追加で含みます。

編集:

同様の何かが事前にここで尋ねられました、 Vim auto-generate ctags を参照してください

9
Blixtor

そのリポジトリから:vim-gutentagsは、Vimで必要なタグファイルの管理に必要なプラグインです。完全に邪魔にならないようにしながら、作業中にタグファイルを(再)生成します。これらのタグファイルも邪魔にならないように最善を尽くします。依存関係はなく、機能します。

https://github.com/ludovicchabant/vim-gutentags で試してみることができます。

3
Huy Vo

このロジックはほとんどの場合に機能します。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()
1
user15071

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
Sergei Struk