GNU GLOBALの対応言語を大幅に増やすPygmentsパーサーを導入する


GNU GLOBAL 6.3.2 より、Pygments を利用したプラグインパーサー(以降 Pygmentsパーサー)が同梱されるようになりました。
これは Python で書かれたシンタックスハイライターである Pygments を利用し、Pygments がサポートするたくさんの種類のプログラミング言語のタグ付けを可能にするものです。

具体的には、GLOBAL-6.3.2 (2014年9月4日リリース)の新機能 に GLOBAL の作者様が書かれているように 25種類、シンボルタグのみの検索ができるものも含めれば 150種類ぐらいの言語に対応しているはずです。
個人的には、Ruby, Go, JavaScript などのタグ付けに利用しています。

そんなPygmentsパーサーですが、GLOBAL のプラグインパーサーの設定自体が少し難しい上、Pygmentsパーサーがいくつかのソフトウェアに依存していたりするため、導入方法がわかりにくいようです。そこで、Pygmentsパーサーの導入方法について解説したいと思います。

Exuberant Ctags の利用

早速インストール…の前に、少し予備知識が必要です。

gtags の生成するタグには、定義タグとシンボルタグがあります。参照タグは少し特殊で、参照タグ専用のインデックスというのはありません。1

Pygments だけではシンボルタグしか生成できません。シンボルタグだけでもタグジャンプはできますが、その場合 定義・参照もすべてシンボル扱いになります。

定義タグ、参照タグの区別ができたほうが便利です。そのため、Pygmentsパーサーでは Exuberant Ctags がインストールされている場合には、Exuberant Ctags を利用して定義タグを生成します。
Pygments と ctags、両方の出力が組み合わさることにより、定義・参照・シンボルの全ての種類のタグジャンプが利用できるようになります。

なお、Exuberant Ctags がサポートしていない言語に関してはシンボルタグのみ生成されます。

インストール

Mac の場合

Mac では Homebrew を利用するのが簡単です。

$ brew install global --with-exuberant-ctags --with-pygments

これにより Python の Pygments パッケージや、Exuberant Ctags も自動的にインストールされます。

Unix系OS の場合

必要なもの

  • Python 2.6 以降 (GLOBAL-6.3.3 以降のPygmentsパーサーでは 3.x も OK)
  • Pygments Python パッケージ (1.6 以降推奨)
  • Exuberant Ctags 5.5 以降

インストール

Pygments パッケージをインストールします。

$ sudo pip install Pygments

Exuberant Ctags をインストールします。

だいたいのディストリビューションではパッケージが用意されているのではないかと思います。
Ubuntu Linux の場合は以下のようにします。

$ sudo apt-get install exuberant-ctags

GNU GLOBAL をインストールします。

http://www.gnu.org/software/global/download.html から最新の global-x.x.x.tar.gz をダウンロード
$ tar xf global-x.x.x.tar.gz
$ cd global-x.x.x
$ ./configure
$ make
$ sudo make install

なお ./configure の実行の際、正しく python の実行ファイルが見つかれば

checking for python... /usr/bin/python

というログが、また、正しく ctags の実行ファイルが見つかれば

checking for exuberant ctags program... using /usr/bin/ctags

というログが出力されます。

動かしてみる

ラベルについて

GNU GLOBAL をインストールしたデフォルトの状態では、ビルトインパーサーが動作するようになっています。
ビルトインパーサーは C/C++, Java, PHP など限られた言語にのみ対応しています。

プラグインパーサーを利用するには、gtags 実行時に「ラベル」を指定し、使いたいパーサーを明示する必要があります。

$ gtags --gtagslabel=pygments

# 環境変数で指定することもできます
$ export GTAGSLABEL=pygments
$ gtags

ラベルとして指定できるのは、/usr/local/etc/gtags/gtags.conf2 に定義されている以下の項目です。

default:\
        :tc=native:
native:\
        :tc=gtags:tc=htags:
user:\
        :tc=user-custom:tc=htags:
ctags:\
        :tc=exuberant-ctags:tc=htags:
pygments:\
        :tc=pygments-parser:tc=htags:

何も指定しないと、default が指定されたことになります。
Pygmentsパーサーを利用する場合はラベルに pygments を指定してください。
なお、このファイルで tc= というのは 他の定義をその場に読み込むというような意味です。

実行例

$ cat hello.rb
class Hello
  def hello
    puts message
  end

  def message; 'hello, world'; end
end
$ gtags --gtagslabel=pygments
$ global -x message hello.rb
message             6 hello.rb         def message; 'hello, world'; end
$ global -rx message hello.rb
message             3 hello.rb             puts message

定義タグと参照タグがそれぞれ検索できていることがわかります。

トラブルシューティング

プラグインパーサーが呼ばれていることの確認

gtags--debug オプションを与えることで、対象のファイルに対してプラグインパーサーが呼ばれているかどうかを確認することができます。

$ gtags --debug
.....
File './hello.rb' is handled as follows:
suffix:   |.rb|
language: |Ruby|
parser:   |parser|
library:  |/usr/local/lib/gtags/pygments-parser.la|
.....

拡張子 .rbhello.rb が Ruby 言語と判断され、pygments-parser が呼ばれていることがわかります。

もしここで期待するプラグインパーサーが呼ばれていない場合は、

  • インストールの手順が正しいか?
  • 設定ファイルの内容が正しいか?

などを確認するとよいでしょう。

タグが生成されていることの確認

gtags-d オプションとタグファイル名を与えることで、タグファイルの内容をダンプすることができます。

$ gtags -d GTAGS
 __.COMPNAME     __.COMPNAME
 __.COMPRESS     __.COMPRESS ddefine ttypedef
 __.VERSION      __.VERSION 6
Hello   1 @n 1 class @n
hello   1 @n 2 def @n
message 1 @n 6 def @n; 'hello, world'; end

$ gtags -d GRTAGS
 __.COMPACT      __.COMPACT
 __.COMPLINE     __.COMPLINE
 __.COMPNAME     __.COMPNAME
 __.VERSION      __.VERSION 6
Hello   1 @n 9
h       1 @n 9-1
hello   1 @n 10
message 1 @n 3
new     1 @n 9
puts    1 @n 3

先頭の数行は管理データですが、それ以降は各行の先頭のフィールドがタグになっています。
GTAGS には定義タグが、GRTAGS にはシンボルタグが格納されています。

GTAGSGRTAGS にそれぞれ期待するタグが生成されているかどうかを確認し、生成されていない場合は、

  • (GTAGSに期待するタグが生成されていない場合) ctags がインストールされているか?
  • Pygments が正しくインストールされているか?

などを確認するとよいでしょう。

Tips

ビルトインパーサーと併用する

Pygmentsパーサーは遅いので、ビルトインパーサーが対応しているファイルについてはビルトインパーサーで処理し、残りをPygmentsパーサーで処理するように設定しておくのがおすすめです。
また同時に、環境変数 GTAGSLABEL--gtagslabel オプションを設定しなくてもPygmentsパーサーが機能するようにします。

設定ファイルを ~/.globalrc という名前でコピーします。

$ cp /usr/local/etc/gtags/gtags.conf ~/.globalrc    # gtags.conf の場所は環境により読み替えてください

~/.globalrc を編集します。

default:\
        :tc=native:
↓
default:\
        :tc=native:tc=pygments:

これにより、環境変数 GTAGSLABEL や --gtagslabel オプションを設定しなくてもPygmentsパーサーが機能するようになります。
さらに、ビルトインパーサーが処理できるファイルに対してはビルトインパーサーが優先的に利用されるようになります。

おわりに

正確さに欠ける、遅い、など欠点もありますが、1回設定すれば多くの言語に対応できるPygmentsパーサーは GNU GLOBAL ユーザーの方には便利に使って頂けるのではないかと思います。
使ってみてのフィードバックなど頂けると幸いです。


  1. 参照タグはシンボルタグと定義タグから導出されます。シンボルタグのうち、同じ識別子が定義タグにも存在するものが参照タグになります。 

  2. パスは環境により読み替えてください。Mac の Homebrew では /usr/local/etc/gtags/gtags.conf、Linux では /usr/local/share/gtags/gtags.conf となることが多いです。