DSL の見出し抽出には Vim の複合ファイルタイプを積極的に利用しよう

obsolete

この記事で紹介している、Vim の複合ファイルタイプ(compound filetype){記述言語}.{DSL} を {記述言語}_{DSL}.vim の outline info にマップするというやり方は改めます。

このやり方だとユーザーがいちいち ftdetect にて複合ファイルタイプの設定をしなければならず面倒な上、vim-ruby のような ftdetect を同梱しているプラグインとの相性も悪い。よって、{記述言語} の outline info が context.buffer.path などを参照しつつ、条件によって {DSL}用の outline info を返すような仕組みを考え中。(追記:2011年10月14日)



DSL ごとに見出しの抽出ルールは異なる

unite-outline を使っていて、例えば RSpec のスペックファイルから適当に見出しを拾おうとした場合、Ruby で通常見出しとして扱われる module, class, def に加えて

describe と it も見出しとしてマッチするようにしよう!

と考えることはとても自然なことです。unite-outline に同梱されている Ruby用の outline info をそのように修正して使っている人もいます。

では、Rakefile はどうしましょう。

task と file も見出しとしてマッチするようにしよう!

RubyDSL ってこれで終わりでしょうか? 他にも色々ありますよね明らかに。その度に、

これも見出しとしてマッチするようにしよう!

とあれこれ追加していくと、Ruby用の outline info はそのうち収拾がつかないことになると思われます。ある DSL ではそれは見出しなんだけど、別の DSL ではそれは違うんだ、みたいな問題が出てきそうです。

ここでの問題は、DSL にはそれぞれ固有の見出し抽出ルールがあるはずなのに、ファイルタイプがすべて記述言語のそれ(この例では Ruby)になってしまうということです。

DSL ごとに固有の outline info を呼び出せればいいのになー、ということになります。

Vim には複合ファイルタイプというものがあってだな……

unite-outline ではこの問題を解決するために、複合ファイルタイプという Vim のマイナー機能を使い、個々の DSL に対応した複合ファイルタイプ用に outline info を用意することとしました。

Vim: Filetype pluginを極める - while ("im automaton");


# 一般的に知られていないことだが、'filetype'は複数の値を設定できる。例えば:setfiletype c.doxygenなどとピリオドで区切った名前の列によって複数の値を持たせることができる。個人的には、複数の値を持つ場合は「compound filetype」、通常の値の場合は「simple filetype」と呼び分けている。


# Compound filetypeの場合、名前が列挙されている順にfiletype pluginのロードが行われる。例えば'filetype'がc.doxygenの場合、まずc用のものがロードされ、その後でdoxygen用のものがロードされる。

具体的には、RSpec のスペックファイル用に、複合ファイルタイプ ruby.rspec の outline info として ruby_rspec.vim を作成し、ファイルタイプが ruby.rspec であれば、ruby.vim に優先して ruby_rspec.vim が使われるようにしました。

これにより、ruby.vim には手を入れることなく、無数の RubyDSL向けに outline info を提供できるようになりました。

複合ファイルタイプの設定方法

Vim Hacks の以下のエントリにて、xxx_spec.rb のファイルタイプを ruby.rspec にする設定方法が解説されています。(末尾の方)

同じ要領で、{記述言語}.{DSL} な複合ファイルタイプの設定を行えば、DSL固有の outline info を利用できるようになります。

また、

:help ftdetect

も熟読をお勧めします。(個人的には vimrc に直接ファイルタイプの設定を書くよりこちらの方が好み)

複合ファイルタイプ設定のススメ

{記述言語}_{DSL}.vim な outline info が見つからなければ {記述言語}.vim へと fallback するので、複合ファイルタイプの設定は必須ではありません。

が、プログラミング言語用の outline info は、素朴なパターンマッチ方式から外部の構文解析プログラムを利用する方式へと徐々に置き換えられていく流れなので、

DSL の見出しを拾うために {記述言語}.vim の見出し抽出パターンをちょこっといじって、みたいな方法はいずれ使えなく可能性が大です。

なので、今のうちに複合ファイルタイプの設定と、{記述言語}_{DSL}.vim の作成をやっておくことをお勧めします。