実践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!