ctagsと連携するように環境を構築する

  • 194
    Like
  • 4
    Comment
More than 1 year has passed since last update.

実践Vim読みました。
達人出版会さんからpdf版が発売されてるのでそちらがおすすめです。何やらAmazonと比べて600円ぐらい安いようですね。

その中の

第6部 ツール
第16章 ctagsを使ってソースコードのインデックスを作成し、ナビゲーションを行う
TIP102: ctagsと連携するようにVimを構成する

の所を掘り下げて見ようと。元々は「Vimを構成する」ですがすでにvimを使いこなす時の環境構築になってしまうのかなと思い少しタイトルを広くとらえる形にしました。

ctagsってなに

まずctagsの説明ですが、実践vimの言葉を引用すると

ctagsは、コードベースを走査し、キーワードのインデックスを作成する外部プログラムだ。

てやつで、そのctagsを使って生成されたtagsファイルを使う事によってキーワードの宣言元へ移動したりキーワードの補完をする事が出来ます。IDEで標準的に実装されてる機能が当たり前に使えるようになります。

ctagsのインストール

debian系

sudo apt-get install exuberant-ctags

mac

brew install ctags

macでは標準でctagsが入っているけどBSD版なので対応言語が少なかったりオプションが違ったりするのでインストールしておきましょう。

ctagsの実行方法

ctags -R

でカレントディレクトリにtagsファイルが作成されます。
これをvimで読み込む設定にしておけばジャンプできたり補完できたりと便利になるしろもの。

今回考察すること

実践Vimの方ではプチまとめとしての考察の項では以下のように書かれている。

コミットするたびにコードベースのインデックスを再作成するのがちょうどよいところを突いている。確かに、作業中のローカルコピーと、tagsファイルが分離されるが、エラーはなんとかなる。アクティブに作業しているコードは、タグを使ってナビゲーションを行いたくなることはあまりないコードだ。

僕もそう思う。

しかしそれはバージョン管理を使っていて、なおかつ分散バージョン管理、例えばGitを使っているプロジェクトにしか適応されないという問題を抱えている。

バージョン管理使うようにしたりgit使うようにすればいいじゃんって、そう思うけどもそうじゃないじゃん?やりたいこととやることが離れすぎちゃうじゃん?やる気無くなっちゃうじゃん?技術ってそうじゃないじゃん?もっと簡単に出来るようにしてインターネットでいい気分したいじゃん?いい気分してる人と仲良くしたいじゃん?なかよしインターネットしたいじゃん?もっと世界良くして行きたいじゃん?

という訳でsvn使ってる弊社でも使えるように環境構築をしてきて培ったノウハウを出して行こうかなというのが本記事の目的になります(前置き長過ぎ..)

svn使うとコミットしてもhookがホストリポジトリでしか実行されないのでローカルではctags実行できないのでそれ対応です。

目次

  • gitのhookを利用してctags実行
  • vimでファイル保存した時にctagsをバックグラウンド実行

とりあえずgitのhookを利用してのctags実行と、vimでファイル保存時にctags実行の二段構えで行くという考え。git使ってるならhook使えば良いしvimで保存時に作るようにしちゃえばどの環境でも大抵使えるからいいっすよねって感じで〜感じで〜

gitのhookを利用してctags実行

vim強であるtpope氏のブログ記事が参考になる。
Effortless Ctags with Git

というかこれだけだと解りづらいので自分が過去に書いた記事を引用
gitのhookでtags作成

git checkoutしたりgit cloneしたりgit mergeしたりgit commitした時にctagsのコマンド実行をさせる

まずはhookで実行させるスクリプトの作成

mkdir -p .git_tmp/hooks
touch .git_tmp/hooks/post-commit # git commit hook
touch .git_tmp/hooks/post-merge # git merge, git pull hook
touch .git_tmp/hooks/post-checkout # git checkout hook
touch .git_tmp/hooks/ctags
chmod +x .git_tmp/hooks/*
#!/bin/sh
.git/hooks/ctags >/dev/null 2>&1 &
rm tags
/usr/local/bin/ctags --tag-relative --recurse --sort=yes  --append=no

とする。ctagsのパスとかは別途設定してくだしあ。

ctagsのオプションを軽く説明すると
- --tag-relative 作成されるtagsファイル内のキーワードのパスが相対パスに
- --recurse ディレクトリを再起的に
- --sort=yes 作成されたキーワードをsortする
- --append=no 既存のタグファイルに追加しない

あとはgitを使う時に作成したhookを共通して使うように設定してあげる

git config --global init.templatedir '.git_tmp'

これで、次からcloneするgitリポジトリはhookが反映される。
vimを開けばタグジャンプだったり補完だったりが「vimの標準機能のみで」実行することができる。

ここからは好みだが.gitディレクトリ下にtagsファイルを作成する方法もある。
そうすればいちいち.gitignoreの指定をしなくてすんだり、tagsの変更分をコミットしたりしなくてすむ。
.git以下に作ってしまうともし閲覧する必要が出てきた時に別のファイルを削除してしまった場合等を考えて設定してみてほしい。考え過ぎかもしれないが。

その場合は以下になる

rm .git/tags
/usr/local/bin/ctags --tag-relative --recurse --sort=yes  --append=no -f .git/tags

あとは.vimrcに以下のようにtagsファイルを指定してあげる

set tags+=.git/tags

fugitive.vimを使っていれば標準で.git/tagsを見るように設定されている。

ファイル保存時にctags実行

.vimrcにファイル保存時に作成する設定をしても良いが、あまりにもソースコードの行数が多かったりするとctagsプロセスが終了する時間がかかってしまう。
なのでバックグラウンドで実行する設定にする必要がある、なおかつバックグラウンドで実行したとしても、頻繁に保存した時にctagsプロセスが多重起動してしまった時が厄介で作成されるtagsファイルのフォーマットが崩れてしまうので作成しなおす必要が出てくる。ああ厄介だーどうしようー

と、そんなこともあろうかとctagsを保存時に実行するauto-ctags.vimというプラグインを作成しておいたので問題はなかった。(宣伝)

インストールをして

NeoBundle 'soramugi/auto-ctags.vim'

vimを開いて以下のコマンドを打ち込めばtagsファイルが作成される

:Ctags

.vimrcに以下の設定をしてやれば保存時に勝手にtagsファイルが作成されます。

let g:auto_ctags = 1

格納ディレクトリも指定できます

let g:auto_ctags_directory_list = ['.git', '.svn']

tagsファイルを読み込む設定はしていないので、自分が設定したディレクトリパスを指定してあげてください。こんな感じで

set tags+=.svn/tags

使い方はここら辺とかに乗ってるんじゃないかな(ほじ(宣伝))
tagsファイルを作成する「auto-ctags.vim」作った

まとめ

結構長くなった。。

以上でgitを使っていてコミットした時にtagsファイルを作成したり、ファイルを保存した時にtagsファイルを作成する環境を構築する方法でした。

元々は自分が過去に書いた記事
ctagsをちゃんと使うが結構見られてるみたいで、そういう需要があるのではないかと思いまとめてみた次第です。書いた時から色々得た知識もありますしね。
でもあんまりctagsの記事を見ないのですが他のvim強の方達は他の方法を取っているのかも?あんまりタグジャンプしないのかな。

タグジャンプはすげー便利な機能だと思っているのでもっと簡単に使えればいいなと思いプラグイン作った次第です。よければ使ってやって下せえ。

あと実践vim面白いよ!

enjoy the vim!