Emacs で関数ジャンプを行うために gtags
を導入した話です。
また global-pygments-plugin
を使って gtags
が対応していない言語でも関数ジャンプをやってみた話です。
記事の中では gtags
のインストール後に Pygments
を導入しますが、
実際にやってみたら Python
や Pygments
を先にインストールしておかないと、
gtags
の ./configure
でちゃんと設定が行われないようです。ご注意ください。
環境
- Ubuntu 14.04
gtags を試す
gtags
でソースコードの関数ジャンプをできるようにする
gtags
は C/C++, Java, PHP などしか対応していないらしい
※まずは通常の gtags
で色々試してみます。
※後述で global-pygments-plugin
を適用して対応言語を増やしてみます。
ということで、
- 事前準備
- gtags のインストール(ソースコードから)
- Emacsからgtagsを使えるようにする
- 実践
- C++ で試してみる
- Java で試してみる
こんな感じで進めていきます。
事前準備
gtags のインストール(ソースコードから)
https://www.gnu.org/software/global/download.html
2016/08/10現在: 6.5.4 が最新
$ wget http://tamacom.com/global/global-6.5.4.tar.gz
$ tar -zxvf global-6.5.4.tar.gz
$ cd global-6.5.4
$ ./configure
$ make
$ make install
$ which gtags
/usr/local/bin/gtags
./configureで発生した問題
configure: checking "location of ncurses.h file"...
configure: error: curses library is required but not found.
If you are not going to use gtags-cscope, please try ./configure --disable-gtagscscope
なんか無いよ。とな。
$ sudo apt-get install ncurses-dev
上記でライブラリをインストールしてから再度 ./configure
で問題なくOK
Emacsからgtagsを使えるようにする
gtags.elのパスを通す
(add-to-list 'load-path "/usr/local/share/gtags")
恐らく上記にあるはず・・・
.emacsの設定を追加
(autoload 'gtags-mode "gtags" "" t)
(setq gtags-mode-hook
'(lambda ()
(local-set-key "\M-t" 'gtags-find-tag) ;関数へジャンプ
(local-set-key "\M-r" 'gtags-find-rtag) ;関数の参照元へジャンプ
(local-set-key "\M-s" 'gtags-find-symbol) ;変数の定義元/参照先へジャンプ
(local-set-key "\C-t" 'gtags-pop-stack) ;前のバッファに戻る
))
とりあえず c-mode
と c++-mode
の時に gtags-mode
に入るようにする
(add-hook 'c-mode-hook 'gtags-mode)
(add-hook 'c++-mode-hook 'gtags-mode)
実践
C++ で試してみる
https://github.com/chibi929/hello-gtags
上記の Cpp
ディレクトリで試しています
ソースコードタグの準備
$ git clone git@github.com:chibi929/hello-gtags.git
$ cd hello-gtags/CppProject
$ gtags -v
[Thu Aug 11 01:01:24 JST 2016] Gtags started.
Using default configuration.
[Thu Aug 11 01:01:24 JST 2016] Creating 'GTAGS' and 'GRTAGS'.
[1] extracting tags of Sample.cpp
[2] extracting tags of Sample.h
[3] extracting tags of main.cpp
[Thu Aug 11 01:01:24 JST 2016] Done.
ジャンプ実行
例1-1(gtags-find-tag)
上記では main.cpp:L11: hoge()
にカーソルを合わせて M-t
を実行しています。
Find tag: (default hoge)
となっており Enter
を押すと main.cpp:L4: void hoge()
に飛びます。
例1-2(gtags-find-tag)
上記では main.cpp:L13: sample.test()
にカーソルを合わせて M-t
を実行しています。
Find tag: (default test)
となっており Enter
を押すと Sample.cpp:L12: void Sample::test()
に飛びます。
例2(gtags-find-rtag)
上記では Sample.cpp:L12: void Sample::test()
にカーソルを合わせて M-r
を実行しています。
Find tag (reference): (default test)
となっており Enter
を押すと以下のように Sample::test()
の参照元を表示してくれます。
上記の例では2つのうちどちらかを選ぶとでそのファイルに飛びます。
例3(gtags-find-symbol)
省略。
変数の参照元や参照先へジャンプすることができます。
Java で試してみる
https://github.com/chibi929/hello-gtags
上記の Java
ディレクトリで試しています
java-mode
時の gtags-mode
の設定が必要
(add-hook 'java-mode-hook 'gtags-mode)
あとは C++ の時と同じなので省略。
global-pygments-plugin を試す
global-pygments-plugin
は GNU GLOBAL 6.3.2
から取り込まれたプラグインらしい
gtags
の欠点だった対応言語が少ないという点を改善してくれるとのこと
global-pygments-plugin
を使用するには Pygments
というものが必要らしい
Pygments
を使用するには Python 2.6 以上
が必要らしい
ということで、
1. Python 2.6 以上の準備
2. Pygments の準備
3. global-pygments-plugin
を利用
といった感じだろうか。
Python 2.6 以上の準備
せっかくなので pyenv
を導入
内容は省略
$ pyenv versions
system
* 2.7.12 (set by /home/chibi/.pyenv/version)
3.5.2
$ python --version
Python 2.7.12
$ pip --version
pip 8.1.1 from /home/chibi/.pyenv/versions/2.7.12/lib/python2.7/site-packages (python 2.7)
とりあえずこんな感じ
Pygments
の準備
$ pip install Pygments
$ pygmentize -V
Pygments version 2.1.3, (c) 2006-2015 by Georg Brandl.
global-pygments-plugin
を利用
.bashrc
に設定を追加
export GTAGSCONF=/usr/local/share/gtags/gtags.conf
export GTAGSLABEL=pygments
上手く動かない!!
pygments_parser.py でエラー!!
$ gtags --gtagslabel=pygments
Traceback (most recent call last):
File "/usr/local/share/gtags/script/pygments_parser.py", line 27, in <module>
import pygments.lexers
ImportError: No module named pygments.lexers
gtags: unexpected EOF.
/usr/local/share/gtags/script/pygments_parser.py
の #!/usr/bin/python
が、
実際に利用している python
を指していないせいだとか。
りあえず無理矢理書き換えてみるとエラーが消えた。
タグが定義されていない!!
$ gtags -v --debug
[Thu Aug 11 23:24:28 JST 2016] Gtags started.
Using configuration file '/usr/local/share/gtags/gtags.conf'.
Using configuration label 'pygments'.
Using plug-in parser.
[Thu Aug 11 23:24:28 JST 2016] Creating 'GTAGS' and 'GRTAGS'.
DBG: Original skip list:
HTML/,HTML.pub/,tags,TAGS,ID,y.tab.c,y.tab.h,gtags.files,cscope.files,cscope.out,cscope.po.out,cscope.in.out,SCCS/,RCS/,CVS/,CVSROOT/,{arch}/,autom4te.cache/,*.orig,*.rej,*.bak,*~,#*#,*.swp,*.tmp,*_flymake.*,*_flymake,*.o,*.a,*.so,*.lo,*.zip,*.gz,*.bz2,*.xz,*.lzh,*.Z,*.tgz,*.min.js,*min.css
DBG: Regular expression of the skip list:
(/\.[^/]+$|/\.[^/]+/|/GTAGS$|/GRTAGS$|/GSYMS$|/GPATH$|/HTML/|/HTML\.pub/|/tags$|/TAGS$|/ID$|/y\.tab\.c$|/y\.tab\.h$|/gtags\.files$|/cscope\.files$|/cscope\.out$|/cscope\.po\.out$|/cscope\.in\.out$|/SCCS/|/RCS/|/CVS/|/CVSROOT/|/\{arch\}/|/autom4te\.cache/|/[^/]*\.orig$|/[^/]*\.rej$|/[^/]*\.bak$|/[^/]*~$|/#[^/]*#$|/[^/]*\.swp$|/[^/]*\.tmp$|/[^/]*_flymake\.[^/]*$|/[^/]*_flymake$|/[^/]*\.o$|/[^/]*\.a$|/[^/]*\.so$|/[^/]*\.lo$|/[^/]*\.zip$|/[^/]*\.gz$|/[^/]*\.bz2$|/[^/]*\.xz$|/[^/]*\.lzh$|/[^/]*\.Z$|/[^/]*\.tgz$|/[^/]*\.min\.js$|/[^/]*min\.css$)
DBG: .[/GPATH] => SKIPPED
DBG: .[/GTAGS] => SKIPPED
DBG: .[/GRTAGS] => SKIPPED
./Main.rb
[1] extracting tags of Main.rb
[Thu Aug 11 23:24:28 JST 2016] Done.
$ gtags -d GTAGS
__.COMPNAME __.COMPNAME
__.COMPRESS __.COMPRESS ddefine ttypedef
__.VERSION __.VERSION 6
すごく苦しんだ。なぜダメなのか。
どうやら gtags
インストール時の ./configure
が影響しているようだ。
つまり Pygments
インストール前に ./configure
を実行しているため設定が何か漏れている気がする。
gtags
をインストールしなおすといけた。
ちなみに上記で引っかかっていた #!/usr/bin/python
の部分も pyenv
導入前に ./configure
をしていたせいのようだ。
更に 追記 を行いましたので まとめ
をご確認下さい。
Ruby で試してみる
https://github.com/chibi929/hello-gtags
上記の Ruby
ディレクトリで試しています
(add-hook 'ruby-mode-hook 'gtags-mode)
C++ , Java と同様に gtags-mode
に入るようにする
$ gtags -v
[Thu Aug 11 23:56:50 JST 2016] Gtags started.
Using configuration file '/usr/local/share/gtags/gtags.conf'.
Using configuration label 'pygments'.
Using plug-in parser.
[Thu Aug 11 23:56:50 JST 2016] Creating 'GTAGS' and 'GRTAGS'.
[1] extracting tags of Sample.rb
[2] extracting tags of Main.rb
[Thu Aug 11 23:56:50 JST 2016] Done.
$ gtags -d GTAGS
__.COMPNAME __.COMPNAME
__.COMPRESS __.COMPRESS ddefine ttypedef
__.VERSION __.VERSION 6
Sample 1 @n 1 class @n
hoge 2 @n 3 def @n
test 1 @n 2 def @n
Emacs での実行は C++ と同じなので省略
最後に
helm-gtags-mode
を導入した内容も書こうと考えていましたが、
操作は gtags-mode
と変わらないと思いますので書きませんでした。
実際に使う時は helm-gtags-mode
を導入して使おうと思います!
色々な言語で関数ジャンプ
というタイトルだけどデフォルト以外だと Ruby
しか試していません。
まぁどれも同じだと思っています。C++, Javaの流れを見ても1個だけやればよさそう・・・。
まとめ
global-pygments-plugin
を使う場合は先に環境を準備しましょう。
今回、まずは通常の gtags
から使ってみようとしたため、後から Pygments
を入れました。
その影響で gtags --gtagslabel=pygments
が上手く動いてくれず、Rubyのソースコードタグが上手く生成されませんでした。
ということで、
1. python & pip の準備
2. Pygments の準備
3. GNU GLOBAL(gtags) の準備
という感じで進めていきましょう。
そもそも ctags
, etags
, gtags
の違いもわかっていませんでしたが、
Emacsでタグジャンプ機能を使用する
こちらの記事で理解しました。
追記
別の環境で入れてみたら gtags -d GTAGS
でダンプしてもどうにも空っぽ
Exuberant Ctags
も入れないとダメかも?
GNU GLOBALの対応言語を大幅に増やすPygmentsパーサーを導入する
上記の記事によると Exuberant Ctags 5.5 以上
が必要とのこと。
$ ctags --version
Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
Compiled: Aug 15 2016, 11:30:15
Addresses: <dhiebert@users.sourceforge.net>, http://ctags.sourceforge.net
Optional compiled features: +wildcards, +regex
入れてみたら期待するタグが定義されていた。
参考サイト
Helm-Gtags-Modeを導入してソースコードの読解する
GNU GLOBALへのPygmentsパーサー取り込みでソースコード読みが信じられないくらいに捗るはず
こちらの記事を参考にさせていただきました。ありがとうございました。