Firefox のアドオンにおいて、Atom や Sublime Text のように plain text な設定ファイルをメニューから開けるようにするにはどのような方法が考えられるでしょうか。
nsIFile#launch
XPCOM を使って任意のファイルを開くためにまず思いつくのは、nsIFile#launch
を使う方法です。
しかし、これは(おそらく)OS に処理を丸投げしているだけなため、状況や環境によっては問題が生じます。例えば、JSON や XML を開きたい場合、それらがテキストエディタに関連付けられていない環境では、ウェブブラウザで開かれてしまったり、最悪該当アプリケーションがないというエラーが出てしまったりします。
nsIFile#reveal
同じく nsIFile
から、reveal
メソッドを使うという方法も考えられます。これは、ファイルに対して用いるとそのファイルを内包しているフォルダを開くという動作になります(Mac における Reveal in Finder のような機能)。
launch
を使うよりはまだマシですが、結局 JSON や XML の取り扱いに関する知識をユーザーに求めるという点においてあまりよい方法とは言えないでしょう。
nsIProcess
nsIProcess
を利用して、エディタを指定したうえでファイルを開くという方法もあります。
この方法では、Mac/Windows/Linuxでデフォルトのエディタを変えなければならず、設定が複雑になるという欠点があります。
しかし、設定画面を作ることでユーザーが使い慣れたエディタを指定できるようにするなどの機能を提供できるという利点もあるため、ファイルをエディタで開くという動作が多くあるようなアドオンでは検討に値するかもしれません。
Scratchpad
Firefox には Scratchpad という CodeMirror ベースのエディタが内蔵されています。
しかしながら、開発者がどのように Scratchpad を使ったらよいかについての解説は MDN に書かれているものの、プログラムからどのように操作できるのかという点についてはドキュメントが全く存在しません。せっかく内蔵しているのにもったいない…
というわけで、本体のコードを読み解くことで判明した利用方法は以下の通りです。
let fileToOpen = ...; // nsIFile let { ScratchpadManager } = Cu.import('resource:///modules/devtools/scratchpad-manager.jsm', {}); let win = ScratchpadManager.openScratchpad(); win.addEventListener('load', () => { win.Scratchpad.addObserver({ onReady: () => { win.Scratchpad.removeObserver(this); win.Scratchpad.importFromFile(fileToOpen, false, () => { win.Scratchpad.editor.setMode({ name: 'xml' }); }); } }); });
まず、resource:///modules/devtools/scratchpad-manager.jsm にて定義されている ScratchpadManager を読み込みます。
そして、openScratchpad
メソッドにより Scratchpad を開きます。このメソッドは aState
という Optional な引数をとり、初期化時のパラメータを渡すことができるようです。おそらく、Firefox の起動時に前回 Scratchpad で開いていたファイルを復元するために使われているのだと思われます。しかし、ファイル名、ファイルの内容(テキスト)、実行コンテキスト(Content or Browser)を渡せるのみであり、今回の用途には適しませんでした。
ウィンドウの読み込みを待った後は、エディタの初期化を待つ必要があります。これには Scratchpad.addObserver
を用います。初期化が完了すると onReady
が呼ばれます。
最後に、ファイルを読み込むためには Scratchpad.importFromFile(aFile, aSilent, aCallback)
を用います。aFile
は読み込むファイルを、aSilent
は読み込み失敗時にエラーを表示するかどうかを、aCallback
は読み込みが完了した時に呼ばれるコールバックを指定します。
JavaScript を読み込む分には aCallback
を無指定にして読みこめば完了ですが、(Scratchpad は JavaScript 専用エディタのようにできているにも関わらず)他のタイプのファイルを読み込むことも可能であり、その場合はシンタックスハイライトを適切に設定しなくてはいけません。具体的には上の win.Scratchpad.editor.setMode({ name: 'xml' });
の部分がそれです。
エディタの設定は Scratchpad.editor
(実体は devtools/sourceeditor/editor.js)からいろいろできるっぽく(あまり調べていない)、いじってみるとなにかおもしろいことができそうな雰囲気がします。ちなみに、editor.js には xml
というモードは定義されていませんが、指定してみたら動作しました :)
まとめ
- テキストファイルを開くなら nsIProcess か Scratchpad
- Scratchpad を外部からいろいろやるとおもしろそう