Ctrl-]を使用したナビゲーションにはvimC++タグファイルを使用します。問題は、一部のファイルが変更されるたびに、リンクが無効になり、ctagsを再実行してタグファイルを更新する必要があることです。私たちのコードベースは巨大で、タグファイルの生成にはかなりの時間がかかります。
バックグラウンドでタグファイルを定期的に更新するツールはありますか?同じことをするようにVIMを設定できますか?
私はWindowsでgvimを使用しています。
Blixtor の回答に加えて、スクリプトの設計について少し慎重に考える必要があります。自動コマンドが Windows の「開始」コマンドなどを使用してバックグラウンドで外部スクリプトを実行するように設計を分離することをお勧めします。これにより、タグ ファイルの生成中に Vim が応答しなくなるのを防ぐことができます。
そのスクリプトは、別のファイル名 (つまり、"tags": ではないctags -R -o newtags .
) を使用してタグ ファイルを生成し、ctags が完了したら、削除tags
して名前を に変更newtags
しtags
ます。これにより、生成中にタグファイルが Vim で使用できなくなるのを防ぐことができます。
まさにこれを行うためにvim -easytagsプラグインを作成しました。プロジェクト全体をスキャンして (コマンド:UpdateTags **/*.[hc]
などを使用して) タグ ファイルを 1 回初期化すると、その後、プラグインは編集時にタグ ファイルと:update
Vim のソース コード ファイルを自動的に更新します。タグ ファイルを更新している間は Vim をブロックしますが、現在のファイルのみをスキャンするため、それほど時間はかかりません。
更新 (2014-07-30):まだ vim-easytags プラグインに取り組んでいます :-)。最近では、Vim のブロックを回避するために非同期モードがサポートされています。私がこれを書いている時点では、非同期モードはまだデフォルトのモードではありませんが、もう少しフィードバックがあれば、おそらくデフォルトのモードに切り替えるでしょう。
私はすでに 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 ライオン
アイデア:
BufWritePost イベントを使用してバッファーが保存されるたびにスクリプトの実行をトリガーするには、Vim 自動コマンド (:help autocommand) を使用します。
このスクリプトは、ctags の生成を開始し、既に実行されている間は実行されないようにする (または最大で 10 分ごとに実行するなど) いくつかの追加の小さなロジックを含んでいます。
編集:
同様の質問が事前にここで行われました。Vim auto-generate ctagsを参照してください。
このロジックはほとんどの場合に機能します。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()
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()