gtags memo

globalやGTAGSの話となるとほとんどvimから検索するみたいな記事ばかりですが、この記事はshellからglobalコマンドをgrepの代替として使います。


# grepに勝るglobalコマンドでファイル内検索
globalコマンドを使えばあらかじめ作成したファイル内の定義を検索するので、grepのようにいちいちファイルをオープンして探すみたいな時間のかかる行為をしなくて高速検索できる。




## tagsファイルを作成
python用には

```shell-session
$ cd ~/Dropbox/Program/python
$ ctags -R **/*.py
```

ディレクトリ数: 209, ファイル数: 4998のディレクトリで10秒程度でした。




## あらかじめGTAGSファイルを作成
```shell-session
$ cd path/to/project
$ global -v
```

> ディレクトリ数:18103, ファイル数:2591 の私のpythonのsite-packageディレクトリでは GPATH, GRTAGS, GTAGSの作成に5分半かかりました。


## 関数->ファイル
zshのcompletionsを使うと`global fine `<kbd>Tab</kbd>とするだけで`fine_ticks`をコンプリーションしてくれて、そのまま<kbd>Enter</kbd>押せば、`fine_ticks`が定義されているファイルパスを見つけてくれます。

```shell-session:fine<tab>でfine_ticks
$ global fine_ticks
pyfeko/bin/pyfeko.py
```

```shell-session:fine_ticksが定義されているファイルのマッチする行を色付きで出力
$ global --grep fine_ticks --result=grep --color
```

* `--grep`: grepを使ってすべてのマッチする行を出力
* `--result`: 出力結果をの表示方法をcscope, ctags, ctags-x, grep, pathから選択。デフォルトはpath
* `--color`で`grep`で抜き出されたところに色付け

```shell-session:resultの出力結果の違い
$ global --grep fine_ticks --result=path
pyfeko/bin/pyfeko.py

$ global --grep fine_ticks --result=cscope
pyfeko/bin/pyfeko.py fine_ticks 163 def fine_ticks(tick, deg):
pyfeko/bin/pyfeko.py fine_ticks 175 print(fine_ticks(np.arange(181),i))
pyfeko/bin/pyfeko.py fine_ticks 233 plt.xticks(fine_ticks(x, xti))  # 30degごと
pyfeko/bin/pyfeko.py fine_ticks 234 plt.yticks(fine_ticks(y, yti))  # 1degごと
pyfeko/bin/pyfeko.py fine_ticks 235 ax = plt.colorbar(ticks=fine_ticks(interval, cmapstep))  # カラーバー2区切りで表示

$ global --grep fine_ticks --result=ctags
fine_ticks	pyfeko/bin/pyfeko.py	163
fine_ticks	pyfeko/bin/pyfeko.py	175
fine_ticks	pyfeko/bin/pyfeko.py	233
fine_ticks	pyfeko/bin/pyfeko.py	234
fine_ticks	pyfeko/bin/pyfeko.py	235

$ global --grep fine_ticks --result=ctags-x
fine_ticks        163 pyfeko/bin/pyfeko.py def fine_ticks(tick, deg):
fine_ticks        175 pyfeko/bin/pyfeko.py               print(fine_ticks(np.arange(181),i))
fine_ticks        233 pyfeko/bin/pyfeko.py     plt.xticks(fine_ticks(x, xti))  # 30degごと
fine_ticks        234 pyfeko/bin/pyfeko.py     plt.yticks(fine_ticks(y, yti))  # 1degごと
fine_ticks        235 pyfeko/bin/pyfeko.py     ax = plt.colorbar(ticks=fine_ticks(interval, cmapstep))  # カラーバー2区切りで表示

$ global --grep fine_ticks --result=grep
pyfeko/bin/pyfeko.py:163:def fine_ticks(tick, deg):
pyfeko/bin/pyfeko.py:175:              print(fine_ticks(np.arange(181),i))
pyfeko/bin/pyfeko.py:233:    plt.xticks(fine_ticks(x, xti))  # 30degごと
pyfeko/bin/pyfeko.py:234:    plt.yticks(fine_ticks(y, yti))  # 1degごと
pyfeko/bin/pyfeko.py:235:    ax = plt.colorbar(ticks=fine_ticks(interval, cmapstep))  # カラーバー2区切りで表示
```

## ファイル->関数
-fオプションを使えば、特定のファイルに含まれる言語の定義だけを標準出力に出力できます。

```shell-session:generator.pyに含まれる定義を出力
$ global -f generator.py                                                                                                     TSTP(-20) ↵  ⚙  03:26 Dur  15251  11:33:01
ctags: Warning: Ignoring non-option in ./.ctags

s                   3 generator.py     s='alphabets'
it                  4 generator.py     it=iter(s)
gen                12 generator.py     def gen(data):
gen2               43 generator.py     def gen2(data):
ls                 64 generator.py     ls=[i*i for i in range(10)]
xvec               71 generator.py     xvec=[2,3,4]
yvec               72 generator.py     yvec=[10,10,10]
f                  78 generator.py     def f():
v                  83 generator.py     v=list(f())
```

下のようにしてパイプで複数ファイルの検索もできます。
findやlocateも応用できそうです。

```shell-session:パイプを利用して検索
$ ls re*  # reを含むファイルを表示
read_filelist.py*  remove_empty_list.py*  requests_use.py*

$ \ls re* | xargs global -f  # バックスラッシュを入れないと*アスタリスクが入って「そんなファイルはない！」と怒られる

ctags: Warning: Ignoring non-option in ./.ctags

codecs              1 read_filelist.py import codecs
re                  2 read_filelist.py import re
read_filelist       5 read_filelist.py def read_filelist(filelist_path):
doctest             3 requests_use.py  import doctest
requests            4 requests_use.py  import requests
sample              7 requests_use.py  def sample(query):
```


## htags
Dropbox上のpythonディレクトリ
ディレクトリ数: 209
ファイル数: 4998
html化にかかった時間: 2min13sec