読者です 読者をやめる 読者になる 読者になる

JavaScriptのソースでTagListプラグインを使う時にしとくべき設定

備忘録 Vim

VimプラグインでTagListというのを使っているけど、JavaScriptのソースでTagList起動使うと、明らかにfunctionがあるのにそれが表示されなかったり、functionに飛ぼうとすると意味不明な場所に飛んだりする。
この問題の回避方法

1. functionがあるのに表示されない

f:id:yuku_t:20111012191827p:image
右側がJavaScriptで左がTagList。明らかにSandboxというのがあるのに含まれていない。何かがおかしい。

ctagsではソースを解析してタグとしてマッチした箇所は、kindという値がそれぞれに割り当てられる。kindの種類を調べるには以下のようにすればいい

$ ctags --list-kings=JavaScript
f  functions
c  classes
m  methods
p  properties
v  global variables

これはつまり、ctagsでJavaScriptのソースを解析すると、5種類のタグが生成される、ということを意味している。

ちなみに、ctagsでタグ抽出を出きるプログラミング言語の一覧は以下のコマンドで得られる。上記のJavaScriptの場所に入る名前は、この出力結果の中に含まれている値でなければならない。

$ ctags --list-languages | grep Java
Java
JavaScript

さて、本題のTagListが出力するタグの種類が明らかに少ない問題は、TagListがJavaScriptの場合はデフォルトでfunctionsに該当するタグだけを表示するように設定されていることが原因だということらしい。画像で示した例の中のSandboxはctags的にはclassesに該当するため、TagListに無視されてしまう。
そこで以下を.vimrcに追加する。(詳しくは :help taglist-extend を参照)

let g:tlist_javascript_settings = 'javascript;c:class;m:method;f:function;p:property'

これで、ctagsによってkindがclasses, methods, functions, propertiesだと判断された箇所に対して、それぞれclass, method, function, propertyというグループでTagListが表示してくれる。

2. 飛ぶ先がおかしい

具体例を示すの面倒なので省きますが、とにかく、関数を選択するとその関数の直前の { に飛ぶことが多々。デフォルトで用意されてるfunctionsの設定が変なのが原因。
というわけで、~/.ctagsに以下を追記する。

--regex-javascript=/([A-Za-z0-9._$()]+)[ \t]*[:=][ \t]*function[ \t]*\(/\1/F,function/

余談
本当は、this.で始まらない、という条件を追加したかったんだけど、上手く行かなかった。正規表現に詳しい人いたら教えてください。僕がやりたいのはこういうことです(イメージ。どっかがおかしい)

--regex-javascript=/(?<!this\.)([A-Za-z0-9._$()]+)[ \t]*[:=][ \t]*function[ \t]*\(/\1/F,function/

この設定の意味は man ctags の --regex- オプションを参照。これがあるとkindが次のようになる

$ ctags --list-kings=JavaScript
f  functions
c  classes
m  methods
p  properties
v  global variables
F  function

一番下の新しく F というのが追加されている。そして、先ほどの設定を以下のように変更する。(f:functionをF:functionに変更)

let g:tlist_javascript_settings = 'javascript;c:class;m:method;F:function;p:property'

以上のように変更するとJavaScriptのソースでもTagListがあれこれ表示してくれるようになる。
f:id:yuku_t:20111012194730p:image