aboutsummaryrefslogtreecommitdiffstats
path: root/char-hints-mod2.js
blob: cd322a51962a824f29f93f9910d7c7d044e3f438 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// PLUGIN_INFO//{{{
var PLUGIN_INFO =
<VimperatorPlugin>
    <name>{NAME}</name>
    <description>character hint mode.</description>
    <author mail="konbu.komuro@gmail.com" homepage="http://d.hatena.ne.jp/hogelog/">hogelog</author>
    <version>0.0.1</version>
    <minVersion>2.0pre</minVersion>
    <maxVersion>2.0pre</maxVersion>
    <detail><![CDATA[

== Usage ==
LowerCase => input hint command line.
UpperCase => select char-hint label.

小文字は候補を絞るためのテキスト入力に使います
大文字は文字ラベルの選択に使います

== OPTIONS ==
set histchars="hjkl" => show char-hint use h, j, k, l.

== TODO ==
 * support hinttimeout.
     ]]></detail>
</VimperatorPlugin>;
//}}}

(function () {

    const DEFAULT_HINTCHARS = "HJKLASDFGYUIOPQWERTNMZXCVB";

    options.add(["hintchars", "hchar"],
        "Hint characters",
        "string", DEFAULT_HINTCHARS);

    function chars2num(chars) //{{{
    {
        var num = 0;
        var hintchars = options.hintchars.toUpperCase();
        var base = hintchars.length;
        for(let i=0,l=chars.length;i<l;++i) {
            num = base*num + hintchars.indexOf(chars[i]);
        }
        return num;
    } //}}}
    function num2chars(num) //{{{
    {
        var chars = "";
        var hintchars = options.hintchars;
        var base = hintchars.length;
        do {
            chars = hintchars[((num % base))] + chars;
            num = Math.floor(num/base);
        } while(num>0);

        return chars;
    } //}}}
    function showCharHints() //{{{
    {
        for(let elem in buffer.evaluateXPath("//*[@liberator:highlight and @number]", window.content.document))
        {
            let num = elem.getAttribute("number");
            let hintchar = num2chars(parseInt(num, 10));
            elem.setAttribute("hintchar", hintchar);
        }
    } //}}}

    var hintContext = hints.addMode;
    var hintChars = [];
    var charhints = plugins.charhints = {
        show: function (minor, filter, win) //{{{
        {
            charhints.original.show(minor, filter, win);
            hintChars = [];
            showCharHints();
        }, //}}}
        onInput: function (event) //{{{
        {
            var hintString = commandline.command;
            commandline.command = hintString.replace(/[A-Z]+/g, "");
            charhints.original.onInput(event);
            showCharHints();
            for(let i=0,l=hintString.length;i<l;++i) {
                if(/^[A-Z]$/.test(hintString[i])) {
                    hintChars.push(hintString[i]);
                }
            }
            if(hintChars.length>0) {
                let numstr = String(chars2num(hintChars.join("")));
                setTimeout(function () {
                    for(let i=0,l=numstr.length;i<l;++i) {
                        let num = numstr[i];
                        let alt = new Object;
                        alt.liberatorString = num;
                        hints.onEvent(alt);
                    }
                }, 10);
            }
        }, //}}}
    };

    if(!charhints.original) {
        charhints.original = {
            show: hints.show,
            onInput: liberator.eval("onInput", hintContext),
        };

        charhints.install = function () //{{{
        {
            hints.show = charhints.show;
            liberator.eval("onInput = plugins.charhints.onInput", hintContext);

            highlight.CSS = highlight.CSS.replace(
                    "Hint::after,,*  content: attr(number);",
                    "Hint::after,,*  content: attr(hintchar);");
            highlight.reload();
        }; //}}}
        charhints.uninstall = function () //{{{
        {
            hints.show = charhints.original.show;
            liberator.eval("onInput = plugins.charhints.original.onInput", hintContext);

            highlight.CSS = highlight.CSS.replace(
                    "Hint::after,,*  content: attr(hintchar);",
                    "Hint::after,,*  content: attr(number);");
            highlight.reload();
        }; //}}}
    }
    charhints.install();
})();

// vim: set fdm=marker sw=4 ts=4 et: