質問
今、 .vimrc
に次のものがあります:
au BufWritePost *.c,*.cpp,*.h !ctags -R
これにはいくつかの問題があります:
- 遅い-最後のタグの生成以降に変更されていないファイルのタグを再生成します。
- 避けられない" Enterを押すか続行するコマンドを入力する"のため、ファイルを書き込んだ後にEnterボタンをもう一度押す必要があります。
これら2つの問題を組み合わせると、( ctags -R
が終了する前に)追加のEnterキーを押しすぎてしまい、面倒なエラーメッセージが表示され、Enterキーをもう一度押す必要があります。
それは大したことではないように聞こえますが、特定の日に行うファイル書き込みの量が多いと、本当に迷惑になる傾向があります。もっと良い方法があります!
解決
au BufWritePost * .c、*。cpp、*。h silent! !ctags -R&
欠点は、完成するまで便利なタグファイルがないことです。 * nixシステムを使用している限り、以前のctagsが完了する前に複数の書き込みを行っても問題ありませんが、テストする必要があります。 Windowsシステムでは、バックグラウンドに配置されず、最初のctagsが終了するまでファイルがロックされていると文句を言います(vimで問題は発生しませんが、わずかに古いタグファイルになります) )。
注、tonyloが示唆するように-append
オプションを使用できますが、 tagbsearch
を無効にする必要があります。これは、タグの検索に時間がかかることを意味します、タグファイルのサイズに応じて。
他のヒント
編集:次の行に沿ったソリューションは、 AutoTag vimスクリプト。ただし、スクリプトは Pythonサポート付きのvimが必要であることに注意してください。
代わりに私のソリューションはawkにシェルアウトするため、より多くのシステムで動作するはずです。
au FileType {c,cpp} au BufWritePost <buffer> silent ! [ -e tags ] && \ ( awk -F'\t' '$2\!="%:gs/'/'\''/"{print}' tags ; ctags -f- '%:gs/'/'\''/' ) \ | sort -t
は保存したばかりのファイルで呼び出され、結果はスクリプトでこの方法でしか書けないことに注意してください。そうしないと、1行で記述しなければなりません。
そこで多くのことが行われています:
この自動コマンドは、ファイルがCまたはC ++であることが検出されたときにトリガーし、
BufWritePost
イベントによってトリガーされるバッファーローカル自動コマンドを追加します。実行時にバッファのファイル名に置き換えられる
%
プレースホルダーと、シェルに使用される:gs
修飾子を使用します。ファイル名を引用します(埋め込まれた単一引用符を引用エスケープエスケープ引用符に変換します)。その方法で
tags
ファイルが存在するかどうかをチェックするシェルコマンドを実行します。 code> ctagssort
されて元の場所に戻されます。警告実装者:これは、すべてが同じディレクトリにあり、それがバッファローカルの現在のディレクトリであることを前提としています。パスマングリングについては何も考えていません。
\t' -k1,1 -o tags.new && mv tags.new tags
スクリプトでこの方法でしか書けないことに注意してください。そうしないと、1行で記述しなければなりません。
そこで多くのことが行われています:
-
この自動コマンドは、ファイルがCまたはC ++であることが検出されたときにトリガーし、
BufWritePost
イベントによってトリガーされるバッファーローカル自動コマンドを追加します。 -
実行時にバッファのファイル名に置き換えられる
%
プレースホルダーと、シェルに使用される:gs
修飾子を使用します。ファイル名を引用します(埋め込まれた単一引用符を引用エスケープエスケープ引用符に変換します)。 -
その方法で
tags
ファイルが存在するかどうかをチェックするシェルコマンドを実行します。 code> ctags は保存したばかりのファイルで呼び出され、結果はsort
されて元の場所に戻されます。
警告実装者:これは、すべてが同じディレクトリにあり、それがバッファローカルの現在のディレクトリであることを前提としています。パスマングリングについては何も考えていません。
これを行うために easytags.vim を作成しました:自動更新タグを強調表示します。プラグインは、編集中のファイルのみ、または編集中のファイルのディレクトリ内のすべてのファイルを(再帰的に)更新するように構成できます。グローバルタグファイル、ファイルタイプ固有のタグファイル、プロジェクト固有のタグファイルを使用できます。
しかし、これは古いスレッドであることに気づきました... inotifyをサポートする環境のような* nixで incron を使用します。ディレクトリ内のファイルが変更されるたびに、常にコマンドを起動します。つまり、
/home/me/Code/c/that_program IN_DELETE,IN_CLOSE_WRITE ctags --sort=yes *.c
それだけです。
おそらく、次のようにctagsにappend引数を使用します。
http://vim.wikia.com/wiki/Autocmd_to_update_ctags_file
コードブラウジングには一般的にソースインサイトを使用しますが、エディターとしてvimを使用しているため、実際にこれを保証することはできません...図を参照してください。
ctagsをcrontab経由で実行するようスケジュールするのはどうですか?プロジェクトツリーの構造がかなり安定している場合、それは実行可能になりますか?
「Enterキーを押す」を抑制するにはプロンプト、:silent を使用します。
OSXでは、少なくとも私にとっては、このコマンドはそのままでは機能しません。
au BufWritePost *.c,*.cpp,*.h silent! !ctags -R &
投稿を見つけました。 -Rオプションを含む標準ctagsバージョン。これだけではうまくいきませんでした。 Homebrewがプログラムをインストールするビンを取得するために、.bash_profileのPATH変数に/ usr / local / binを追加する必要がありました。
私の意見では、プラグインインデクサーの方が優れています。
http://www.vim.org/scripts/script.php? script_id = 3221
次のいずれかです:
1)project.tar.gzのアドオン
2)独立したプラグイン
- バックグラウンドタグの生成(ctagsが機能するまで待つ必要はありません)
- 複数のプロジェクトをサポート
このための AutoTag というvimプラグインがあります。まあ。
タグリストがインストールされている場合、タグリストも更新されます。
-append
オプションが実際の方法です。 grep -v
とともに使用すると、更新できる tagged ファイルは1つだけです。たとえば、この問題に対処する未研磨のプラグインの抜粋です。 (NB:&quot; external&quot; ライブラリプラグイン
" Options {{{1
let g:tags_options_cpp = '--c++-kinds=+p --fields=+imaS --extra=+q'
function! s:CtagsExecutable()
let tags_executable = lh#option#Get('tags_executable', s:tags_executable, 'bg')
return tags_executable
endfunction
function! s:CtagsOptions()
let ctags_options = lh#option#Get('tags_options_'.&ft, '')
let ctags_options .= ' '.lh#option#Get('tags_options', '', 'wbg')
return ctags_options
endfunction
function! s:CtagsDirname()
let ctags_dirname = lh#option#Get('tags_dirname', '', 'b').'/'
return ctags_dirname
endfunction
function! s:CtagsFilename()
let ctags_filename = lh#option#Get('tags_filename', 'tags', 'bg')
return ctags_filename
endfunction
function! s:CtagsCmdLine(ctags_pathname)
let cmd_line = s:CtagsExecutable().' '.s:CtagsOptions().' -f '.a:ctags_pathname
return cmd_line
endfunction
" ######################################################################
" Tag generating functions {{{1
" ======================================================================
" Interface {{{2
" ======================================================================
" Mappings {{{3
" inoremap <expr> ; <sid>Run('UpdateTags_for_ModifiedFile',';')
nnoremap <silent> <Plug>CTagsUpdateCurrent :call <sid>UpdateCurrent()<cr>
if !hasmapto('<Plug>CTagsUpdateCurrent', 'n')
nmap <silent> <c-x>tc <Plug>CTagsUpdateCurrent
endif
nnoremap <silent> <Plug>CTagsUpdateAll :call <sid>UpdateAll()<cr>
if !hasmapto('<Plug>CTagsUpdateAll', 'n')
nmap <silent> <c-x>ta <Plug>CTagsUpdateAll
endif
" ======================================================================
" Auto command for automatically tagging a file when saved {{{3
augroup LH_TAGS
au!
autocmd BufWritePost,FileWritePost * if ! lh#option#Get('LHT_no_auto', 0) | call s:Run('UpdateTags_for_SavedFile') | endif
aug END
" ======================================================================
" Internal functions {{{2
" ======================================================================
" generate tags on-the-fly {{{3
function! UpdateTags_for_ModifiedFile(ctags_pathname)
let source_name = expand('%')
let temp_name = tempname()
let temp_tags = tempname()
" 1- purge old references to the source name
if filereadable(a:ctags_pathname)
" it exists => must be changed
call system('grep -v " '.source_name.' " '.a:ctags_pathname.' > '.temp_tags.
\ ' && mv -f '.temp_tags.' '.a:ctags_pathname)
endif
" 2- save the unsaved contents of the current file
call writefile(getline(1, '
このコードは以下を定義します:
-
^ Xta
を使用して、現在のプロジェクトのすべてのファイルのタグベースを強制的に更新します。
-
^ Xtc
を使用して、現在の(保存されていない)ファイルのタグベースを強制的に更新します。
- ファイルが保存されるたびにタグベースを更新する自動コマンド。
また、ファイルタイプに応じてctags呼び出しを調整するために、自動更新を無効にする多くのオプションをサポートしています。
これは単なるヒントではなく、プラグインの小さな抜粋です。
HTH、
), temp_name, 'b')
" 3- call ctags, and replace references to the temporary source file to the
" real source file
let cmd_line = s:CtagsCmdLine(a:ctags_pathname).' '.source_name.' --append'
let cmd_line .= ' && sed "s#\t'.temp_name.'\t#\t'.source_name.'\t#" > '.temp_tags
let cmd_line .= ' && mv -f '.temp_tags.' '.a:ctags_pathname
call system(cmd_line)
call delete(temp_name)
return ';'
endfunction
" ======================================================================
" generate tags for all files {{{3
function! s:UpdateTags_for_All(ctags_pathname)
call delete(a:ctags_pathname)
let cmd_line = 'cd '.s:CtagsDirname()
" todo => use project directory
"
let cmd_line .= ' && '.s:CtagsCmdLine(a:ctags_pathname).' -R'
echo cmd_line
call system(cmd_line)
endfunction
" ======================================================================
" generate tags for the current saved file {{{3
function! s:UpdateTags_for_SavedFile(ctags_pathname)
let source_name = expand('%')
let temp_tags = tempname()
if filereadable(a:ctags_pathname)
" it exists => must be changed
call system('grep -v " '.source_name.' " '.a:ctags_pathname.' > '.temp_tags.' && mv -f '.temp_tags.' '.a:ctags_pathname)
endif
let cmd_line = 'cd '.s:CtagsDirname()
let cmd_line .= ' && ' . s:CtagsCmdLine(a:ctags_pathname).' --append '.source_name
" echo cmd_line
call system(cmd_line)
endfunction
" ======================================================================
" (public) Run a tag generating function {{{3
function! LHTagsRun(tag_function)
call s:Run(a:tag_function)
endfunction
" ======================================================================
" (private) Run a tag generating function {{{3
" See this function as a /template method/.
function! s:Run(tag_function)
try
let ctags_dirname = s:CtagsDirname()
if strlen(ctags_dirname)==1
throw "tags-error: empty dirname"
endif
let ctags_filename = s:CtagsFilename()
let ctags_pathname = ctags_dirname.ctags_filename
if !filewritable(ctags_dirname) && !filewritable(ctags_pathname)
throw "tags-error: ".ctags_pathname." cannot be modified"
endif
let Fn = function("s:".a:tag_function)
call Fn(ctags_pathname)
catch /tags-error:/
" call lh#common#ErrorMsg(v:exception)
return 0
finally
endtry
echo ctags_pathname . ' updated.'
return 1
endfunction
function! s:Irun(tag_function, res)
call s:Run(a:tag_function)
return a:res
endfunction
" ======================================================================
" Main function for updating all tags {{{3
function! s:UpdateAll()
let done = s:Run('UpdateTags_for_All')
endfunction
" Main function for updating the tags from one file {{{3
" @note the file may be saved or "modified".
function! s:UpdateCurrent()
if &modified
let done = s:Run('UpdateTags_for_ModifiedFile')
else
let done = s:Run('UpdateTags_for_SavedFile')
endif
endfunction
このコードは以下を定義します:
-
^ Xta
を使用して、現在のプロジェクトのすべてのファイルのタグベースを強制的に更新します。 -
^ Xtc
を使用して、現在の(保存されていない)ファイルのタグベースを強制的に更新します。 - ファイルが保存されるたびにタグベースを更新する自動コマンド。 また、ファイルタイプに応じてctags呼び出しを調整するために、自動更新を無効にする多くのオプションをサポートしています。 これは単なるヒントではなく、プラグインの小さな抜粋です。
HTH、
自動タグは、保存時に既存のタグファイルを更新するvimプラグインです。
タグファイルに最大サイズを適用することを除いて、何年も問題なく使用しています。ただし、同じタグファイルですべてのインデックスが付けられた非常に大きなコードセットがない限り、その制限に達することはありません。
自動タグにはvimでのPythonサポートが必要であることに注意してください。