mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-22 15:48:00 +01:00
abbreviations for textboxes (thanks calmar)
This commit is contained in:
2
AUTHORS
2
AUTHORS
@@ -5,6 +5,7 @@ Main developer:
|
||||
Developers:
|
||||
* Viktor Kojouharov (Виктор Кожухаров)
|
||||
* Doug Kearns (dougkearns@gmail.com)
|
||||
* Marco Candrian
|
||||
|
||||
Patches:
|
||||
* Muthu Kannan (ctrl-v support)
|
||||
@@ -12,7 +13,6 @@ Patches:
|
||||
* Lee Hinman (:open ./.. support)
|
||||
* Bart Trojanowski (Makefile)
|
||||
* Hannes Rist (:set titlestring support)
|
||||
* Marco Candrian (shift-insert patch)
|
||||
* Nikolai Weibull ($VIMPERATOR_HOME)
|
||||
* Joseph Xu (supporting multiple top level windows better)
|
||||
</pre>
|
||||
|
||||
1
NEWS
1
NEWS
@@ -8,6 +8,7 @@
|
||||
read up the new help for the f, F and ; commands for details
|
||||
removed the following hint options: 'hintchars'
|
||||
added the following hint options: 'hinttimeout'
|
||||
* abbreviations for text fields (:abbr etc.) (thanks calmar)
|
||||
* you can edit textfields with Ctrl-i now using an external editor (thanks to Joseph Xu)
|
||||
* :open, :bmarks, etc. filter on space separated tokens now, so you can
|
||||
search with :open linux windows <tab> all your bookmarks/history
|
||||
|
||||
@@ -92,7 +92,7 @@ vimperator.Command = function(specs, action, extra_info) //{{{
|
||||
|
||||
vimperator.Command.prototype.execute = function(args, special, count, modifiers)
|
||||
{
|
||||
this.action.call(this, args, special, count, modifiers);
|
||||
return this.action.call(this, args, special, count, modifiers);
|
||||
}
|
||||
|
||||
// return true if the candidate name matches one of the command's aliases
|
||||
@@ -1098,6 +1098,110 @@ vimperator.Commands = function() //{{{
|
||||
"Without arguments, displays a list of all variables."
|
||||
}
|
||||
));
|
||||
// code for abbreviations
|
||||
addDefaultCommand(new vimperator.Command(["ab[breviate]"],
|
||||
function(args)
|
||||
{
|
||||
if (!args)
|
||||
{
|
||||
vimperator.editor.listAbbreviations("!", "");
|
||||
return;
|
||||
}
|
||||
|
||||
var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
|
||||
var [lhs, rhs] = [matches[1], matches[2]];
|
||||
if (rhs)
|
||||
vimperator.editor.addAbbreviation("!", lhs, rhs);
|
||||
else
|
||||
vimperator.editor.listAbbreviations("!", lhs);
|
||||
},
|
||||
{
|
||||
usage: ["ab[breviate] {lhs} {rhs}", "ab[breviate] {lhs}", "ab[breviate]"],
|
||||
short_help: "Abbreviate a key sequence",
|
||||
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/>"
|
||||
}
|
||||
));
|
||||
addDefaultCommand(new vimperator.Command(["ca[bbrev]"],
|
||||
function(args)
|
||||
{
|
||||
if (!args)
|
||||
{
|
||||
vimperator.editor.listAbbreviations("c", "");
|
||||
return;
|
||||
}
|
||||
|
||||
var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
|
||||
var [lhs, rhs] = [matches[1], matches[2]];
|
||||
if (rhs)
|
||||
vimperator.editor.addAbbreviation("c", lhs, rhs);
|
||||
else
|
||||
vimperator.editor.listAbbreviations("c", lhs);
|
||||
},
|
||||
{
|
||||
usage: ["ca[bbrev] {lhs} {rhs}", "ca[bbrev] {lhs}", "ca[bbrev]"],
|
||||
short_help: "Abbreviate a key sequence for Command-line mode",
|
||||
help: "Same as <code class='command'>:ab[reviate]</code>, but for Command-line mode only."
|
||||
}
|
||||
));
|
||||
addDefaultCommand(new vimperator.Command(["ia[bbrev]"],
|
||||
function(args)
|
||||
{
|
||||
if (!args)
|
||||
{
|
||||
vimperator.editor.listAbbreviations("i", "");
|
||||
return;
|
||||
}
|
||||
|
||||
var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/)
|
||||
var [lhs, rhs] = [matches[1], matches[2]];
|
||||
if (rhs)
|
||||
vimperator.editor.addAbbreviation("i", lhs, rhs);
|
||||
else
|
||||
vimperator.editor.listAbbreviations("i", lhs);
|
||||
},
|
||||
{
|
||||
usage: ["ia[bbrev] {lhs} {rhs}", "ia[bbrev] {lhs}", "ia[bbrev]"],
|
||||
short_help: "Abbreviate a key sequence for Insert mode",
|
||||
help: "Same as <code class='command'>:ab[breviate]</code>, but for Insert mode only."
|
||||
}
|
||||
));
|
||||
addDefaultCommand(new vimperator.Command(["una[bbreviate]"],
|
||||
function(args) { vimperator.editor.removeAbbreviation("!", args); },
|
||||
{
|
||||
usage: ["una[bbreviate] {lhs}"],
|
||||
short_help: "Remove an abbreviation"
|
||||
}
|
||||
));
|
||||
addDefaultCommand(new vimperator.Command(["cuna[bbrev]"],
|
||||
function(args) { vimperator.editor.removeAbbreviation("c", args); },
|
||||
{
|
||||
usage: ["cuna[bbrev] {lhs}"],
|
||||
short_help: "Remove an abbreviation for Command-line mode",
|
||||
help: "Same as <code class='command'>:una[bbreviate]</code>, but for Command-line mode only."
|
||||
}
|
||||
));
|
||||
addDefaultCommand(new vimperator.Command(["iuna[bbrev]"],
|
||||
function(args) { vimperator.editor.removeAbbreviation("i", args); },
|
||||
{
|
||||
usage: ["iuna[bbrev] {lhs}"],
|
||||
short_help: "Remove an abbreviation for Insert mode",
|
||||
help: "Same as <code class='command'>:una[bbreviate]</code>, but for Insert mode only."
|
||||
}
|
||||
));
|
||||
addDefaultCommand(new vimperator.Command(["ab[clear]"],
|
||||
function(args) { vimperator.editor.removeAllAbbreviations("!"); },
|
||||
{ short_help: "Remove all abbreviations" }
|
||||
));
|
||||
addDefaultCommand(new vimperator.Command(["cab[clear]"],
|
||||
function(args) { vimperator.editor.removeAllAbbreviations("c"); },
|
||||
{ short_help: "Remove all abbreviations for Command-line mode" }
|
||||
));
|
||||
addDefaultCommand(new vimperator.Command(["iab[clear]"],
|
||||
function(args) { vimperator.editor.removeAllAbbreviations("i"); },
|
||||
{ short_help: "Remove all abbreviations for Insert mode" }
|
||||
));
|
||||
addDefaultCommand(new vimperator.Command(["map"],
|
||||
// 0 args -> list all maps
|
||||
// 1 arg -> list the maps starting with args
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
/***** BEGIN LICENSE BLOCK ***** {{{
|
||||
*
|
||||
* Mozilla Public License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License
|
||||
* at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2007: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
}}} ***** END LICENSE BLOCK *****/
|
||||
|
||||
// command names taken from:
|
||||
@@ -19,9 +31,10 @@
|
||||
|
||||
vimperator.Editor = function() //{{{
|
||||
{
|
||||
// store our last search with f,F,t or T
|
||||
// store our last search with f, F, t or T
|
||||
var last_findChar = null;
|
||||
var last_findChar_func = null;
|
||||
var abbrev = {}; // abbrev["lhr"][0] is the {rhs} and abbrev["lhr"][1] the mode {i,c,!}
|
||||
|
||||
function editor()
|
||||
{
|
||||
@@ -379,6 +392,119 @@ vimperator.Editor = function() //{{{
|
||||
|
||||
tmpfile.remove(false);
|
||||
}
|
||||
|
||||
// Abbreviations {{{
|
||||
// TODO: won't save into vimperatorrc? with mkvimperatorrc
|
||||
|
||||
// filter is i, c or "!" (insert or command abbreviations or both)
|
||||
this.listAbbreviations = function(filter, lhs)
|
||||
{
|
||||
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.removeAllAbbreviations = 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
|
||||
{
|
||||
var textbox = editor();
|
||||
var text = textbox.value;
|
||||
var currStart = textbox.selectionStart;
|
||||
var currEnd = textbox.selectionEnd;
|
||||
var foundWord = text.substring(0, currStart).replace(/^(.|\n)*?(\S+)$/m, "$2"); // get last word \b word boundary
|
||||
if (!foundWord)
|
||||
return true;
|
||||
|
||||
for (var item in abbrev)
|
||||
{
|
||||
if (item == foundWord && (abbrev[item][1] == filter || abbrev[item][1] == "!"))
|
||||
{
|
||||
// if found, replace accordingly
|
||||
var len = foundWord.length;
|
||||
var abbr_text = abbrev[item][0];
|
||||
text = text.substring(0, currStart - len) + abbr_text + text.substring(currStart);
|
||||
textbox.value = text;
|
||||
textbox.selectionStart = currStart - len + abbr_text.length;
|
||||
textbox.selectionEnd = currEnd - len + abbr_text.length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//}}}
|
||||
} //}}}
|
||||
|
||||
// vim: set fdm=marker sw=4 ts=4 et:
|
||||
|
||||
@@ -622,7 +622,6 @@ vimperator.Events = function() //{{{
|
||||
|
||||
|
||||
// if Hit-a-hint mode is on, special handling of keys is required
|
||||
// FIXME: <Esc> should be handled properly!
|
||||
if (key != "<Esc>" && key != "<C-[>")
|
||||
{
|
||||
if (vimperator.mode == vimperator.modes.HINTS)
|
||||
@@ -684,7 +683,9 @@ vimperator.Events = function() //{{{
|
||||
else
|
||||
{
|
||||
vimperator.input.buffer = "";
|
||||
map.execute(null, vimperator.input.count);
|
||||
var ret = map.execute(null, vimperator.input.count);
|
||||
if (map.flags & vimperator.Mappings.flags.ALLOW_EVENT_ROUTING && ret)
|
||||
stop = false;
|
||||
}
|
||||
}
|
||||
else if (vimperator.mappings.getCandidates(vimperator.mode, candidate_command).length > 0)
|
||||
|
||||
@@ -87,7 +87,8 @@ vimperator.Map.prototype.execute = function(motion, count, argument)
|
||||
args.push(count);
|
||||
if (this.flags & vimperator.Mappings.flags.ARGUMENT)
|
||||
args.push(argument);
|
||||
this.action.apply(this, args);
|
||||
|
||||
return this.action.apply(this, args);
|
||||
}
|
||||
//}}}
|
||||
|
||||
@@ -176,9 +177,10 @@ vimperator.Mappings = function() //{{{
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
vimperator.Mappings.flags = {
|
||||
MOTION: 1 << 0,
|
||||
COUNT: 1 << 1,
|
||||
ARGUMENT: 1 << 2
|
||||
ALLOW_EVENT_ROUTING: 1 << 0, // if set, return true inside the map command to pass the event further to firefox
|
||||
MOTION: 1 << 1,
|
||||
COUNT: 1 << 2,
|
||||
ARGUMENT: 1 << 3
|
||||
};
|
||||
|
||||
// NOTE: just normal mode for now
|
||||
@@ -1948,7 +1950,7 @@ vimperator.Mappings = function() //{{{
|
||||
addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.COMMAND_LINE], ["<C-u>"],
|
||||
function()
|
||||
{
|
||||
// broken in FF3, deletes the wohle line:
|
||||
// broken in FF3, deletes the whole line:
|
||||
// vimperator.editor.executeCommand("cmd_deleteToBeginningOfLine", 1);
|
||||
vimperator.editor.executeCommand("cmd_selectBeginLine", 1);
|
||||
vimperator.editor.executeCommand("cmd_delete", 1);
|
||||
@@ -1979,6 +1981,24 @@ vimperator.Mappings = function() //{{{
|
||||
function() { vimperator.editor.editWithExternalEditor(); },
|
||||
{ }
|
||||
));
|
||||
addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.TEXTAREA], ["<Space>", "<Tab>", "<Return>"],
|
||||
function() { return vimperator.editor.expandAbbreviation("i"); },
|
||||
{ flags: vimperator.Mappings.flags.ALLOW_EVENT_ROUTING }
|
||||
));
|
||||
addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.TEXTAREA],
|
||||
["<C-]>", "<C-5>"], function() { vimperator.editor.expandAbbreviation("i"); }, { }
|
||||
));
|
||||
|
||||
//}}}
|
||||
// COMMAND_LINE mode
|
||||
//{{{
|
||||
addDefaultMap(new vimperator.Map([vimperator.modes.COMMAND_LINE], ["<Space>"],
|
||||
function() { return vimperator.editor.expandAbbreviation("c"); },
|
||||
{ flags: vimperator.Mappings.flags.ALLOW_EVENT_ROUTING }
|
||||
));
|
||||
addDefaultMap(new vimperator.Map([vimperator.modes.COMMAND_LINE],
|
||||
["<C-]>", "<C-5>"], function() { vimperator.editor.expandAbbreviation("c"); }, { }
|
||||
));
|
||||
|
||||
//}}}
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ vimperator.CommandLine = function() //{{{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
const UNINITIALIZED = -2; // notifies us, if we need to start history/tab-completion from the beginning
|
||||
|
||||
var completionlist = new vimperator.InformationList("vimperator-completion", { min_items: 2, max_items: 10 });
|
||||
|
||||
Reference in New Issue
Block a user