C なんて読めなくても succor.el を使ってみる

kansai-emacs#x04 に参加して、r_takaishi さんの succor.el に感銘を受けたので、頑張って手元で使えるようにセットアップしてみました。

succor.el というのは、ひらメソッドによるコードリーディングのメモを emacs + org-modeでつけることができるようにする、というもので、必要なものは、

です。詳細は r_takaishi さんのサイトでうどん食べればわかります。

global の exuberant ctags プラグインを有効化する

succor.el では global の GTAGS を利用しているのですが、残念ながら、global は対応している言語がとても切ない感じで、私が読みたいコードには使えません。
次善の策として、global のプラグイン機能で exuberant ctags を流用できるようにしてみることにします。

ただ、残念なことに debian に入っている global はバージョンが古く、しかもプラグインが有効になっていないので、パッケージを作り直す必要があります。
といっても、configure に --with-exuberant-ctags=/usr/bin/ctags-exuberant を追加してリビルドするだけ (というと語弊があるけど) なので簡単です。私は global-6.1 版としてパッケージを作り直しました。

パッケージができたらおもむろにインストールし、/usr/share/doc/global から gtags.conf を適当なところ (ここでは $HOME) にコピーすれば準備完了です。

cd
cp /usr/share/doc/global/examples/gtags.conf.gz $HOME
gunzip gtags.conf.gz

プラグインを利用して GTAGS を作成するには、読みたいコードのツリーに移動して、

gtags --gtagsconf=$HOME/gtags.conf --gtagslabel=exuberant-ctags

とすれば OK です。私は puppet のツリーで試してみましたが、ぱっと見た感じでは問題なく作成されているようです。

succor.el の設定

基本的な設定は succor.el に付属の README にも書かれていますが、そのままだと、手元ではうまく動いてくれませんでした。理由はよくわからないのですが、ノートを保存するディレクトリとして、コメント ("ノートを保存するディレクトリ") を使おうとするんですよね。というわけで、とりあえずこんな感じにしてみました。

;(auto-install-from-url "https://github.com/takaishi/succor/raw/master/succor.el")

(autoload-if-found 'succor-mode "succor" "" t)

;ノートを保存するディレクトリ
(setq *succor-directory* (expand-file-name "~/.succor/"))

;ノートファイルが使う拡張子
(setq *succor-file-extension* ".org")

;(setq *succor-current-project* nil)
;(setq *succor-work-directory* nil)
;(setq *succor-note-window* nil)

(setq gtags-mode-hook '(succor-mode))

普通はファイルの拡張子別にフックをかけて gtags-mode を有効化するものらしいですが、私の場合は今のところ succor.el を使う時 = global を使う時、なので、gtags-mode にフックをかけて succor-mode を有効化するようにしてあります。
succor-mode を呼んだときに gtags-mode を自動で、の方が自然かなぁとも思うのですが、その方針だとうまく動かせなかったので、gtags-mode が提供している hook を利用する方法に逃げました。

また、最初の使用時に ~/.succor が存在しない場合にディレクトリが作れなかったので、断腸の思いで少しだけ本体にも手を入れました。

diff --git a/succor.el b/succor.el
index f7cbfac..62cf3f6 100644
--- a/succor.el
+++ b/succor.el
@@ -43,7 +43,7 @@
     (setq *succor-work-directory*
           (concat *succor-directory* *succor-current-project* "/"))
     (unless (file-exists-p *succor-work-directory*)
-        (make-directory *succor-work-directory*))
+        (make-directory *succor-work-directory* t))
     (ad-activate-regexp "gtags-find-tag-after-hook")
     (ad-activate-regexp "gtags-pop-stack-after-hook")))

しばらくコードを読むときはこれを使ってみて、succor.el 的な exuberant ctags の互換性を試してみようと思います。

C-c C-r succor-capture (現在行についてノートをとる)
M-t gtags-find-tag (関数にジャンプしてノートを開く)
C-t gtags-pop-stack (関数にジャンプしてノートを開く)