statuslineに現在のモードなどを表示するスクリプト

今日は「statuslineにMIMEタイプと文字コードとを表示するスクリプト - くふんを狙え」で書いたスクリプトを改良して「statuslineに現在のモードなどを表示するスクリプト」を書いたという話。

maine_coon.js 画面をひろくひろく使う - くふんを狙え」でも書いたように、maine_coon.jsは便利だが、現在のモードが分からなくなるという問題がある。そこでstatuslineに現在のモードを表示してやることにした。

現在のモードについてはmodes.getMode(liberator.mode).nameとやれば取得できる。しかし「-- PASS THROUGH --」などはモードとして扱われていないため取得できない。

では、Vimperator自身はどう処理しているのか。確認したところ、これらの表示はmodesのプライベートな関数であるgetModeMessage()が処理している。そこでid:nokturnalmortum先生の黒魔術を真似てliberator.eval()してやる*1。びっくりするほど予定どおり動いた。

以前書いた「statuslineにMIMEタイプと文字コードを表示するスクリプト」と「statuslineの[+-]を<>にして左端に表示するスクリプトの機能とをまぜる。それでできたものが以下。

(function() {
    // statuslineに現在のモードと履歴とMIMEタイプと文字コードとを表示する
    liberator.plugins.krogueUpdateStatusBar = function() {
        var target = document.getElementById("liberator-statusline");
        var id_prefix = "liberator-statusline-field-";
        var items = [
            {
                id: "krogue-history",
                pos: "before",
                func: function() {
                    var history = getWebNavigation().sessionHistory;
                    return "[" + (history.index > 0 ? "<" : " ") + "|" + (history.index < history.count - 1 ? ">" : " ") + "]";
                },
            },
            {
                id: "krogue-contenttype",
                func: function() window.content.document.contentType,
            },
            {
                id: "krogue-characterset",
                func: function() window.content.document.characterSet,
            },
            {
                id: "krogue-modemessage",
                pos: "before",
                func: function() liberator.eval("getModeMessage", modes.getMode)().replace(/^-- (.*) --$/, "$1"),
            },
        ];
        items.forEach(function(item, i, arr) {
            var label = document.getElementById(id_prefix + item.id);
            if (!label) {
                label = document.createElement("label");
                label.setAttribute("class", "plain");
                label.setAttribute("id", id_prefix + item.id);
                label.setAttribute("flex", 0);
                switch (item.pos) {
                    case "before":
                        target.insertBefore(label, target.firstChild);
                        break;
                    case "after":
                        target.appendChild(label);
                        break;
                    default:
                        target.appendChild(label);
                }
            }
            label.setAttribute("value", item.func());
        });
    };
    setInterval(liberator.plugins.krogueUpdateStatusBar, 100);
})();

autocommandはうるさかったので、代わりに100msごとに更新するようにしてみた。

今日はここまで。またすこし使いやすくなりましたとさ。

id間違えてたので修正。nokturnalmortumさん、ごめんなさい。

*1:書いていて「魔法使いの弟子」が思い浮かんだ