[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