[Vimperator] abbreviation (patch)

calmar mac at calmar.ws
Wed Oct 31 23:46:29 PDT 2007


Hi all,

well, there is the need to let the <TAB>'s <Space>'s etc dispatch
(or however) further - properly.

arg, well, it's not possible to setup two identical abbreviation
for either i or c with a different rhl. There cold be done some
hackish thing to provide that. Actually a case what shouldn't
happen really often (aka *very* seldom in real-live even?), so I
didn't do anywthing for that yet.

There would be some solutions I have in Mind, but just very 'not
nice' - many additional if statements...

beeing able to 'ask' for a particular 'lhs' (assoziative) is not
too bad so. (instead of always looping through just to find a
possible match).

besides:

when there is a c abb and a identical i abb it adds up to ! (here
the 'bug' mentioned above would be active as well).

when there are ! abbrevs, and there is a iunab on that, a c is
resulting. The same as on Vim.

Cheers
marco

-- 
   (o_  It rocks: LINUX + Command-Line-Interface
   //\
   V_/_                     http://www.calmar.ws
-------------- next part --------------
? abbr.patch
? diff.patch
? tmp_abbrev.patch
Index: commands.js
===================================================================
RCS file: /cvs/vimperator/src/content/commands.js,v
retrieving revision 1.44
diff -u -r1.44 commands.js
--- commands.js	31 Oct 2007 09:02:03 -0000	1.44
+++ commands.js	1 Nov 2007 06:21:10 -0000
@@ -1098,6 +1098,174 @@
                   "Without arguments, displays a list of all variables."
         }
     ));
+    addDefaultCommand(new vimperator.Command(["ab[breviate]"],
+        function(args)
+        {
+
+            var filter = "!";
+            if (!args)
+            {
+                vimperator.editor.listAbbreviation(filter, "");
+                return;
+            }
+
+            var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
+            var [lhs, rhs] = [matches[1], matches[2]];
+
+            if (rhs)
+            {
+                vimperator.editor.addAbbreviation(filter, lhs, rhs); 
+            } 
+            else
+            {
+                vimperator.editor.listAbbreviation(filter, lhs);
+            }
+        },
+        {
+            usage: ["ab[breviate] {lhs} {rhs}", "ab[breviate] {lhs}", "ab[breviate]"],
+            short_help: "Abbreviate the key sequence {lhs} to {rhs} in 'insert and comment' mode.",
+            help: "Abbreviate <code class=\"argument\">{lhs}</code> to <code class=\"argument\">{rhs}</code>.<br/>" +
+                  "If only <code class=\"argument\">{lhs}</code> given, list that particual abbreviation.<br />" +
+                  "List all abbreviations, if no arguments to are given.<br />" +
+                  "Abbreviations are NOT saved during sessions, make sure you put them in your vimperatorrc file!"
+        }
+    ));
+    addDefaultCommand(new vimperator.Command(["una[bbreviate]"],
+        function(args)
+        {
+        //TODO: check that args is ok.. e.g. no rhl
+                vimperator.editor.removeAbbreviation("!", args);
+        },
+        {
+            usage: ["cuna[bbrev]"],
+            short_help: "Delete {lhr} 'command' abbreviations.",
+            help: "Delete {lhr} 'command' abbreviations."
+        }
+    ));
+    addDefaultCommand(new vimperator.Command(["ab[clear]"],
+        function(args)
+        {
+
+                vimperator.editor.removeAllAbbreviation("!");
+        },
+        {
+            usage: ["cabc[lear]"],
+            short_help: "Delelte all 'command' abbreviations.",
+            help: "Delete all 'command' abbreviations."
+        }
+    ));
+    addDefaultCommand(new vimperator.Command(["ca[bbrev]"],
+        function(args)
+        {
+
+            var filter = "c";
+            if (!args)
+            {
+                vimperator.editor.listAbbreviation(filter,"");
+                return;
+            }
+
+            var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
+            var [lhs, rhs] = [matches[1], matches[2]];
+
+            if (rhs)
+            {
+                vimperator.editor.addAbbreviation(filter, lhs, rhs); 
+            } 
+            else
+            {
+                vimperator.editor.listAbbreviation(filter, lhs);
+            }
+        },
+        {
+            usage: ["ca[bbrev] {lhs} {rhs}", "ca[bbrev] {lhs}", "ca[bbrev]"],
+            short_help: "Abbreviate the key sequence {lhs} to {rhs} in 'comment' mode.",
+            help: "Abbreviate <code class=\"argument\">{lhs}</code> to <code class=\"argument\">{rhs}</code>.<br/>" +
+                  "If only <code class=\"argument\">{lhs}</code> given, list that particual abbreviation.<br />" +
+                  "List all abbreviations, if no arguments are given.<br />" +
+                  "Abbreviations are NOT saved during sessions, make sure you put them in your vimperatorrc file!"
+        }
+    ));
+    addDefaultCommand(new vimperator.Command(["cuna[bbrev]"],
+        function(args)
+        {
+        //TODO: check that args is ok.. e.g. no rhl
+                vimperator.editor.removeAbbreviation("c", args);
+        },
+        {
+            usage: ["cuna[bbrev]"],
+            short_help: "Delete {lhr} 'command' abbreviations.",
+            help: "Delete {lhr} 'command' abbreviations."
+        }
+    ));
+    addDefaultCommand(new vimperator.Command(["cab[clear]"],
+        function(args)
+        {
+
+                vimperator.editor.removeAllAbbreviation("c");
+        },
+        {
+            usage: ["cabc[lear]"],
+            short_help: "Delelte all 'command' abbreviations.",
+            help: "Delete all 'command' abbreviations."
+        }
+    ));
+    addDefaultCommand(new vimperator.Command(["ia[bbrev]"],
+        function(args)
+        {
+
+            var filter = "i";
+            if (!args)
+            {
+                vimperator.editor.listAbbreviation(filter,"");
+                return;
+            }
+
+            var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
+            var [lhs, rhs] = [matches[1], matches[2]];
+
+            if (rhs)
+            {
+                vimperator.editor.addAbbreviation(filter, lhs, rhs); 
+            } 
+            else
+            {
+                vimperator.editor.listAbbreviation(filter, lhs);
+            }
+        },
+        {
+            usage: ["ia[bbrev] {lhs} {rhs}", "ia[bbrev] {lhs}", "ia[bbrev]"],
+            short_help: "Abbreviate the key sequence {lhs} to {rhs} in insert mode.",
+            help: "Abbreviate <code class=\"argument\">{lhs}</code> to <code class=\"argument\">{rhs}</code>.<br/>" +
+                  "If only <code class=\"argument\">{lhs}</code> given, list that particual abbreviation.<br />" +
+                  "List all abbreviations, if no arguments are given.<br />" +
+                  "Abbreviations are NOT saved during sessions, make sure you put them in your vimperatorrc file!"
+        }
+    ));
+    addDefaultCommand(new vimperator.Command(["iuna[bbrev]"],
+        function(args)
+        {
+        //TODO: check that args is ok.. e.g. no rhl
+                vimperator.editor.removeAbbreviation("i", args);
+        },
+        {
+            usage: ["iuna[bbrev]"],
+            short_help: "Delete {lhr} 'insert' abbreviations.",
+            help: "Delete {lhr} 'insert' abbreviations."
+        }
+    ));
+    addDefaultCommand(new vimperator.Command(["iab[clear]"],
+        function(args)
+        {
+
+                vimperator.editor.removeAllAbbreviation("i");
+        },
+        {
+            usage: ["iabc[lear]"],
+            short_help: "Delelte all 'insert' abbreviations.",
+            help: "Delete all 'insert' abbreviations."
+        }
+    ));
     addDefaultCommand(new vimperator.Command(["map"],
         // 0 args -> list all maps
         // 1 arg  -> list the maps starting with args
Index: editor.js
===================================================================
RCS file: /cvs/vimperator/src/content/editor.js,v
retrieving revision 1.6
diff -u -r1.6 editor.js
--- editor.js	25 Oct 2007 13:25:58 -0000	1.6
+++ editor.js	1 Nov 2007 06:21:11 -0000
@@ -379,6 +379,135 @@
 
         tmpfile.remove(false);
     }
+
+    // Abbreviations {{{
+    var abbrev = new Object();  // abbrev["lhr"][0] beeing the rhs
+                                // abbrev["lhr"][1] beeing the mode {i,c,!}
+
+
+    // TODO: after listing the abbreviations, the MOW should close or so after a :
+    //       at least,  issuing :abbr twice, results in a double-height MOW
+    // XXX: won't save into vimperatorrc? with mkvimperatorrc
+    
+
+    this.listAbbreviation = function(filter, lhs)        // filter beeing i or c (insert or command abbreviations)
+    {
+        if (lhs)    // list only that one
+        {
+            if (abbrev[lhs])
+            {
+                vimperator.echo(abbrev[lhs][1] + "    " + lhs + "        " + abbrev[lhs][0]);
+                return true;
+            }
+            vimperator.echoerr("No abbreviations found");
+            return false;
+        } 
+        else      // list all (for that filter {i,c,!})
+        {
+            var flagFound = false;
+            var searchFilter = filter == "!" ? "!ci" : filter + "!"; // ! -> list all, on c or i ! matches too)
+            var list = "<table>";
+            for (var item in abbrev)
+            {
+                if (searchFilter.indexOf(abbrev[item][1]) > -1)
+                {
+                    if (!flagFound)
+                        flagFound = true;
+                    list += "<tr>";
+                    list += "<td> " + abbrev[item][1] + "</td>";
+                    list += "<td> " + vimperator.util.escapeHTML(item) + "</td>";
+                    list += "<td> " + vimperator.util.escapeHTML(abbrev[item][0]) + "</td>";
+                    list += "</tr>";
+                }
+            }
+            if (!flagFound)
+            {
+                vimperator.echoerr("No abbreviations found");
+                return;
+            }
+            list += "</table>";
+            vimperator.commandline.echo(list, vimperator.commandline.HL_NORMAL, vimperator.commandline.FORCE_MULTILINE);
+        }
+    }
+
+    this.addAbbreviation = function(filter, lhs, rhs)
+    {
+        var modeSign = filter;
+
+        // get proper Mode value i + c = !  on identical abbreviations
+        if (abbrev[lhs] && abbrev[lhs][0] == rhs && abbrev[lhs][1] != filter)
+            modeSign = "!";
+
+        abbrev[lhs] = [rhs, modeSign];
+    }
+
+    this.removeAbbreviation = function(filter, lhs)
+    {
+        if (abbrev[lhs])       // abbrev exists
+        {
+            if (filter == "!" || ( abbrev[lhs][1] == filter && filter != "!" ))
+            {                
+                delete (abbrev[lhs]);
+                return true;
+            }
+            else if (abbrev[lhs][1] == "!")   // exists as ! -> no 'full' delete, since filter is not either
+            {
+                abbrev[lhs][1] = filter == "i" ? "c" : "i";   // it's a !; e.g. ! - i = c; ! - c = i
+                return true;
+            }
+
+        }
+        vimperator.echoerr("E24: No such abbreviation");
+        return false;
+    }
+
+    this.removeAllAbbreviation = function(filter)
+    {
+        for (var item in abbrev)
+        {
+            if (filter == "!" || abbrev[item][1] == "!" || abbrev[item][1] == filter)
+                this.removeAbbreviation(filter, item);
+        }
+    }
+
+    this.expandAbbreviation = function(filter)       // try to find an candidate and replace accordingly
+    {
+        if (filter == "c") 
+            var textbox = document.getElementById("vimperator-commandline-command");
+        else
+            var textbox = editor();
+
+        text = textbox.value;
+
+//        if (textbox.setSelectionRange())   // XXX: necessary? doesn't work at least
+        var currPos = textbox.selectionStart;       //current position
+        var foundWord = text.substring(0, currPos).replace(/^.*?(\S+)$/, "$1");     // get last word \b word boundary
+
+        if (!foundWord) // FIXME: dispach further
+            return;
+
+        for (var item in abbrev)
+        {
+            if (item == foundWord && (abbrev[item][1] == filter || abbrev[item][1] == "!"))
+            {
+                // if found, replace accordingly
+                var tmp = currPos - foundWord.length;
+
+                //FIXME: <Tab> if <Tab> etc; not always " "
+                text = text.substring(0, tmp) +  abbrev[item][0] + " " +  text.substring(currPos);
+                textbox.value = text;
+                textbox.selectionStart = tmp + abbrev[item][0].length + 1; // FIXME: + 1 because of space (only)
+                textbox.selectionEnd = textbox.selectionStart;
+                return;
+            }
+        }
+
+        //FIXME: <Tab> if <Tab> etc; not always " "
+        //        textbox.value = text + " ";
+        //        default action should take place..
+    }
+
+//    //}}}
 } //}}}
 
 // vim: set fdm=marker sw=4 ts=4 et:
Index: mappings.js
===================================================================
RCS file: /cvs/vimperator/src/content/mappings.js,v
retrieving revision 1.32
diff -u -r1.32 mappings.js
--- mappings.js	31 Oct 2007 10:23:48 -0000	1.32
+++ mappings.js	1 Nov 2007 06:21:12 -0000
@@ -1979,6 +1979,17 @@
         function() { vimperator.editor.editWithExternalEditor(); }, 
         { }
     ));
+    addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.TEXTAREA], ["<Space>"], // add <Return> and<Tab> 
+        function() { vimperator.editor.expandAbbreviation("i"); },
+        { }
+    ));
+    //}}}
+    // COMMAND_LINE mode
+    //{{{
+    addDefaultMap(new vimperator.Map([vimperator.modes.COMMAND_LINE], ["<Space>"], // add <Return> and<Tab> 
+        function() { vimperator.editor.expandAbbreviation("c"); },
+        { }
+    ));
 
     //}}}
 


More information about the Vimperator mailing list