もうちょっとスクリプティングについて整理してみよう。
- なぜスクリプティングが必要なのか?
ユーザに wasavi の動作を好きにさせるため - どのような動作をスクリプタブルにするのか?
バッファへの読み込みの前後、書き込みの前後、モード変更の前後、オプションの変更時などでイベントを発生させ、各タイミングでユーザ定義のスクリプトを実行させる。スクリプト内で、wasavi に対してなにがしかの動作を行わせるようにする。また、ex コマンドに :script(スクリプトの定義と実行)、および vim で言うところの :command を追加する。 - スクリプトの言語は何か?
javascript。javascript でやるとすると、なんでもやり放題というふうにはさせないようにしなければならないのと、同期・非同期のことを考える必要がある。前者は sandbox な iframe 内で実行させるようにすればいいかもしれない。例によって Opera だけ sandbox にまだ対応していないが、まあこれは html5 の仕様なのでいずれ実装される。されたらいいな。後者は難しい。スクリプトの呼び出し自体を同期的にするか、非同期的にするか? また、スクリプトに対しては wasavi を操作するインターフェースを公開することになるのだが、スクリプトからの wasavi の呼び出しもまた同期的なのか、非同期的なのかを考える必要がある。
まずスクリプト自体の呼び出しだが、これは両方サポートする必要があると思う。バッファを編集するコマンドとして定義したスクリプトは、シーケンシャルに実行されないと辻褄が合わなくなる。一方、たとえば XHR を利用して何処かに何かを通知するようなスクリプトは、別にサーバの応答をその場で待つ必要もないだろう。そういうわけで両方必要。
呼び出し方。:script コマンドにスクリプトのソースを引数として与えて
:script foo();
あるいは :script と :scriptend コマンドのペアの間に記述して
:script async
function foo () {
wasavi.run('Ihello, world\u001b');
}
foo();
:scriptend
みたいな感じか。デフォルトは同期呼び出しで、:script の最初の引数が “async” だったら非同期スクリプトとして呼び出す……みたいな。いやダメだな。非同期として設計されたスクリプトを同期設計のつもりで呼び出したり、その逆が起こりうる。スクリプト自身が動作を表明した方がいい。
:script
wasavi.async = true;
function foo () {
;
}
foo();
:scriptend
こんな感じか。
だいたいイメージが固まってきたかな!