ctagsをElixirに対応させて「定義にジャンプ」を実現する【Elixir, Atom Editor】

  • 9
    Like
  • 0
    Comment
More than 1 year has passed since last update.

ctags

南極を含む7大陸で使用されていると評判(?)のexuberant ctagsは、

generates an index (or tag) file of language objects found in source files that allows these items to be quickly and easily located by a text editor or other utility.

とあるように、関数やクラス定義のインデックスを生成し、エディタ機能で容易にその定義位置にジャンプしたり、定義ファイルを開いたりするためのユーティリティです。

41の言語にデフォルトで対応しているとのことですが、Elixirは入っていません。

が、インデックスしたい定義の正規表現を登録することで、(大雑把になら)簡単に別言語ファイルに対応できます。

使い方

$ cd project_root
$ ctags -R [paths]

tagsというファイルが生成され、中に関数やクラスが列挙されていればOK.

設定ファイルは~/.ctagsという名前でホームディレクトリにおきます。

Elixir

mmorearty/elixir-ctagsで公開されています。

~/.ctags
--langdef=Elixir
--langmap=Elixir:.ex.exs
--regex-Elixir=/^[ \t]*def(p?)[ \t]+([a-z_][a-zA-Z0-9_?!]*)/\2/f,functions,functions (def ...)/

...

--regex-<langdef>の行は、/<regex>/<capture>/<label>/という構造になっているようです。ドキュメントはあまり詳細ではないですが、生成されたtagsファイルを見るとなんとなくわかります。

上記例の場合、(p?)([a-z_][a-zA-Z0-9_?!]*)でキャプチャが2箇所あり、実際にインデックスされて欲しい関数名の方は2番めなので、<capture>項に\2を指定します。

Atom Editorで「定義にジャンプ」

ビルトインのsymbols-viewパッケージが担当しています。

単語を選択(OSXならcmd-d、あるいはctrl-shift-W)して、alt-cmd-downでジャンプできます。alt-cmd-upで元のファイルの元の位置に戻れます。

が、このストロークは複雑なのと、選択した単語がインデックスに存在していても、ジャンプが効かないケースがあります。
(例えばNested.ModuleNested部分を選択してジャンプしようとする場合。symbols-view側の仕様?)

どちらかと言うと、ファイル内であればcmd-r、プロジェクト全体であればshift-cmd-Rを使って、検索モーダルから探すほうが直観的かもしれません。個人的にはこちらを多用しています。

goto

ctagsを使わず独自にインデックスを(in-memoryで)自動構築してジャンプを行うgotoというパッケージもあり、symbols-viewを代替できるようです。手動でctagsコマンドを叩く手間が省けてお手軽ですが、まだ試してはいません。

ただ、ctagsを介しておけばvimやEmacsでも同じインデックスを使い回せる利点があるので、どちらが良いかは好みと状況によるでしょう。

Tips

以下おまけ。

インデックス生成

たまに手動でコマンドを叩くだけですが、面倒ですよね。自動でやらせたい。"ctagsと連携するように環境を構築する"も参考に。

  1. git hookで好きなタイミングで実行させる。
    • post-commit, post-merge, post-checkoutあたりか。
  2. npm scriptsやgulpでwatchしているプロジェクトであれば、適当なスクリプトにctags呼び出しを絡ませておく。
    • ctags自体は単純なシロモノなので高速ですが、走査するファイル量によるので、[paths]引数で適宜範囲指定。
    • depsとか、node_modulesとかは最初から含めないのがよさげ。
  3. mix-test.watchを使っているのなら、System.cmd/3とかでctagsを呼び出すMix taskを作っておいて、configで指定する。
    • 試してはいません。でもできるはず。
  4. ファイル保存時にコマンドを実行する系のAtomパッケージでフックする。

エディタ等ローカル開発環境周りの設定事項はできればGitに入ってプロジェクトで共有されるファイルでは設定したくないので、1か4が有望そうです。

tagsファイルはglobal ignore

同様に、頻繁に更新されることになるtagsファイルもGitには入れたくありません。が、同名のファイルが複数プロジェクトで生成されるので、いちいち.gitignoreに書かせてもらうのは忍びない。

global ignoreに入れておくのがよさそうです。

Scala

他の未対応言語ももちろんカバーできます。

Scalaならこちらのgistが参考になります。

~/.ctags
--langdef=scala
--langmap=scala:.scala
--regex-scala=/^[ \t]*((abstract|final|sealed|implicit|lazy)[ \t]*)*(private|protected)?[ \t]*class[ \t]+([a-zA-Z0-9_]+)/\4/c,classes/

...

SBTを使っている場合、sbt-ctagsというプラグインを使うとビルド時に生成可能のようです。~/.ctagsは必要です。

筆者設定

gistで公開しています。skirino/cromadefunシリーズにも対応。