plugin load order
2.0pre のハナシ ( いやまぁここではいつも 2.0pre のハナシしかしてないけどきにすんな ) 。以下で話題が出てる library for plugins なんだけどおれも前々から highlight.js とか spellchecker.js とか書いてたので、読み込まれるタイミングの制御ができればなーということで調べてみた結果。
- http://d.hatena.ne.jp/nokturnalmortum/20081207/1228624507
- http://coderepos.org/share/browser/lang/javascript/vimperator-plugins/trunk/libly.js
まず plugin の load 順は現在以下のようになっている ( 教えてくれた id:nokturnalmortum , id:teramako ありがとう ) 。
- runtimepath に記載された directory ( 以下 $RUNTIMEPATH ) 順に以下を行う
- $RUNTIMEPATH/plugin にあるファイルを辞書順 ( localeCompare ) に sort した順番で読み込んでいく
- 読み込む際は io.source 関数を使う
runtimepath の扱いは :help initialization
の記述と違って 'plugin' という下位 directory を参照するようになってるけどソース ( loadPlugins in http://vimperator.org/trac/gitweb/?p=liberator.git;f=common/content/liberator.js;hb=HEAD ) にそう書いてあるので仕方ない。そのうちどちらかが直されると思う。
というわけで以下の 3 (+1) 種類の方法が考えられる。前半 2 つが利用者が使える手法、後半は plugin 作者が考慮すべき手法。
- runtimepath
- library をおく directory を作ってその path を runtimepath に指定する。この際の指定は相対パスでもいいので、たとえば以下のようにすると $HOME/vimperator/library/plugin が library をおく directory 、 $HOME/vimperator/plugin が普通の plugin をおく directory になる。
:set runtimepath=vimperator/library,vimperator
- rename
- 先に読み込みたい plugin のファイル名の先頭に数字をつける。細かく制御したい場合は数字が若い順に読み込まれることを利用して以下のようにするといいかも。ただ '2_a.js' と '10_a.js' だと sort の関係上 '10_a.js' が先に読み込まれるので数字部分は桁あわせをしたほうがいい。 CodeRepos にはすでに 100 を越える plugin があるし今現在も増え続けているので 3 桁であわせてもいいかもしれない。
- 01_libly.js
- 02_highlight.js
- 03_spellchcker.js
- 04_oreorelibrary.js
- appendAnchor.js
- ...
- 先に読み込みたい plugin のファイル名の先頭に数字をつける。細かく制御したい場合は数字が若い順に読み込まれることを利用して以下のようにするといいかも。ただ '2_a.js' と '10_a.js' だと sort の関係上 '10_a.js' が先に読み込まれるので数字部分は桁あわせをしたほうがいい。 CodeRepos にはすでに 100 を越える plugin があるし今現在も増え続けているので 3 桁であわせてもいいかもしれない。
- io.source / io.sourceFromRuntimePath
- io.source は実質絶対パスで指定しないといけないので Windows 環境なら
io.source('%HOME%/vimperator/plugin/libly.js')
とかしないといけないんだけど環境によって %HOME% と $HOME を使い分けないといけないとか plugin のある directory path を知ってないといけないので plugin 内で使うのは実質無理。 - 幸い io.sourceFromRuntimePath method というものが用意されていて rumtimepath で指定した directory を探しに行ってくれる。のでたとえば
io.sourceFromRuntimePath('plugin/libly.js')
っていう風に書ける。
- io.source は実質絶対パスで指定しないといけないので Windows 環境なら
- setTimeout
- 番外編。 JavaScript で何か処理を遅延させたいときの常套手段。 library を使う側を setTimeout で囲む。そうするとその plugin だけ遅延して実行されるので結果的に library が先に読み込まれる。
- library を使う側が考慮しなきゃならないのでめんどくさい。さらに遅延時間やタイミングによって library の読み込みが間に合わないこともあるので確実性に欠ける。というわけで結果的に使わないのがいいと思う。
で、どの手法をとるのがいいかというとやっぱり plugin 制作者が 3 番で対処するのがみんなが幸せになれそう。てか既に multi_requester.js ではそうしてる。ただまぁ、なんか動作がおかしいとか動かないといったときのために利用者は 1, 2 番の方法を覚えておくといいかも。