1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-23 06:17:58 +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 ///////////////////////////////////////////////// ////////////////////// OPTIONS /////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -279,11 +280,11 @@ vimperator.Buffer = function () //{{{
vimperator.mappings.add(modes, ["gf"], vimperator.mappings.add(modes, ["gf"],
"View source", "View source",
function () { vimperator.commands.viewsource(); }); function () { vimperator.buffer.viewSource(null, false); });
vimperator.mappings.add(modes, ["gF"], vimperator.mappings.add(modes, ["gF"],
"View source with an external editor", "View source with an external editor",
function () { vimperator.commands.viewsource(null, true); }); function () { vimperator.buffer.viewSource(null, true); });
vimperator.mappings.add(modes, ["gi"], vimperator.mappings.add(modes, ["gi"],
"Focus last used input field", "Focus last used input field",
@@ -446,32 +447,7 @@ vimperator.Buffer = function () //{{{
vimperator.commands.add(["vie[wsource]"], vimperator.commands.add(["vie[wsource]"],
"View source code of current document", "View source code of current document",
function (args, special) function (args, special) { vimperator.buffer.viewSource(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)
}
});
vimperator.commands.add(["zo[om]"], vimperator.commands.add(["zo[om]"],
"Set zoom value of current web page", "Set zoom value of current web page",
@@ -1338,6 +1314,33 @@ vimperator.Buffer = function () //{{{
window.openDialog("chrome://global/content/viewPartialSource.xul", window.openDialog("chrome://global/content/viewPartialSource.xul",
"_blank", "scrollbars,resizable,chrome,dialog=no", "_blank", "scrollbars,resizable,chrome,dialog=no",
docUrl, docCharset, reference, "selection"); 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. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** 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) if (!specs || !action)
return null; return null;
if (!extraInfo)
extraInfo = {};
// convert command name abbreviation specs of the form // convert command name abbreviation specs of the form
// 'shortname[optional-tail]' to short and long versions Eg. 'abc[def]' -> // 'shortname[optional-tail]' to short and long versions Eg. 'abc[def]' ->
// 'abc', 'abcdef' // 'abc', 'abcdef'
@@ -59,28 +64,19 @@ vimperator.Command = function (specs, action, extraInfo) //{{{
return { names: names, longNames: longNames, shortNames: shortNames }; return { names: names, longNames: longNames, shortNames: shortNames };
}; };
this.specs = specs;
var expandedSpecs = parseSpecs(specs); var expandedSpecs = parseSpecs(specs);
this.specs = specs;
this.shortNames = expandedSpecs.shortNames; 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) // return the primary command name (the long name of the first spec listed)
this.name = this.longNames[0]; this.name = this.longNames[0];
this.names = expandedSpecs.names; // return all command name aliases
// return all command name aliases this.description = extraInfo.description || "";
this.names = expandedSpecs.names;
this.action = action; this.action = action;
if (extraInfo)
{
this.help = extraInfo.help || null;
this.shortHelp = extraInfo.shortHelp || null;
this.completer = extraInfo.completer || null; this.completer = extraInfo.completer || null;
this.args = extraInfo.args || []; this.args = extraInfo.args || [];
this.isUserCommand = extraInfo.isUserCommand || false; this.isUserCommand = extraInfo.isUserCommand || false;
}
}; };
vimperator.Command.prototype = { vimperator.Command.prototype = {
@@ -475,15 +471,9 @@ vimperator.Commands = function () //{{{
return commandsIterator(); return commandsIterator();
}, },
// FIXME
// TODO: should commands added this way replace existing commands?
add: function (names, description, action, extra) add: function (names, description, action, extra)
{ {
var extra = extra || {}; var command = new vimperator.Command(names, description, action, extra);
if (!extra.shortHelp)
extra.shortHelp = description;
var command = new vimperator.Command(names, action, extra);
if (!command) if (!command)
return false; return false;
@@ -491,28 +481,26 @@ vimperator.Commands = function () //{{{
{ {
if (exCommands[i].name == command.name) if (exCommands[i].name == command.name)
{ {
//if (!replace) // never replace for now
return false; // never replace for now vimperator.log("Warning: :" + names[0] + " already exists, NOT replacing existing command.", 2);
//else return false;
// break;
} }
} }
// 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); exCommands.push(command);
return true; return true;
}, },
// TODO: will change it's interface/semantics later! addUserCommand: function (names, description, action, extra, replace)
addUserCommand: function (command, 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++) for (var i = 0; i < exCommands.length; i++)
{ {
if (exCommands[i].name == command.name) 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); exCommands.push(command);
return true; return true;
}, },
@@ -591,24 +572,11 @@ vimperator.Commands = function () //{{{
}; };
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// DEFAULT COMMANDS //////////////////////////////////////// ////////////////////// COMMANDS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
// move to vim.js: commandManager.add(["com[mand]"],
"List and define commands",
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]"],
function (args, special) function (args, special)
{ {
if (args) if (args)
@@ -624,9 +592,14 @@ vimperator.Commands = function () //{{{
if (rep) 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"); vimperator.echoerr("E174: Command already exists: add ! to replace it");
} }
}
else else
{ {
var cmdlist = getUserCommands(cmd); var cmdlist = getUserCommands(cmd);
@@ -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], [["-bang"], OPTION_NOARG],
[["-bar"], OPTION_NOARG]] */ [["-bar"], OPTION_NOARG]] */
} });
));
// TODO: part of vimperator.js or vim.js? // TODO: remove preview window, or change it at least
commandManager.addUserCommand(new vimperator.Command(["o[pen]", "e[dit]"], commandManager.add(["pc[lose]"],
function (args, special) "Close preview window on bottom of screen",
{ function () { vimperator.previewwindow.hide(); });
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); }
}
));
// 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; return commandManager;

View File

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

View File

@@ -148,6 +148,39 @@ vimperator.Editor = function () //{{{
{ flags: vimperator.Mappings.flags.MOTION | vimperator.Mappings.flags.COUNT }); { 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 ///////////////////////////////////////////////// ////////////////////// OPTIONS /////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -163,6 +196,7 @@ vimperator.Editor = function () //{{{
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// MAPPINGS //////////////////////////////////////////////// ////////////////////// MAPPINGS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
var modes = [vimperator.modes.INSERT, vimperator.modes.COMMAND_LINE]; var modes = [vimperator.modes.INSERT, vimperator.modes.COMMAND_LINE];
/* KEYS COUNT CARET TEXTAREA VISUAL_TEXTAREA */ /* KEYS COUNT CARET TEXTAREA VISUAL_TEXTAREA */
@@ -400,6 +434,14 @@ vimperator.Editor = function () //{{{
}, },
{ flags: vimperator.Mappings.flags.ARGUMENT | vimperator.Mappings.flags.COUNT}); { flags: vimperator.Mappings.flags.ARGUMENT | vimperator.Mappings.flags.COUNT});
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// COMMANDS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
addAbbreviationCommands("", "");
addAbbreviationCommands("i", "insert");
addAbbreviationCommands("c", "command line");
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{

View File

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

View File

@@ -46,6 +46,7 @@ vimperator.Mail = function ()
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// MAPPINGS //////////////////////////////////////////////// ////////////////////// MAPPINGS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
var modes = vimperator.config.mailModes || [vimperator.modes.NORMAL]; var modes = vimperator.config.mailModes || [vimperator.modes.NORMAL];
vimperator.mappings.add(modes, ["<Return>", "i"], 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. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** 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) if (!modes || (!cmds || !cmds.length) || !action)
return null; return null;
if (!extraInfo)
extraInfo = {};
this.modes = modes; 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; this.action = action;
if (extraInfo)
{
this.flags = extraInfo.flags || 0; this.flags = extraInfo.flags || 0;
this.description = extraInfo.description || "";
this.shortHelp = extraInfo.shortHelp || "";
this.rhs = extraInfo.rhs || null; this.rhs = extraInfo.rhs || null;
this.noremap = extraInfo.noremap || false; this.noremap = extraInfo.noremap || false;
}
}; };
vimperator.Map.prototype = { vimperator.Map.prototype = {
@@ -85,11 +86,6 @@ vimperator.Mappings = function () //{{{
user[mode] = []; user[mode] = [];
} }
function addDefaultMap(map)
{
map.modes.forEach(function (mode) { main[mode].push(map); });
}
function addMap(map, userMap) function addMap(map, userMap)
{ {
var where = userMap ? user : main; var where = userMap ? user : main;
@@ -161,6 +157,104 @@ vimperator.Mappings = function () //{{{
throw StopIteration; 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 ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -189,25 +283,21 @@ vimperator.Mappings = function () //{{{
add: function (modes, keys, description, action, extra) add: function (modes, keys, description, action, extra)
{ {
addMap (new vimperator.Map(modes, keys, addMap (new vimperator.Map(modes, keys, description, action, extra), false);
action, { shortHelp: description, flags: (extra && extra.flags) ? extra.flags : 0 }), false);
}, },
// TODO: change map to "easier" arguments addUserMap: function (modes, keys, description, action, extra)
addUserMap: function (map)
{ {
// 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++) 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++) for (var j = 0; j < map.modes.length; j++)
removeMap(map.modes[j], map.names[i]); removeMap(map.modes[j], map.names[i]);
} }
// all maps got removed (matching names = lhs), and added newly here addMap (map, true);
for (var k = 0; k < map.modes.length; k++)
user[map.modes[k]].push(map);
}, },
get: function (mode, cmd) get: function (mode, cmd)

View File

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

View File

@@ -182,7 +182,7 @@ vimperator.Tabs = function () //{{{
vimperator.mappings.add([vimperator.modes.NORMAL], ["u"], vimperator.mappings.add([vimperator.modes.NORMAL], ["u"],
"Undo closing of a tab", "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 }); { flags: vimperator.Mappings.flags.COUNT });
vimperator.mappings.add([vimperator.modes.NORMAL], ["<C-^>", "<C-6>"], vimperator.mappings.add([vimperator.modes.NORMAL], ["<C-^>", "<C-6>"],
@@ -238,6 +238,10 @@ vimperator.Tabs = function () //{{{
vimperator.buffer.list(special); vimperator.buffer.list(special);
}); });
vimperator.commands.add(["quita[ll]", "qa[ll]"],
"Quit " + vimperator.config.appName,
function () { vimperator.quit(false); });
vimperator.commands.add(["reloada[ll]"], vimperator.commands.add(["reloada[ll]"],
"Reload all tab pages", "Reload all tab pages",
function (args, special) { vimperator.tabs.reloadAll(special); }); 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 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 ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////

View File

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

View File

@@ -103,7 +103,7 @@ const vimperator = (function () //{{{
{ {
vimperator.mappings.add(vimperator.modes.all, ["<F1>"], vimperator.mappings.add(vimperator.modes.all, ["<F1>"],
"Open help window", "Open help window",
function () { vimperator.commands.help(); }); function () { vimperator.help(); });
vimperator.mappings.add([vimperator.modes.NORMAL], ["ZQ"], vimperator.mappings.add([vimperator.modes.NORMAL], ["ZQ"],
"Quit and don't save the session", "Quit and don't save the session",
@@ -160,7 +160,7 @@ const vimperator = (function () //{{{
{ {
usage += "<tr><td style='color: magenta; padding-right: 20px'> :" + usage += "<tr><td style='color: magenta; padding-right: 20px'> :" +
vimperator.util.escapeHTML(command.name) + "</td><td>" + vimperator.util.escapeHTML(command.name) + "</td><td>" +
vimperator.util.escapeHTML(command.shortHelp) + "</td></tr>"; vimperator.util.escapeHTML(command.description) + "</td></tr>";
} }
usage += "</table>"; usage += "</table>";
@@ -169,46 +169,7 @@ const vimperator = (function () //{{{
vimperator.commands.add(["h[elp]"], vimperator.commands.add(["h[elp]"],
"Display help", "Display help",
function (args, special, count, modifiers) function (args) { vimperator.help(args); },
{
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);
},
{ {
completer: function (filter) { return vimperator.completion.help(filter); } completer: function (filter) { return vimperator.completion.help(filter); }
}); });
@@ -268,6 +229,16 @@ const vimperator = (function () //{{{
vimperator.events.feedkeys(args, special); 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]"], vimperator.commands.add(["res[tart]"],
"Force " + vimperator.config.appName + " to restart", "Force " + vimperator.config.appName + " to restart",
function () { vimperator.restart(); }); function () { vimperator.restart(); });
@@ -364,7 +335,7 @@ const vimperator = (function () //{{{
vimperator.open("about:"); vimperator.open("about:");
else else
vimperator.echo(":" + vimperator.util.escapeHTML(vimperator.commandline.getCommand()) + "\n" + vimperator.echo(":" + vimperator.util.escapeHTML(vimperator.commandline.getCommand()) + "\n" +
vimperator.config.appName + " " + vimperator.version + vimperator.config.hostApplication + " " + vimperator.version +
" running on:\n" + navigator.userAgent); " running on:\n" + navigator.userAgent);
}); });
@@ -377,7 +348,7 @@ const vimperator = (function () //{{{
{ {
usage += "<tr><td style='color: magenta; padding-right: 20px'> " + usage += "<tr><td style='color: magenta; padding-right: 20px'> " +
vimperator.util.escapeHTML(mapping.names[0]) + "</td><td>" + vimperator.util.escapeHTML(mapping.names[0]) + "</td><td>" +
vimperator.util.escapeHTML(mapping.shortHelp || "") + "</td></tr>"; vimperator.util.escapeHTML(mapping.description) + "</td></tr>";
} }
usage += "</table>"; usage += "</table>";
@@ -616,6 +587,47 @@ const vimperator = (function () //{{{
return features.some (function(feat) { return feat == feature; }); 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 // logs a message to the javascript error console
// if msg is an object, it is beautified // if msg is an object, it is beautified
log: function (msg, level) log: function (msg, level)
@@ -807,7 +819,7 @@ const vimperator = (function () //{{{
if (vimperator.options.getPref("extensions." + vimperator.config.name.toLowerCase() + ".firsttime", true)) if (vimperator.options.getPref("extensions." + vimperator.config.name.toLowerCase() + ".firsttime", true))
{ {
setTimeout(function () { setTimeout(function () {
vimperator.commands.help(); vimperator.help();
vimperator.options.setPref("extensions." + vimperator.config.name.toLowerCase() + ".firsttime", false); vimperator.options.setPref("extensions." + vimperator.config.name.toLowerCase() + ".firsttime", false);
}, 1000); }, 1000);
} }

View File

@@ -32,8 +32,9 @@ vimperator.config = {
hostApplication: "Firefox", hostApplication: "Firefox",
/*** optional options, there are checked for existance and a fallback provided ***/ /*** 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"] }, guioptions: { m: ["toolbar-menubar"], T: ["nav-bar"], b: ["PersonalToolbar"] },
dialogs: [ dialogs: [
["about", "About Firefox", ["about", "About Firefox",
function() { openDialog("chrome://browser/content/aboutDialog.xul", "_blank", "chrome,dialog,modal,centerscreen"); }], function() { openDialog("chrome://browser/content/aboutDialog.xul", "_blank", "chrome,dialog,modal,centerscreen"); }],
@@ -229,6 +230,26 @@ vimperator.config = {
"Show progress of current downloads", "Show progress of current downloads",
function () { vimperator.open("chrome://mozapps/content/downloads/downloads.xul", vimperator.NEW_TAB); }); 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]"], vimperator.commands.add(["redr[aw]"],
"Redraw the screen", "Redraw the screen",
function () 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); }
});
} }
} }