複数のタグテーブルを切り替え

普段コードを読むときはタブジャンプに etags じゃなくて global に付属している gtags を使っている。理由は複数の候補の時に選択肢を表示して選べるようになっているから。

ただ面倒なのが、複数のプロジェクトのソースをかけもちしていたり、同じソフトウェアでもいろいろなバージョンのソースを持っていたりすると、別のソースを読む時にいちいちタグテーブルを切り替えなければならないこと。また、これは gtags の仕様なのかタグテーブル(GTAGSファイル)があるディレクトリにいちいち移動しなければならない。

これはかなりめんどーなので、下記の elisp 関数を .emacs に書いて拡張した。

  • 1. あらかじめ複数のソース(ここでは emacs 22, emacs 21, httpd 2.28という 3 つのソースがあるとする)の名前と GTAGS ファイルがあるトップディレクトリを連想リストに入れておく。
  • 2. M-x my-gtags-select-tag-table(F12キーに割り当ててみた)で呼び出すとウィンドウが分割されて、リストしておいたタグテーブルを番号づけして表示してくれる。番号を選べばタグテーブルがスイッチされて次からのタグジャンプの時には選んだタグテーブルが使われるようになるといった仕組み。


;;; ** gtags-mode
(global-set-key "\M-." 'gtags-find-tag)
(autoload 'gtags-find-tag "gtags" "" t)
(autoload 'gtags-mode "gtags" "" t)
(add-hook 'gtags-mode-hook 'setnu-mode)

(setq my-gtags-tag-table-alist
	  '(
		("emacs 22" . "/home/kyagi/src/emacs22")
		("emacs 21" . "/home/kyagi/src/emacs21")
		("httpd 2.2.8" . "/home/kyagi/src/http-2.2.8")
		))

(defun my-gtags-show-tag-table-alist ()
  (split-window-vertically)
  (other-window 1)
  (switch-to-buffer "*my-gtags-show-tag-table-alist*")
  (let ((n 1) (tag-table) (tag-table-alist))
	(setq tag-table-alist my-gtags-tag-table-alist)
	(while tag-table-alist
	  (setq tag-table (car tag-table-alist))
	  (insert (format "%d %s\n" n (car tag-table)))
	  (setq tag-table-alist (cdr tag-table-alist))
	  (setq n (1+ n)))))

(defun my-gtags-hide-tag-table-alist ()
  (kill-buffer "*my-gtags-show-tag-table-alist*")
  (other-window 1)
  (delete-other-windows))

(defun my-gtags-select-tag-table ()
  (interactive)
  (gtags-mode t)
  (my-gtags-show-tag-table-alist)
  (let ((n 0) (answer) (tag-table) (tag-table-alist))
	(setq tag-table-alist my-gtags-tag-table-alist)
	(setq answer (read-from-minibuffer "which tag table do you want to use?:"))
	(setq answer (string-to-number answer))
	(while (not (= n answer))
	  (setq tag-table (car tag-table-alist))
	  (setq tag-table-alist (cdr tag-table-alist))
	  (setq n (1+ n)))
	(setq-default gtags-rootdir (cdr tag-table)))
  (my-gtags-hide-tag-table-alist)
  (cd gtags-rootdir))

(global-set-key [f12] 'my-gtags-select-tag-table)

個人的にはなかなか重宝している。同様に不満を持っている人も多いと思うのでもう少し推敲したら作成元に投げてみようかな。