1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-22 23:58:00 +01:00

* renamed shortHelp -> decription

* refactored abbreviation and mapping commands (actually 200 LOC less now :)
This commit is contained in:
Martin Stubenschrott
2008-02-29 14:46:33 +00:00
parent 8184b1109f
commit 57debc00e0
13 changed files with 357 additions and 493 deletions

View File

@@ -140,6 +140,7 @@ vimperator.Buffer = function () //{{{
}
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// OPTIONS /////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
@@ -279,11 +280,11 @@ vimperator.Buffer = function () //{{{
vimperator.mappings.add(modes, ["gf"],
"View source",
function () { vimperator.commands.viewsource(); });
function () { vimperator.buffer.viewSource(null, false); });
vimperator.mappings.add(modes, ["gF"],
"View source with an external editor",
function () { vimperator.commands.viewsource(null, true); });
function () { vimperator.buffer.viewSource(null, true); });
vimperator.mappings.add(modes, ["gi"],
"Focus last used input field",
@@ -446,32 +447,7 @@ vimperator.Buffer = function () //{{{
vimperator.commands.add(["vie[wsource]"],
"View source code of current document",
function (args, special)
{
var url = args || vimperator.buffer.URL;
if (special) // external editor
{
// TODO: make that a helper function
// TODO: save return value in v:shell_error
var newThread = Components.classes["@mozilla.org/thread-manager;1"].getService().newThread(0);
var editor = vimperator.options["editor"];
var args = editor.split(" "); // FIXME: too simple
if (args.length < 1)
{
vimperator.open("view-source:" + url)
vimperator.echoerr("no editor specified");
return;
}
var prog = args.shift();
args.push(url)
vimperator.callFunctionInThread(newThread, vimperator.io.run, [prog, args, true]);
}
else
{
vimperator.open("view-source:" + url)
}
});
function (args, special) { vimperator.buffer.viewSource(args, special) });
vimperator.commands.add(["zo[om]"],
"Set zoom value of current web page",
@@ -1320,7 +1296,7 @@ vimperator.Buffer = function () //{{{
vimperator.beep();
},
viewSelectionSource: function()
viewSelectionSource: function ()
{
// copied (and tuned somebit) from browser.jar -> nsContextMenu.js
var focusedWindow = document.commandDispatcher.focusedWindow;
@@ -1338,6 +1314,33 @@ vimperator.Buffer = function () //{{{
window.openDialog("chrome://global/content/viewPartialSource.xul",
"_blank", "scrollbars,resizable,chrome,dialog=no",
docUrl, docCharset, reference, "selection");
},
// url is optional
viewSource: function (url, useExternalEditor)
{
var url = url || vimperator.buffer.URL;
if (useExternalEditor)
{
// TODO: make that a helper function
// TODO: save return value in v:shell_error
var newThread = Components.classes["@mozilla.org/thread-manager;1"].getService().newThread(0);
var editor = vimperator.options["editor"];
var args = editor.split(" "); // FIXME: too simple
if (args.length < 1)
{
vimperator.echoerr("no editor specified");
return;
}
var prog = args.shift();
args.push(url)
vimperator.callFunctionInThread(newThread, vimperator.io.run, [prog, args, true]);
}
else
{
vimperator.open("view-source:" + url)
}
}
};
//}}}

View File

@@ -26,11 +26,16 @@ 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 *****/
vimperator.Command = function (specs, action, extraInfo) //{{{
// Do NOT create instances of this class yourself, use the helper method
// vimperator.commands.add() instead
vimperator.Command = function (specs, description, action, extraInfo) //{{{
{
if (!specs || !action)
return null;
if (!extraInfo)
extraInfo = {};
// convert command name abbreviation specs of the form
// 'shortname[optional-tail]' to short and long versions Eg. 'abc[def]' ->
// 'abc', 'abcdef'
@@ -59,28 +64,19 @@ vimperator.Command = function (specs, action, extraInfo) //{{{
return { names: names, longNames: longNames, shortNames: shortNames };
};
this.specs = specs;
var expandedSpecs = parseSpecs(specs);
this.specs = specs;
this.shortNames = expandedSpecs.shortNames;
this.longNames = expandedSpecs.longNames;
this.longNames = expandedSpecs.longNames;
// return the primary command name (the long name of the first spec listed)
this.name = this.longNames[0];
// return all command name aliases
this.names = expandedSpecs.names;
this.action = action;
if (extraInfo)
{
this.help = extraInfo.help || null;
this.shortHelp = extraInfo.shortHelp || null;
this.completer = extraInfo.completer || null;
this.args = extraInfo.args || [];
this.isUserCommand = extraInfo.isUserCommand || false;
}
this.name = this.longNames[0];
this.names = expandedSpecs.names; // return all command name aliases
this.description = extraInfo.description || "";
this.action = action;
this.completer = extraInfo.completer || null;
this.args = extraInfo.args || [];
this.isUserCommand = extraInfo.isUserCommand || false;
};
vimperator.Command.prototype = {
@@ -475,15 +471,9 @@ vimperator.Commands = function () //{{{
return commandsIterator();
},
// FIXME
// TODO: should commands added this way replace existing commands?
add: function (names, description, action, extra)
{
var extra = extra || {};
if (!extra.shortHelp)
extra.shortHelp = description;
var command = new vimperator.Command(names, action, extra);
var command = new vimperator.Command(names, description, action, extra);
if (!command)
return false;
@@ -491,28 +481,26 @@ vimperator.Commands = function () //{{{
{
if (exCommands[i].name == command.name)
{
//if (!replace)
return false; // never replace for now
//else
// break;
// never replace for now
vimperator.log("Warning: :" + names[0] + " already exists, NOT replacing existing command.", 2);
return false;
}
}
// add an alias, so that commands can be accessed with
// vimperator.commands.zoom("130")
this[command.name] = function (args, special, count, modifiers)
{
command.execute(args, special, count, modifiers);
};
exCommands.push(command);
return true;
},
// TODO: will change it's interface/semantics later!
addUserCommand: function (command, replace)
addUserCommand: function (names, description, action, extra, replace)
{
var extra = extra || {};
extra.isUserCommand = true;
description = description || "User defined command";
var command = new vimperator.Command(names, description, action, extra);
if (!command)
return false;
for (var i = 0; i < exCommands.length; i++)
{
if (exCommands[i].name == command.name)
@@ -524,13 +512,6 @@ vimperator.Commands = function () //{{{
}
}
// add an alias, so that commands can be accessed with
// vimperator.commands.zoom("130")
this[command.name] = function (args, special, count, modifiers)
{
command.execute(args, special, count, modifiers);
};
exCommands.push(command);
return true;
},
@@ -591,24 +572,11 @@ vimperator.Commands = function () //{{{
};
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// DEFAULT COMMANDS ////////////////////////////////////////
////////////////////// COMMANDS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
// move to vim.js:
commandManager.addUserCommand(new vimperator.Command(["q[uit]"],
function () { vimperator.tabs.remove(getBrowser().mCurrentTab, 1, false, 1); },
{ shortHelp: "Quit current tab" }
));
// TODO: check for "tabs" feature
commandManager.addUserCommand(new vimperator.Command(["quita[ll]", "qa[ll]"],
function () { vimperator.quit(false); },
{ shortHelp: "Quit Vimperator", }
));
// TODO: move where? (commands.js would be fine, but timing issue)
commandManager.addUserCommand(new vimperator.Command(["com[mand]"],
commandManager.add(["com[mand]"],
"List and define commands",
function (args, special)
{
if (args)
@@ -624,8 +592,13 @@ vimperator.Commands = function () //{{{
if (rep)
{
if (!vimperator.commands.addUserCommand(new vimperator.Command([cmd], function (args, special, count, modifiers) { eval(rep) }, { isUserCommand: rep } ), special))
if (!vimperator.commands.addUserCommand([cmd],
"User defined command",
function (args, special, count, modifiers) { eval(rep) }),
special);
{
vimperator.echoerr("E174: Command already exists: add ! to replace it");
}
}
else
{
@@ -644,323 +617,16 @@ vimperator.Commands = function () //{{{
}
},
{
shortHelp: "Lists and defines commands" /*,
args: [[["-nargs"], OPTION_STRING, function (arg) { return /^(0|1|\*|\?|\+)$/.test(arg); }],
/*args: [[["-nargs"], OPTION_STRING, function (arg) { return /^(0|1|\*|\?|\+)$/.test(arg); }],
[["-bang"], OPTION_NOARG],
[["-bar"], OPTION_NOARG]] */
}
));
});
// TODO: part of vimperator.js or vim.js?
commandManager.addUserCommand(new vimperator.Command(["o[pen]", "e[dit]"],
function (args, special)
{
if (args)
{
vimperator.open(args);
}
else
{
if (special)
BrowserReloadSkipCache();
else
BrowserReload();
}
},
{
shortHelp: "Open one or more URLs in the current tab",
completer: function (filter) { return vimperator.completion.url(filter); }
}
));
// TODO: remove preview window, or change it at least
commandManager.add(["pc[lose]"],
"Close preview window on bottom of screen",
function () { vimperator.previewwindow.hide(); });
// move to editor.js: - TODO: unify
commandManager.addUserCommand(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);
},
{
shortHelp: "Abbreviate a key sequence"
}
));
commandManager.addUserCommand(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);
},
{
shortHelp: "Abbreviate a key sequence for Command-line mode"
}
));
commandManager.addUserCommand(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);
},
{ shortHelp: "Abbreviate a key sequence for Insert mode" }
));
commandManager.addUserCommand(new vimperator.Command(["una[bbreviate]"],
function (args) { vimperator.editor.removeAbbreviation("!", args); },
{ shortHelp: "Remove an abbreviation" }
));
commandManager.addUserCommand(new vimperator.Command(["cuna[bbrev]"],
function (args) { vimperator.editor.removeAbbreviation("c", args); },
{ shortHelp: "Remove an abbreviation for Command-line mode" }
));
commandManager.addUserCommand(new vimperator.Command(["iuna[bbrev]"],
function (args) { vimperator.editor.removeAbbreviation("i", args); },
{ shortHelp: "Remove an abbreviation for Insert mode" }
));
commandManager.addUserCommand(new vimperator.Command(["abc[lear]"],
function (args) { vimperator.editor.removeAllAbbreviations("!"); },
{ shortHelp: "Remove all abbreviations" }
));
commandManager.addUserCommand(new vimperator.Command(["cabc[lear]"],
function (args) { vimperator.editor.removeAllAbbreviations("c"); },
{ shortHelp: "Remove all abbreviations for Command-line mode" }
));
commandManager.addUserCommand(new vimperator.Command(["iabc[lear]"],
function (args) { vimperator.editor.removeAllAbbreviations("i"); },
{ shortHelp: "Remove all abbreviations for Insert mode" }
));
// TODO: add helper method: addMappingCommand
// 0 args -> list all maps
// 1 arg -> list the maps starting with args
// 2 args -> map arg1 to arg*
function map(args, mode, noremap)
{
if (!args)
{
vimperator.mappings.list(mode);
return;
}
// ?:\s+ <- don't remember; (...)? optional = rhs
var [, lhs, rhs] = args.match(/(\S+)(?:\s+(.+))?/);
var leaderRegexp = /<Leader>/i;
if (leaderRegexp.test(lhs))
lhs = lhs.replace(leaderRegexp, vimperator.events.getMapLeader());
if (!rhs) // list the mapping
{
vimperator.mappings.list(mode, lhs);
}
else
{
for (var index = 0; index < mode.length; index++)
{
vimperator.mappings.addUserMap(new vimperator.Map([mode[index]], [lhs],
function (count) { vimperator.events.feedkeys((count > 1 ? count : "") + rhs, noremap); },
{ flags: vimperator.Mappings.flags.COUNT, rhs: rhs, noremap: noremap}
));
}
}
}
commandManager.addUserCommand(new vimperator.Command(["map"],
function (args) { map(args, [vimperator.modes.NORMAL], false); },
{ shortHelp: "Map the key sequence {lhs} to {rhs}" }
));
commandManager.addUserCommand(new vimperator.Command(["cm[ap]"],
function (args) { map(args, [vimperator.modes.COMMAND_LINE], false); },
{ shortHelp: "Map the key sequence {lhs} to {rhs} (in command-line mode)" }
));
commandManager.addUserCommand(new vimperator.Command(["im[ap]"],
function (args) { map(args, [vimperator.modes.INSERT, vimperator.modes.TEXTAREA], false); },
{ shortHelp: "Map the key sequence {lhs} to {rhs} (in insert mode)" }
));
commandManager.addUserCommand(new vimperator.Command(["mapc[lear]"],
function (args)
{
if (args)
{
vimperator.echoerr("E474: Invalid argument");
return;
}
vimperator.mappings.removeAll(vimperator.modes.NORMAL);
},
{
shortHelp: "Remove all mappings"
}
));
commandManager.addUserCommand(new vimperator.Command(["cmapc[lear]"],
function (args)
{
if (args)
{
vimperator.echoerr("E474: Invalid argument");
return;
}
vimperator.mappings.removeAll(vimperator.modes.COMMAND_LINE);
},
{
shortHelp: "Remove all mappings (in command-line mode)"
}
));
commandManager.addUserCommand(new vimperator.Command(["imapc[lear]"],
function (args)
{
if (args)
{
vimperator.echoerr("E474: Invalid argument");
return;
}
vimperator.mappings.removeAll(vimperator.modes.INSERT);
vimperator.mappings.removeAll(vimperator.modes.TEXTAREA);
},
{
shortHelp: "Remove all mappings (in insert mode)"
}
));
// TODO: remove duplication in :map
commandManager.addUserCommand(new vimperator.Command(["no[remap]"],
function (args) { map(args, [vimperator.modes.NORMAL], true); },
{ shortHelp: "Map the key sequence {lhs} to {rhs}" }
));
// XXX: TODO: remove duplication in :cmap
commandManager.addUserCommand(new vimperator.Command(["cno[remap]"],
function (args) { map(args, [vimperator.modes.COMMAND_LINE], true); },
{ shortHelp: "Map the key sequence {lhs} to {rhs} (in command-line mode)" }
));
commandManager.addUserCommand(new vimperator.Command(["ino[remap]"],
function (args) { map(args, [vimperator.modes.INSERT, vimperator.modes.TEXTAREA], true); },
{ shortHelp: "Map the key sequence {lhs} to {rhs} (in insert mode)" }
));
commandManager.addUserCommand(new vimperator.Command(["unm[ap]"],
function (args)
{
if (!args)
{
vimperator.echoerr("E474: Invalid argument");
return;
}
var lhs = args;
if (vimperator.mappings.hasMap(vimperator.modes.NORMAL, lhs))
vimperator.mappings.remove(vimperator.modes.NORMAL, lhs);
else
vimperator.echoerr("E31: No such mapping");
},
{
shortHelp: "Remove the mapping of {lhs}"
}
));
commandManager.addUserCommand(new vimperator.Command(["cunm[ap]"],
function (args)
{
if (!args)
{
vimperator.echoerr("E474: Invalid argument");
return;
}
var lhs = args;
if (vimperator.mappings.hasMap(vimperator.modes.COMMAND_LINE, lhs))
vimperator.mappings.remove(vimperator.modes.COMMAND_LINE, lhs);
else
vimperator.echoerr("E31: No such mapping");
},
{
shortHelp: "Remove the mapping of {lhs} (in command-line mode)"
}
));
commandManager.addUserCommand(new vimperator.Command(["iunm[ap]"],
function (args)
{
if (!args)
{
vimperator.echoerr("E474: Invalid argument");
return;
}
var lhs = args;
var flag = false;
if (vimperator.mappings.hasMap(vimperator.modes.INSERT, lhs))
{
vimperator.mappings.remove(vimperator.modes.INSERT, lhs);
flag = true;
}
if (vimperator.mappings.hasMap(vimperator.modes.TEXTAREA, lhs))
{
vimperator.mappings.remove(vimperator.modes.TEXTAREA, lhs);
flag = true;
}
if (!flag)
vimperator.echoerr("E31: No such mapping");
},
{
shortHelp: "Remove the mapping of {lhs} (in insert mode)"
}
));
// TODO: remove/change preview window
commandManager.addUserCommand(new vimperator.Command(["pc[lose]"],
function () { vimperator.previewwindow.hide(); },
{ shortHelp: "Close preview window on bottom of screen" }
));
// TODO: check for v.has("windows")
commandManager.addUserCommand(new vimperator.Command(["winc[lose]", "wc[lose]"],
function (args) { window.close(); },
{ shortHelp: "Close window" }
));
commandManager.addUserCommand(new vimperator.Command(["wino[pen]", "wo[pen]", "wine[dit]"],
function (args)
{
if (args)
vimperator.open(args, vimperator.NEW_WINDOW);
else
vimperator.open("about:blank", vimperator.NEW_WINDOW);
},
{
shortHelp: "Open one or more URLs in a new window"
}
));
// TODO: check for v.has("session")?
commandManager.addUserCommand(new vimperator.Command(["wqa[ll]", "wq", "xa[ll]"],
function () { vimperator.quit(true); },
{ shortHelp: "Save the session and quit" }
));
//}}}
return commandManager;

View File

@@ -305,12 +305,12 @@ vimperator.Completion = function () //{{{
if (!filter)
{
for (var command in vimperator.commands)
completions.push([command.name, command.shortHelp]);
completions.push([command.name, command.description]);
return [0, completions];
}
for (var command in vimperator.commands)
completions.push([command.longNames, command.shortHelp]);
completions.push([command.longNames, command.description]);
return [0, buildLongestStartingSubstring(completions, filter)];
},
@@ -333,7 +333,7 @@ vimperator.Completion = function () //{{{
{
if (prefix && option.type != "boolean")
continue;
options.push([option.names, option.shortHelp]);
options.push([option.names, option.description]);
}
return options;
}
@@ -381,7 +381,7 @@ vimperator.Completion = function () //{{{
{
if (prefix && option.type != "boolean")
continue;
options.push([prefix + option.name, option.shortHelp]);
options.push([prefix + option.name, option.description]);
}
return [0, options];
}
@@ -421,7 +421,7 @@ vimperator.Completion = function () //{{{
return option.names[j].indexOf($_) == 0;
});
}
optionCompletions.push([prefix + option.names[j], option.shortHelp]);
optionCompletions.push([prefix + option.names[j], option.description]);
break;
}
}

View File

@@ -148,6 +148,39 @@ vimperator.Editor = function () //{{{
{ flags: vimperator.Mappings.flags.MOTION | vimperator.Mappings.flags.COUNT });
}
// mode = "i" -> add :iabbrev, :iabclear and :iunabbrev commands
function addAbbreviationCommands(char, modeDescription)
{
var modeDescription = modeDescription ? " in " + modeDescription + " mode" : "";
var mode = char || "!";
vimperator.commands.add([char ? char + "a[bbrev]" : "ab[breviate]"],
"Abbreviate a key sequence" + modeDescription,
function (args)
{
if (!args)
{
vimperator.editor.listAbbreviations(mode, "");
return;
}
var matches = args.match(/^([^\s]+)(?:\s+(.+))?$/);
var [lhs, rhs] = [matches[1], matches[2]];
if (rhs)
vimperator.editor.addAbbreviation(mode, lhs, rhs);
else
vimperator.editor.listAbbreviations(mode, lhs);
});
vimperator.commands.add([char ? char + "una[bbrev]" : "una[bbreviate]"],
"Remove an abbreviation" + modeDescription,
function (args) { vimperator.editor.removeAbbreviation(mode, args); });
vimperator.commands.add([char + "abc[lear]"],
"Remove all abbreviations" + modeDescription,
function (args) { vimperator.editor.removeAllAbbreviations(mode); });
}
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// OPTIONS /////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
@@ -163,6 +196,7 @@ vimperator.Editor = function () //{{{
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// MAPPINGS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
var modes = [vimperator.modes.INSERT, vimperator.modes.COMMAND_LINE];
/* KEYS COUNT CARET TEXTAREA VISUAL_TEXTAREA */
@@ -400,6 +434,14 @@ vimperator.Editor = function () //{{{
},
{ flags: vimperator.Mappings.flags.ARGUMENT | vimperator.Mappings.flags.COUNT});
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// COMMANDS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
addAbbreviationCommands("", "");
addAbbreviationCommands("i", "insert");
addAbbreviationCommands("c", "command line");
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{

View File

@@ -350,8 +350,8 @@ vimperator.Hints = function () //{{{
case "O": vimperator.commandline.open(":", "open " + loc, vimperator.modes.EX); break;
case "t": vimperator.buffer.followLink(elem, vimperator.NEW_TAB); break;
case "T": vimperator.commandline.open(":", "tabopen " + loc, vimperator.modes.EX); break;
case "v": vimperator.commands.viewsource(loc); break;
case "V": vimperator.commands.viewsource(loc, true); break;
case "v": vimperator.buffer.viewSource(loc, false); break;
case "V": vimperator.buffer.viewSource(loc, true); break;
case "w": vimperator.buffer.followLink(elem, vimperator.NEW_WINDOW); break;
case "W": vimperator.commandline.open(":", "winopen " + loc, vimperator.modes.EX); break;
case "y": setTimeout(function(){vimperator.copyToClipboard(loc, true)}, timeout + 50); break;

View File

@@ -46,6 +46,7 @@ vimperator.Mail = function ()
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// MAPPINGS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
var modes = vimperator.config.mailModes || [vimperator.modes.NORMAL];
vimperator.mappings.add(modes, ["<Return>", "i"],

View File

@@ -26,24 +26,25 @@ 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 *****/
vimperator.Map = function (modes, cmds, action, extraInfo) //{{{
// Do NOT create instances of this class yourself, use the helper method
// vimperator.mappings.add() instead
vimperator.Map = function (modes, cmds, description, action, extraInfo) //{{{
{
if (!modes || (!cmds || !cmds.length) || !action)
return null;
if (!extraInfo)
extraInfo = {};
this.modes = modes;
this.names = cmds;
// only store keysyms with uppercase modifier strings
this.names = cmds.map(function (cmd) { return cmd.replace(/[casm]-/g, function (name) { return name.toUpperCase(); });});
this.action = action;
if (extraInfo)
{
this.flags = extraInfo.flags || 0;
this.shortHelp = extraInfo.shortHelp || "";
this.rhs = extraInfo.rhs || null;
this.noremap = extraInfo.noremap || false;
}
this.flags = extraInfo.flags || 0;
this.description = extraInfo.description || "";
this.rhs = extraInfo.rhs || null;
this.noremap = extraInfo.noremap || false;
};
vimperator.Map.prototype = {
@@ -85,11 +86,6 @@ vimperator.Mappings = function () //{{{
user[mode] = [];
}
function addDefaultMap(map)
{
map.modes.forEach(function (mode) { main[mode].push(map); });
}
function addMap(map, userMap)
{
var where = userMap ? user : main;
@@ -161,6 +157,104 @@ vimperator.Mappings = function () //{{{
throw StopIteration;
}
function addMapCommands(char, modes, modeDescription)
{
// 0 args -> list all maps
// 1 arg -> list the maps starting with args
// 2 args -> map arg1 to arg*
function map(args, mode, noremap)
{
if (!args)
{
vimperator.mappings.list(mode);
return;
}
// ?:\s+ <- don't remember; (...)? optional = rhs
var [, lhs, rhs] = args.match(/(\S+)(?:\s+(.+))?/);
var leaderRegexp = /<Leader>/i;
if (leaderRegexp.test(lhs))
lhs = lhs.replace(leaderRegexp, vimperator.events.getMapLeader());
if (!rhs) // list the mapping
{
vimperator.mappings.list(mode, lhs);
}
else
{
for (var index = 0; index < mode.length; index++)
{
vimperator.mappings.addUserMap([mode[index]], [lhs],
"User defined mapping",
function (count) { vimperator.events.feedkeys((count > 1 ? count : "") + rhs, noremap); },
{
flags: vimperator.Mappings.flags.COUNT,
rhs: rhs,
noremap: noremap
});
}
}
}
var modeDescription = modeDescription ? " in " + modeDescription + " mode" : "";
vimperator.commands.add([char ? char + "m[ap]" : "map"],
"Map a key sequence" + modeDescription,
function (args) { map(args, modes, false); });
vimperator.commands.add([char + "no[remap]"],
"Map a key sequence without remapping keys" + modeDescription,
function (args) { map(args, modes, true); });
vimperator.commands.add([char + "mapc[lear]"],
"Remove all mappings" + modeDescription,
function (args)
{
if (args)
{
vimperator.echoerr("E474: Invalid argument");
return;
}
for (let i = 0; i < modes.length; i++)
vimperator.mappings.removeAll(modes[i]);
});
vimperator.commands.add([char + "unm[ap]"],
"Remove a mapping" + modeDescription,
function (args)
{
if (!args)
{
vimperator.echoerr("E474: Invalid argument");
return;
}
var flag = false;
for (let i = 0; i < modes.length; i++)
{
if (vimperator.mappings.hasMap(modes[i], args))
{
vimperator.mappings.remove(modes[i], args);
flag = true;
}
}
if (!flag)
vimperator.echoerr("E31: No such mapping");
});
}
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// COMMANDS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
addMapCommands("", [vimperator.modes.NORMAL], "");
addMapCommands("c", [vimperator.modes.COMMAND_LINE], "command line");
addMapCommands("i", [vimperator.modes.INSERT, vimperator.modes.TEXTAREA], "insert");
if (vimperator.has("mail"))
addMapCommands("m", [vimperator.modes.MESSAGE], "message");
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
@@ -189,25 +283,21 @@ vimperator.Mappings = function () //{{{
add: function (modes, keys, description, action, extra)
{
addMap (new vimperator.Map(modes, keys,
action, { shortHelp: description, flags: (extra && extra.flags) ? extra.flags : 0 }), false);
addMap (new vimperator.Map(modes, keys, description, action, extra), false);
},
// TODO: change map to "easier" arguments
addUserMap: function (map)
addUserMap: function (modes, keys, description, action, extra)
{
// a map can have multiple names
var map = new vimperator.Map(modes, keys, description || "User defined mapping", action, extra);
// remove all old mappings to this key sequence
for (var i = 0; i < map.names.length; i++)
{
// only store keysyms with uppercase modifier strings
map.names[i] = map.names[i].replace(/[casm]-/g, function (name) { return name.toUpperCase(); });
for (var j = 0; j < map.modes.length; j++)
removeMap(map.modes[j], map.names[i]);
}
// all maps got removed (matching names = lhs), and added newly here
for (var k = 0; k < map.modes.length; k++)
user[map.modes[k]].push(map);
addMap (map, true);
},
get: function (mode, cmd)

View File

@@ -33,10 +33,12 @@ vimperator.config = {
/*** optional options, there are checked for existance and a fallback provided ***/
features: ["hints", "mail", "marks"],
guioptions: { m: ["mail-toolbar-menubar2"], T: ["mail-bar2"], f: ["folderPaneBox", "folderpane_splitter"], F: ["folderPaneHeader"] },
get browserModes() { return [vimperator.modes.MESSAGE]; },
get mainWidget() { return GetThreadTree(); }, // focusContent() focuses this widget
mainWindowID: "messengerWindow", // used for :set titlestring
guioptions: { m: ["mail-toolbar-menubar2"], T: ["mail-bar2"], f: ["folderPaneBox", "folderpane_splitter"], F: ["folderPaneHeader"] },
dialogs: [
/*["about", "About Firefox",
function() { openDialog("chrome://browser/content/aboutDialog.xul", "_blank", "chrome,dialog,modal,centerscreen"); }],
@@ -83,9 +85,8 @@ vimperator.config = {
init: function()
{
vimperator.mappings.add([vimperator.modes.NORMAL],
["o"], "Open one or more URLs",
["o"], "Open a message",
function () { vimperator.commandline.open(":", "open ", vimperator.modes.EX); });
}
}

View File

@@ -38,7 +38,7 @@ vimperator.Option = function (names, description, type, defaultValue, getter, se
this.name = names[0];
this.names = names;
this.type = type;
this.shortHelp = description || "";
this.description = description || "";
// "", 0 are valid default values
this.defaultValue = (defaultValue === undefined) ? null : defaultValue;

View File

@@ -182,7 +182,7 @@ vimperator.Tabs = function () //{{{
vimperator.mappings.add([vimperator.modes.NORMAL], ["u"],
"Undo closing of a tab",
function (count) { vimperator.commands.undo("", false, count); },
function (count) { vimperator.commands.get("undo").execute("", false, count); },
{ flags: vimperator.Mappings.flags.COUNT });
vimperator.mappings.add([vimperator.modes.NORMAL], ["<C-^>", "<C-6>"],
@@ -238,6 +238,10 @@ vimperator.Tabs = function () //{{{
vimperator.buffer.list(special);
});
vimperator.commands.add(["quita[ll]", "qa[ll]"],
"Quit " + vimperator.config.appName,
function () { vimperator.quit(false); });
vimperator.commands.add(["reloada[ll]"],
"Reload all tab pages",
function (args, special) { vimperator.tabs.reloadAll(special); });
@@ -394,6 +398,12 @@ vimperator.Tabs = function () //{{{
undoCloseTab(); // doesn't work with i as the index to undoCloseTab
});
if (vimperator.has("session"))
{
vimperator.commands.add(["wqa[ll]", "wq", "xa[ll]"],
"Save the session and quit",
function () { vimperator.quit(true); });
}
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION //////////////////////////////////////////

View File

@@ -134,7 +134,7 @@ vimperator.util = { //{{{
var ret = "";
var longHelp = false;
if ((command.help && command.shortHelp) && (command.help.length + command.shortHelp.length) > 50)
if ((command.help && command.description) && (command.help.length + command.description.length) > 50)
longHelp = true;
// the tags which are printed on the top right
@@ -162,7 +162,7 @@ vimperator.util = { //{{{
// the actual help text
if (command.shortHelp)
{
ret += command.shortHelp + "."; // the help description
ret += command.description + "."; // the help description
if (extraHelp)
ret += " +\n" + extraHelp;
}

View File

@@ -103,7 +103,7 @@ const vimperator = (function () //{{{
{
vimperator.mappings.add(vimperator.modes.all, ["<F1>"],
"Open help window",
function () { vimperator.commands.help(); });
function () { vimperator.help(); });
vimperator.mappings.add([vimperator.modes.NORMAL], ["ZQ"],
"Quit and don't save the session",
@@ -160,7 +160,7 @@ const vimperator = (function () //{{{
{
usage += "<tr><td style='color: magenta; padding-right: 20px'> :" +
vimperator.util.escapeHTML(command.name) + "</td><td>" +
vimperator.util.escapeHTML(command.shortHelp) + "</td></tr>";
vimperator.util.escapeHTML(command.description) + "</td></tr>";
}
usage += "</table>";
@@ -169,46 +169,7 @@ const vimperator = (function () //{{{
vimperator.commands.add(["h[elp]"],
"Display help",
function (args, special, count, modifiers)
{
function jumpToTag(file, tag)
{
vimperator.open("chrome://" + vimperator.config.name.toLowerCase() + "/locale/" + file);
setTimeout(function() {
var elem = vimperator.buffer.getElement('@class="tag" and text()="' + tag + '"');
if (elem)
window.content.scrollTo(0, elem.getBoundingClientRect().top - 10); // 10px context
else
dump('no element: ' + '@class="tag" and text()="' + tag + '"\n' );
}, 200);
}
if (!args)
{
vimperator.open("chrome://" + vimperator.config.name.toLowerCase() + "/locale/intro.html");
return;
}
var [, items] = vimperator.completion.help(args);
var partialMatch = -1;
for (var i = 0; i < items.length; i++)
{
if (items[i][0] == args)
{
jumpToTag(items[i][1], items[i][0]);
return;
}
else if (partialMatch == -1 && items[i][0].indexOf(args) > -1)
{
partialMatch = i;
}
}
if (partialMatch > -1)
jumpToTag(items[partialMatch][1], items[partialMatch][0]);
else
vimperator.echoerr("E149: Sorry, no help for " + args);
},
function (args) { vimperator.help(args); },
{
completer: function (filter) { return vimperator.completion.help(filter); }
});
@@ -268,6 +229,16 @@ const vimperator = (function () //{{{
vimperator.events.feedkeys(args, special);
});
vimperator.commands.add(["q[uit]"],
vimperator.has("tabs") ? "Quit current tab" : "Quit application",
function ()
{
if (vimperator.has("tabs"))
vimperator.tabs.remove(getBrowser().mCurrentTab, 1, false, 1);
else
vimperator.quit(false);
});
vimperator.commands.add(["res[tart]"],
"Force " + vimperator.config.appName + " to restart",
function () { vimperator.restart(); });
@@ -364,7 +335,7 @@ const vimperator = (function () //{{{
vimperator.open("about:");
else
vimperator.echo(":" + vimperator.util.escapeHTML(vimperator.commandline.getCommand()) + "\n" +
vimperator.config.appName + " " + vimperator.version +
vimperator.config.hostApplication + " " + vimperator.version +
" running on:\n" + navigator.userAgent);
});
@@ -377,7 +348,7 @@ const vimperator = (function () //{{{
{
usage += "<tr><td style='color: magenta; padding-right: 20px'> " +
vimperator.util.escapeHTML(mapping.names[0]) + "</td><td>" +
vimperator.util.escapeHTML(mapping.shortHelp || "") + "</td></tr>";
vimperator.util.escapeHTML(mapping.description) + "</td></tr>";
}
usage += "</table>";
@@ -616,6 +587,47 @@ const vimperator = (function () //{{{
return features.some (function(feat) { return feat == feature; });
},
help: function(topic)
{
function jumpToTag(file, tag)
{
vimperator.open("chrome://" + vimperator.config.name.toLowerCase() + "/locale/" + file);
setTimeout(function() {
var elem = vimperator.buffer.getElement('@class="tag" and text()="' + tag + '"');
if (elem)
window.content.scrollTo(0, elem.getBoundingClientRect().top - 10); // 10px context
else
dump('no element: ' + '@class="tag" and text()="' + tag + '"\n' );
}, 200);
}
if (!topic)
{
vimperator.open("chrome://" + vimperator.config.name.toLowerCase() + "/locale/intro.html");
return;
}
var [, items] = vimperator.completion.help(topic);
var partialMatch = -1;
for (var i = 0; i < items.length; i++)
{
if (items[i][0] == topic)
{
jumpToTag(items[i][1], items[i][0]);
return;
}
else if (partialMatch == -1 && items[i][0].indexOf(topic) > -1)
{
partialMatch = i;
}
}
if (partialMatch > -1)
jumpToTag(items[partialMatch][1], items[partialMatch][0]);
else
vimperator.echoerr("E149: Sorry, no help for " + topic);
},
// logs a message to the javascript error console
// if msg is an object, it is beautified
log: function (msg, level)
@@ -807,7 +819,7 @@ const vimperator = (function () //{{{
if (vimperator.options.getPref("extensions." + vimperator.config.name.toLowerCase() + ".firsttime", true))
{
setTimeout(function () {
vimperator.commands.help();
vimperator.help();
vimperator.options.setPref("extensions." + vimperator.config.name.toLowerCase() + ".firsttime", false);
}, 1000);
}

View File

@@ -32,8 +32,9 @@ vimperator.config = {
hostApplication: "Firefox",
/*** optional options, there are checked for existance and a fallback provided ***/
features: ["bookmarks", "history", "marks", "quickmarks", "hints", "tabs", "windows"],
features: ["bookmarks", "hints", "history", "marks", "quickmarks", "session", "tabs", "windows"],
guioptions: { m: ["toolbar-menubar"], T: ["nav-bar"], b: ["PersonalToolbar"] },
dialogs: [
["about", "About Firefox",
function() { openDialog("chrome://browser/content/aboutDialog.xul", "_blank", "chrome,dialog,modal,centerscreen"); }],
@@ -229,6 +230,26 @@ vimperator.config = {
"Show progress of current downloads",
function () { vimperator.open("chrome://mozapps/content/downloads/downloads.xul", vimperator.NEW_TAB); });
vimperator.commands.add(["o[pen]", "e[dit]"],
"Open one or more URLs in the current tab",
function (args, special)
{
if (args)
{
vimperator.open(args);
}
else
{
if (special)
BrowserReloadSkipCache();
else
BrowserReload();
}
},
{
completer: function (filter) { return vimperator.completion.url(filter); }
});
vimperator.commands.add(["redr[aw]"],
"Redraw the screen",
function ()
@@ -281,8 +302,26 @@ vimperator.config = {
}
}
},
{ completer: function (filter) { return vimperator.completion.sidebar(filter); } });
{
completer: function (filter) { return vimperator.completion.sidebar(filter); }
});
vimperator.commands.add(["winc[lose]", "wc[lose]"],
"Close window",
function (args) { window.close(); });
vimperator.commands.add(["wino[pen]", "wo[pen]", "wine[dit]"],
"Open one or more URLs in a new window",
function (args)
{
if (args)
vimperator.open(args, vimperator.NEW_WINDOW);
else
vimperator.open("about:blank", vimperator.NEW_WINDOW);
},
{
completer: function (filter) { return vimperator.completion.url(filter); }
});
}
}