id:eel3:20090326:1238028321 の続編。
コードを書く時は基本的にvim派*1なので、関数などのオブジェクトを一覧表示してくれるtaglist.vimを愛用している。
taglist.vimは背後でExuberant Ctagsを使っているので、ctagsの解析能力が向上すれば関数一覧に表示されるものも増えるはず……なんだけど、そこは現実社会ほどではないけど事前の根回しが重要、ということらしい。
ctagsで解析されていても、taglist.vim側で表示しないオブジェクトがある
id:m-hiyama:20080627:1214549228 にsample.jsというサンプルソースがあるけど、試しに手元のExuberant Ctags 5.7J1で「ctags sample.js」でタグを生成させたら、こんな結果になった*2。
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ ! =中略= !_TAG_PROGRAM_VERSION 5.7J1 // Baz sample.js /^function Baz(n) {$/;" c Baz.f5 sample.js /^Baz.prototype.f5 = function() {$/;" m f1 sample.js /^function f1() {$/;" f f2 sample.js /^var f2 = function() {$/;" f f4 sample.js /^ f4: function() {$/;" m foo.f3 sample.js /^foo.f3 = function() {$/;" f g sample.js /^var g = 1;$/;" v
後半に注目。行の末尾にアルファベットが1文字あるけど、これはタグ付けしたオブジェクトの種類を表すフラグ。このフラグの意味は「--list-kinds」で取得できる。
D:\temp>ctags --list-kinds=javascript f functions c classes m methods v global variables m methods D:\temp>
taglist.vimは、標準だとJavaScriptのソースでは上記のfにあたるオブジェクトしか表示しない*3。それ以外も表示したい場合.vimrcないし_vimrcに設定を追加する必要があるらしい。例えばc、f、mに該当するオブジェクトを表示したい場合、.vimrcに次のように追記する。
" taglist.vim: JavaScriptの表示対象を変更 let g:tlist_javascript_settings = 'javascript;c:class;m:method;f:function'
tlist_javascript_settingsという変数を宣言して初期化している。変数名と値のフォーマットについては、taglist.vim ver.4.5の348行目以降が参考になりそう。
ctagsの「--regex-」でマッチしたオブジェクトに割り振るフラグに注意する
「--regex-
--regex-<LANG>=/regexp/replacement/[kind-spec/][flags]
この中の「kind-spec」は、「regexp」にマッチしたオブジェクトに割り振るフラグ文字を指定する。
例えばctagsで「--regex-javascript」を使う場合、
--regex-javascript=/^[ \t]*(.*)[ \t]*:[ \t]*function/\1/m,methods/
末尾側の「/m,methods/」は、
- 正規表現にマッチしたオブジェクトのタグには、フラグ文字としてmを付加する。
- このmはmethodsのm。
という意味になる。指定した正規表現にマッチするオブジェクトがあると、生成されるタグのフラグ文字はmになる。
なので、taglist.vimで表示するようになっていないフラグ文字を指定してしまうと、ctaqgsは該当するオブジェクトへのタグを生成するけどtaglist.vimで表示されない。
「kind-spec」には、taglist.vimで表示する設定になっているフラグを指定すること。
ctagsで同一オブジェクトへのタグを複数生成すると、taglist.vimでも同じオブジェクトが複数表示される
「--regex-
解決策としては2通りが思いつく。
*1:でもCommon LispとRubyとSchemeはNTEmacs。
*2:前のエントリで書いた「--regex-javascript」な方法を適用しているので、ノーマルなctagsとは結果が異なっているので注意。
*3:ver.4.5で確認。