Webブラウザとして良くconkerorを使い始めたのだが,前回終了時のバッファ(いわゆるタブ)を保存することがデフォルトではできない.
公式のWikiや適当にググった結果を見る限り,そのような設定ファイルは見つからなかったので,自分で書いてみた.
Conkerorとは
Mozilla XULRunnerをベースにしたWebブラウザで,
- CUI/TUIでの利用がベース
- Emacsとかviのように,設定ファイルで動作をカスタマイズ可能
という特徴がある.KeySnailが使えなくなる日に備えて徐々にconkerorへの移動を自分は開始してみたが,まだまだ先は長い.
設定ファイル
/**
* The browser restore the windows and buffers from last time.
*/
var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
var startup_filename = ".conkeror_startup";
var startup_file = get_home_directory();
startup_file.append(startup_filename);
function can_restore_windows_and_buffers() {
var count = 0;
var flag = true;
for_each_buffer(function (buffer) {
count += 1;
var uri = buffer.current_uri.resolve(null);
if (uri != null && uri != homepage) {
flag = false;
}
});
return count <= 1 && flag;
}
function should_save_windows_and_buffers() {
var count = 0;
for_each_window(function (w) {
count += 1;
});
// if the number of windows is 1, save windows and buffers.
return count == 1;
}
/* save windows and buffers */
function save_windows_and_buffers() {
try {
var windows = [];
for_each_window(function (w) {
var buffers = [];
w.buffers.for_each(function (buffer) {
buffers.push(buffer.current_uri.resolve(null));
});
windows.push(buffers);
});
var data = JSON.stringify(windows);
/* write file
(https://developer.mozilla.org/ja/docs/Code_snippets/File_I_O#.E3.83.95.E3.82.A1.E3.82.A4.E3.83.AB.E3.81.AB.E6.9B.B8.E3.81.8D.E5.87.BA.E3.81.99)
*/
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
foStream.init(startup_file, 0x02 | 0x08 | 0x20, 0664, 0);
foStream.write(data, data.length);
foStream.close();
} catch (e) {
dumpln("Error in save buffers: " + e);
}
}
// add hook to save the windows and buffers when the conkeror exit.
add_hook("quit_hook", save_windows_and_buffers);
add_hook("window_before_close_hook", function(w) {
if (should_save_windows_and_buffers()) {
save_windows_and_buffers();
}
return true;
});
if (!startup_file.exists()) {
return ;
}
/* read file
(https://developer.mozilla.org/ja/docs/Code_snippets/File_I_O#.E3.83.95.E3.82.A1.E3.82.A4.E3.83.AB.E3.81.AB.E6.9B.B8.E3.81.8D.E5.87.BA.E3.81.99)
*/
var data = "";
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
fstream.init(startup_file, -1, 0, 0);
sstream.init(fstream);
var str = sstream.read(4096);
while (str.length > 0) {
data += str;
str = sstream.read(4096);
}
sstream.close();
fstream.close();
var windows = JSON.parse(data);
add_hook("window_initialize_late_hook", function(w) {
if (!can_restore_windows_and_buffers()) return ;
var buffer = null;
w.buffers.for_each(function(b) {
buffer = b;
});
if (buffer == null) return ;
for (var i = 0, l1 = windows.length; i < l1; i++) {
var window = windows[i];
for (var j = 0, l2 = window.length; j < l2; j++) {
var uri = ioService.newURI(window[j], null, null);
if (j == 0) {
if (i != 0) {
browser_object_follow(buffer, OPEN_NEW_WINDOW, uri.spec);
} else {
browser_object_follow(buffer, OPEN_CURRENT_BUFFER, uri.spec);
}
} else {
browser_object_follow(buffer, OPEN_NEW_BUFFER, uri.spec);
}
}
}
});
${HOME}/.conkeror_startup
ファイルに,前回終了時のバッファ一覧が保存され,起動時にはそのファイルを読んで復元するようになっている.
書いているときにハマったのは,
- conkerorの終了は,次の2つのhookを併用して検出する必要がある(ここが結構ハマった).
-
quit_hook
-
C-x C-c
等での終了時のhook
-
-
window_before_close_hook
が呼び出され,かつ,windowの個数が1個- 何らかの手段で,最後のwindowを閉じたときのhook
-
- スクリプトが呼び出されているタイミングでは,まだwindowは初期化されていない
-
window_initialize_late_hook
を使って,windowが開かれたときに復元処理を行う必要がある
-
の2箇所.この2点を除けば難しいところのないスクリプトだったし,参考URLはコメントで載せてあるので説明は省く.