mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-22 06:08:02 +01:00
Also groupify commands. Usage examples are in official plugins.
--HG-- branch : groups
This commit is contained in:
@@ -76,7 +76,7 @@ var AutoCommands = Module("autocommands", {
|
|||||||
this.user = contexts.hives.autocmd.user;
|
this.user = contexts.hives.autocmd.user;
|
||||||
},
|
},
|
||||||
|
|
||||||
hives: Group.Hive("autocmd", AutoCmdHive),
|
hives: Group.Hives("autocmd", AutoCmdHive),
|
||||||
|
|
||||||
get activeHives() contexts.activeGroups("autocmd").map(function (h) h.autocmd).filter(function (h) h._store.length),
|
get activeHives() contexts.activeGroups("autocmd").map(function (h) h.autocmd).filter(function (h) h._store.length),
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ var Command = Class("Command", {
|
|||||||
this.options = this.options.map(CommandOption.fromArray, CommandOption);
|
this.options = this.options.map(CommandOption.fromArray, CommandOption);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get toStringParams() [this.name, this.hive.group.name],
|
||||||
|
|
||||||
get helpTag() ":" + this.name,
|
get helpTag() ":" + this.name,
|
||||||
|
|
||||||
get lastCommand() this._lastCommand || commandline.command,
|
get lastCommand() this._lastCommand || commandline.command,
|
||||||
@@ -170,12 +172,8 @@ var Command = Class("Command", {
|
|||||||
* @param {string} name The candidate name.
|
* @param {string} name The candidate name.
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
hasName: function (name) {
|
hasName: function (name) this.parsedSpecs.some(
|
||||||
return this.specs.some(function (spec) {
|
function ([long, short]) name.indexOf(short) == 0 && long.indexOf(name) == 0),
|
||||||
let [, head, tail] = /([^[]+)(?:\[(.*)])?/.exec(spec);
|
|
||||||
return name.indexOf(head) == 0 && (head + (tail || "")).indexOf(name) == 0;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper function to parse an argument string.
|
* A helper function to parse an argument string.
|
||||||
@@ -399,15 +397,118 @@ var ex = {
|
|||||||
__noSuchMethod__: function (meth, args) this._run(meth).apply(this, args)
|
__noSuchMethod__: function (meth, args) this._run(meth).apply(this, args)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var CommandHive = Class("CommandHive", {
|
||||||
|
init: function init(group) {
|
||||||
|
this.group = group;
|
||||||
|
this._map = {};
|
||||||
|
this._list = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
get toStringParams() [this.group.name],
|
||||||
|
|
||||||
|
get builtin() this.group.builtin,
|
||||||
|
|
||||||
|
/** @property {Iterator(Command)} @private */
|
||||||
|
__iterator__: function () array.iterValues(this._list.sort(function (a, b) a.name > b.name)),
|
||||||
|
|
||||||
|
/** @property {string} The last executed Ex command line. */
|
||||||
|
repeat: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new command.
|
||||||
|
*
|
||||||
|
* @param {string[]} names The names by which this command can be
|
||||||
|
* invoked. The first name specified is the command's canonical
|
||||||
|
* name.
|
||||||
|
* @param {string} description A description of the command.
|
||||||
|
* @param {function} action The action invoked by this command.
|
||||||
|
* @param {Object} extra An optional extra configuration hash.
|
||||||
|
* @optional
|
||||||
|
*/
|
||||||
|
add: function (names, description, action, extra, replace) {
|
||||||
|
extra = extra || {};
|
||||||
|
if (!extra.definedAt)
|
||||||
|
extra.definedAt = Commands.getCaller(Components.stack.caller);
|
||||||
|
|
||||||
|
extra.hive = this;
|
||||||
|
extra.parsedSpecs = Command.parseSpecs(names);
|
||||||
|
|
||||||
|
let names = array.flatten(extra.parsedSpecs);
|
||||||
|
let name = names[0];
|
||||||
|
|
||||||
|
dactyl.assert(!names.some(function (name) name in commands.builtin._map),
|
||||||
|
"E182: Can't replace non-user command: " + name);
|
||||||
|
|
||||||
|
dactyl.assert(replace || names.every(function (name) !(name in this._map), this),
|
||||||
|
"Not replacing command " + name);
|
||||||
|
|
||||||
|
for (let name in values(names)) {
|
||||||
|
ex.__defineGetter__(name, function () this._run(name));
|
||||||
|
if (name in this._map)
|
||||||
|
this.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
let closure = function () self._map[name];
|
||||||
|
|
||||||
|
memoize(this._map, name, function () Command(names, description, action, extra));
|
||||||
|
memoize(this._list, this._list.length, closure);
|
||||||
|
for (let alias in values(names.slice(1)))
|
||||||
|
memoize(this._map, alias, closure);
|
||||||
|
|
||||||
|
return name;
|
||||||
|
},
|
||||||
|
_add: function (names, description, action, extra, replace) {
|
||||||
|
extra = extra || {};
|
||||||
|
extra.definedAt = Commands.getCaller(Components.stack.caller.caller);
|
||||||
|
return this.add.apply(this, arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the command with matching *name*.
|
||||||
|
*
|
||||||
|
* @param {string} name The name of the command to return. This can be
|
||||||
|
* any of the command's names.
|
||||||
|
* @param {boolean} full If true, only return a command if one of
|
||||||
|
* its names matches *name* exactly.
|
||||||
|
* @returns {Command}
|
||||||
|
*/
|
||||||
|
get: function (name, full) this._map[name]
|
||||||
|
|| !full && array.nth(this._list, function (cmd) cmd.hasName(name), 0)
|
||||||
|
|| null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the user-defined command with matching *name*.
|
||||||
|
*
|
||||||
|
* @param {string} name The name of the command to remove. This can be
|
||||||
|
* any of the command's names.
|
||||||
|
*/
|
||||||
|
remove: function (name) {
|
||||||
|
dactyl.assert(this.group !== contexts.default,
|
||||||
|
"Cannot delete non-user commands");
|
||||||
|
|
||||||
|
let cmd = this.get(name);
|
||||||
|
this._list = this._list.filter(function (c) c !== cmd);
|
||||||
|
for (let name in values(cmd.names))
|
||||||
|
delete this._map[name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @instance commands
|
* @instance commands
|
||||||
*/
|
*/
|
||||||
var Commands = Module("commands", {
|
var Commands = Module("commands", {
|
||||||
init: function () {
|
init: function () {
|
||||||
this._exCommands = [];
|
this.user = contexts.hives.commands.user;
|
||||||
this._exMap = {};
|
this.builtin = contexts.hives.commands.builtin;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
hives: Group.Hives("commands", CommandHive),
|
||||||
|
|
||||||
|
get allHives() contexts.allGroups.commands,
|
||||||
|
|
||||||
|
get userHives() this.allHives.filter(function (h) h !== this.builtin, this),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property Indicates that no count was specified for this
|
* @property Indicates that no count was specified for this
|
||||||
* command invocation.
|
* command invocation.
|
||||||
@@ -423,84 +524,17 @@ var Commands = Module("commands", {
|
|||||||
COUNT_ALL: -2, // :%...
|
COUNT_ALL: -2, // :%...
|
||||||
|
|
||||||
/** @property {Iterator(Command)} @private */
|
/** @property {Iterator(Command)} @private */
|
||||||
__iterator__: function () {
|
iterator: function () iter.apply(null, this.hives)
|
||||||
let sorted = this._exCommands.sort(function (a, b) a.name > b.name);
|
.sort(function (a, b) a.serialGroup - b.serialGroup || a.name > b.name)
|
||||||
return array.iterValues(sorted);
|
.iterValues(),
|
||||||
},
|
|
||||||
iterator: function () {
|
|
||||||
let sorted = this._exCommands.sort(function (a, b) a.serialGroup - b.serialGroup || a.name > b.name);
|
|
||||||
return array.iterValues(sorted);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** @property {string} The last executed Ex command line. */
|
/** @property {string} The last executed Ex command line. */
|
||||||
repeat: null,
|
repeat: null,
|
||||||
|
|
||||||
_addCommand: function (args, replace) {
|
add: function () this.builtin._add.apply(this.builtin, arguments),
|
||||||
if (!args[3])
|
addUserCommand: deprecated("commands.user.add", { get: function addUserCommand() this.user.closure._add }),
|
||||||
args[3] = {};
|
getUserCommands: deprecated("iter(commands.user)", function getUserCommands() iter(commands.user).toArray()),
|
||||||
args[3].definedAt = Commands.getCaller(Components.stack.caller.caller);
|
removeUserCommand: deprecated("commands.user.remove", { get: function removeUserCommand() this.user.closure.remove }),
|
||||||
|
|
||||||
let names = array.flatten(Command.parseSpecs(args[0]));
|
|
||||||
args.parsedSpecs = names;
|
|
||||||
|
|
||||||
dactyl.assert(!names.some(function (name) name in this._exMap && !this._exMap[name].user, this),
|
|
||||||
"E182: Can't replace non-user command: " + args[0][0]);
|
|
||||||
|
|
||||||
if (!replace || !args[3].user)
|
|
||||||
dactyl.assert(!names.some(function (name) name in this._exMap, this),
|
|
||||||
"Not replacing command " + args[0]);
|
|
||||||
|
|
||||||
for (let name in values(names)) {
|
|
||||||
ex.__defineGetter__(name, function () this._run(name));
|
|
||||||
if (name in this._exMap)
|
|
||||||
commands.removeUserCommand(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = names[0];
|
|
||||||
let closure = function () commands._exMap[name];
|
|
||||||
|
|
||||||
memoize(this._exMap, name, function () Command.apply(null, args));
|
|
||||||
memoize(this._exCommands, this._exCommands.length, closure);
|
|
||||||
|
|
||||||
for (let alias in values(names.slice(1)))
|
|
||||||
memoize(this._exMap, alias, closure);
|
|
||||||
|
|
||||||
return name;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a new default command.
|
|
||||||
*
|
|
||||||
* @param {string[]} names The names by which this command can be
|
|
||||||
* invoked. The first name specified is the command's canonical
|
|
||||||
* name.
|
|
||||||
* @param {string} description A description of the command.
|
|
||||||
* @param {function} action The action invoked by this command.
|
|
||||||
* @param {Object} extra An optional extra configuration hash.
|
|
||||||
* @optional
|
|
||||||
*/
|
|
||||||
add: function (names, description, action, extra) {
|
|
||||||
return this._addCommand([names, description, action, extra], false);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a new user-defined command.
|
|
||||||
*
|
|
||||||
* @param {string[]} names The names by which this command can be
|
|
||||||
* invoked. The first name specified is the command's canonical
|
|
||||||
* name.
|
|
||||||
* @param {string} description A description of the command.
|
|
||||||
* @param {function} action The action invoked by this command.
|
|
||||||
* @param {Object} extra An optional extra configuration hash.
|
|
||||||
* @param {boolean} replace Overwrite an existing command with the same
|
|
||||||
* canonical name.
|
|
||||||
*/
|
|
||||||
addUserCommand: function (names, description, action, extra, replace) {
|
|
||||||
extra = extra || {};
|
|
||||||
extra.user = true;
|
|
||||||
|
|
||||||
return this._addCommand([names, description, action, extra], replace);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the specified command invocation object serialized to
|
* Returns the specified command invocation object serialized to
|
||||||
@@ -535,6 +569,60 @@ var Commands = Module("commands", {
|
|||||||
return res.join(" ");
|
return res.join(" ");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the command with matching *name*.
|
||||||
|
*
|
||||||
|
* @param {string} name The name of the command to return. This can be
|
||||||
|
* any of the command's names.
|
||||||
|
* @returns {Command}
|
||||||
|
*/
|
||||||
|
get: function (name, full) iter(this.hives).map(function ([i, hive]) hive.get(name, full))
|
||||||
|
.nth(util.identity, 0),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a list of user-defined commands.
|
||||||
|
*/
|
||||||
|
list: function list() {
|
||||||
|
function completerToString(completer) {
|
||||||
|
if (completer)
|
||||||
|
return [k for ([k, v] in Iterator(config.completers)) if (completer == completion.closure[v])][0] || "custom";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!commands.userHives.some(function (h) h._list.length))
|
||||||
|
dactyl.echomsg("No user-defined commands found");
|
||||||
|
else
|
||||||
|
commandline.commandOutput(
|
||||||
|
<table>
|
||||||
|
<tr highlight="Title">
|
||||||
|
<td/>
|
||||||
|
<td style="padding-right: 1em;"></td>
|
||||||
|
<td style="padding-right: 1ex;">Name</td>
|
||||||
|
<td style="padding-right: 1ex;">Args</td>
|
||||||
|
<td style="padding-right: 1ex;">Range</td>
|
||||||
|
<td style="padding-right: 1ex;">Complete</td>
|
||||||
|
<td style="padding-right: 1ex;">Definition</td>
|
||||||
|
</tr>
|
||||||
|
<col style="min-width: 6em; padding-right: 1em;"/>
|
||||||
|
{
|
||||||
|
template.map(commands.userHives, function (hive) let (i = 0)
|
||||||
|
<tr style="height: .5ex;"/> +
|
||||||
|
template.map(hive, function (cmd)
|
||||||
|
template.map(cmd.names, function (name)
|
||||||
|
<tr>
|
||||||
|
<td highlight="Title">{!i++ ? hive.group.name : ""}</td>
|
||||||
|
<td>{cmd.bang ? "!" : " "}</td>
|
||||||
|
<td>{cmd.name}</td>
|
||||||
|
<td>{cmd.argCount}</td>
|
||||||
|
<td>{cmd.count ? "0c" : ""}</td>
|
||||||
|
<td>{completerToString(cmd.completer)}</td>
|
||||||
|
<td>{cmd.replacementText || "function () { ... }"}</td>
|
||||||
|
</tr>)) +
|
||||||
|
<tr style="height: .5ex;"/>)
|
||||||
|
}
|
||||||
|
</table>);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes an Ex command script.
|
* Executes an Ex command script.
|
||||||
*
|
*
|
||||||
@@ -603,35 +691,6 @@ var Commands = Module("commands", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the command with matching *name*.
|
|
||||||
*
|
|
||||||
* @param {string} name The name of the command to return. This can be
|
|
||||||
* any of the command's names.
|
|
||||||
* @returns {Command}
|
|
||||||
*/
|
|
||||||
get: function (name, full)
|
|
||||||
this._exMap[name] || !full && array.nth(this._exCommands, function (cmd) cmd.hasName(name), 0) || null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the user-defined command with matching *name*.
|
|
||||||
*
|
|
||||||
* @param {string} name The name of the command to return. This can be
|
|
||||||
* any of the command's names.
|
|
||||||
* @returns {Command}
|
|
||||||
*/
|
|
||||||
getUserCommand: function (name)
|
|
||||||
array.nth(this._exCommands, function (cmd) cmd.user && cmd.hasName(name), 0) || null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all user-defined commands.
|
|
||||||
*
|
|
||||||
* @returns {Command[]}
|
|
||||||
*/
|
|
||||||
getUserCommands: function () {
|
|
||||||
return this._exCommands.filter(function (cmd) cmd.user);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a command invocation contains a URL referring to the
|
* Returns true if a command invocation contains a URL referring to the
|
||||||
* domain *host*.
|
* domain *host*.
|
||||||
@@ -1121,21 +1180,8 @@ var Commands = Module("commands", {
|
|||||||
get complQuote() Commands.complQuote,
|
get complQuote() Commands.complQuote,
|
||||||
|
|
||||||
/** @property */
|
/** @property */
|
||||||
get quoteArg() Commands.quoteArg, // XXX: better somewhere else?
|
get quoteArg() Commands.quoteArg // XXX: better somewhere else?
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the user-defined command with matching *name*.
|
|
||||||
*
|
|
||||||
* @param {string} name The name of the command to remove. This can be
|
|
||||||
* any of the command's names.
|
|
||||||
*/
|
|
||||||
removeUserCommand: function (name) {
|
|
||||||
let cmd = this.get(name);
|
|
||||||
dactyl.assert(cmd.user, "E184: No such user-defined command: " + name);
|
|
||||||
this._exCommands = this._exCommands.filter(function (c) c !== cmd);
|
|
||||||
for (let name in values(cmd.names))
|
|
||||||
delete this._exMap[name];
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
/**
|
/**
|
||||||
* Returns a frame object describing the currently executing
|
* Returns a frame object describing the currently executing
|
||||||
@@ -1199,7 +1245,7 @@ var Commands = Module("commands", {
|
|||||||
completion.command = function command(context) {
|
completion.command = function command(context) {
|
||||||
context.title = ["Command"];
|
context.title = ["Command"];
|
||||||
context.keys = { text: "longNames", description: "description" };
|
context.keys = { text: "longNames", description: "description" };
|
||||||
context.completions = [k for (k in commands)];
|
context.generate = function () commands.hives.map(function (h) h._list).flatten();
|
||||||
};
|
};
|
||||||
|
|
||||||
// provides completions for ex commands, including their arguments
|
// provides completions for ex commands, including their arguments
|
||||||
@@ -1254,8 +1300,6 @@ var Commands = Module("commands", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
commands: function () {
|
commands: function () {
|
||||||
let completerMap = config.completers;
|
|
||||||
|
|
||||||
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s
|
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s
|
||||||
// specified - useful?
|
// specified - useful?
|
||||||
commands.add(["com[mand]"],
|
commands.add(["com[mand]"],
|
||||||
@@ -1266,7 +1310,9 @@ var Commands = Module("commands", {
|
|||||||
dactyl.assert(!cmd || cmd.split(",").every(commands.validName.closure.test),
|
dactyl.assert(!cmd || cmd.split(",").every(commands.validName.closure.test),
|
||||||
"E182: Invalid command name");
|
"E182: Invalid command name");
|
||||||
|
|
||||||
if (args.literalArg) {
|
if (!args.literalArg)
|
||||||
|
commands.list();
|
||||||
|
else {
|
||||||
let completer = args["-complete"];
|
let completer = args["-complete"];
|
||||||
let completerFunc = null; // default to no completion for user commands
|
let completerFunc = null; // default to no completion for user commands
|
||||||
|
|
||||||
@@ -1295,10 +1341,10 @@ var Commands = Module("commands", {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
completerFunc = function (context) completion.closure[completerMap[completer]](context);
|
completerFunc = function (context) completion.closure[config.completers[completer]](context);
|
||||||
}
|
}
|
||||||
|
|
||||||
let added = commands.addUserCommand(cmd.split(","),
|
let added = args["-group"].add(cmd.split(","),
|
||||||
args["-description"],
|
args["-description"],
|
||||||
contexts.bindMacro(args, "-ex",
|
contexts.bindMacro(args, "-ex",
|
||||||
function makeParams(args, modifiers) ({
|
function makeParams(args, modifiers) ({
|
||||||
@@ -1323,29 +1369,6 @@ var Commands = Module("commands", {
|
|||||||
if (!added)
|
if (!added)
|
||||||
dactyl.echoerr("E174: Command already exists: add ! to replace it");
|
dactyl.echoerr("E174: Command already exists: add ! to replace it");
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
let completerToString = function completerToString(completer) {
|
|
||||||
if (completer)
|
|
||||||
return [k for ([k, v] in Iterator(completerMap)) if (completer == completion.closure[v])][0] || "custom";
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: perhaps we shouldn't allow options in a list call but just ignore them for now
|
|
||||||
let cmds = commands._exCommands.filter(function (c) c.user && (!cmd || c.name.match("^" + cmd)));
|
|
||||||
|
|
||||||
if (cmds.length > 0)
|
|
||||||
commandline.commandOutput(
|
|
||||||
template.tabular(["", "Name", "Args", "Range", "Complete", "Definition"], ["padding-right: 2em;"],
|
|
||||||
([cmd.bang ? "!" : " ",
|
|
||||||
cmd.name,
|
|
||||||
cmd.argCount,
|
|
||||||
cmd.count ? "0c" : "",
|
|
||||||
completerToString(cmd.completer),
|
|
||||||
cmd.replacementText || "function () { ... }"]
|
|
||||||
for ([, cmd] in Iterator(cmds)))));
|
|
||||||
else
|
|
||||||
dactyl.echomsg("No user-defined commands found");
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
bang: true,
|
bang: true,
|
||||||
completer: function (context, args) {
|
completer: function (context, args) {
|
||||||
@@ -1362,22 +1385,27 @@ var Commands = Module("commands", {
|
|||||||
// TODO: "E180: invalid complete value: " + arg
|
// TODO: "E180: invalid complete value: " + arg
|
||||||
names: ["-complete", "-C"],
|
names: ["-complete", "-C"],
|
||||||
description: "The argument completion function",
|
description: "The argument completion function",
|
||||||
completer: function (context) [[k, ""] for ([k, v] in Iterator(completerMap))],
|
completer: function (context) [[k, ""] for ([k, v] in Iterator(config.completers))],
|
||||||
type: CommandOption.STRING,
|
type: CommandOption.STRING,
|
||||||
validator: function (arg) arg in completerMap || /^custom,/.test(arg),
|
validator: function (arg) arg in config.completers || /^custom,/.test(arg),
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
names: ["-description", "-desc", "-d"],
|
names: ["-description", "-desc", "-d"],
|
||||||
description: "A user-visible description of the command",
|
description: "A user-visible description of the command",
|
||||||
default: "User-defined command",
|
default: "User-defined command",
|
||||||
type: CommandOption.STRING
|
type: CommandOption.STRING
|
||||||
}, {
|
},
|
||||||
|
contexts.GroupFlag("commands"),
|
||||||
|
{
|
||||||
names: ["-javascript", "-js", "-j"],
|
names: ["-javascript", "-js", "-j"],
|
||||||
description: "Execute the definition as JavaScript rather than Ex commands"
|
description: "Execute the definition as JavaScript rather than Ex commands"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
names: ["-literal", "-l"],
|
names: ["-literal", "-l"],
|
||||||
description: "Process the nth ignoring any quoting or meta characters",
|
description: "Process the nth ignoring any quoting or meta characters",
|
||||||
type: CommandOption.INT
|
type: CommandOption.INT
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
names: ["-nargs", "-a"],
|
names: ["-nargs", "-a"],
|
||||||
description: "The allowed number of arguments",
|
description: "The allowed number of arguments",
|
||||||
completer: [["0", "No arguments are allowed (default)"],
|
completer: [["0", "No arguments are allowed (default)"],
|
||||||
@@ -1388,31 +1416,36 @@ var Commands = Module("commands", {
|
|||||||
default: "0",
|
default: "0",
|
||||||
type: CommandOption.STRING,
|
type: CommandOption.STRING,
|
||||||
validator: function (arg) /^[01*?+]$/.test(arg)
|
validator: function (arg) /^[01*?+]$/.test(arg)
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
names: ["-nopersist", "-n"],
|
names: ["-nopersist", "-n"],
|
||||||
description: "Do not save this command to an auto-generated RC file"
|
description: "Do not save this command to an auto-generated RC file"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
literal: 1,
|
literal: 1,
|
||||||
serialize: function () [ {
|
|
||||||
command: this.name,
|
serialize: function () array(commands.userHives)
|
||||||
bang: true,
|
.filter(function (h) h.group.persist)
|
||||||
options: iter([v, typeof cmd[k] == "boolean" ? null : cmd[k]]
|
.map(function (hive) [
|
||||||
// FIXME: this map is expressed multiple times
|
{
|
||||||
for ([k, v] in Iterator({
|
command: this.name,
|
||||||
argCount: "-nargs",
|
bang: true,
|
||||||
bang: "-bang",
|
options: iter([v, typeof cmd[k] == "boolean" ? null : cmd[k]]
|
||||||
count: "-count",
|
// FIXME: this map is expressed multiple times
|
||||||
description: "-description"
|
for ([k, v] in Iterator({
|
||||||
}))
|
argCount: "-nargs",
|
||||||
if (cmd[k])).toObject(),
|
bang: "-bang",
|
||||||
arguments: [cmd.name],
|
count: "-count",
|
||||||
literalArg: cmd.action,
|
description: "-description"
|
||||||
ignoreDefaults: true
|
}))
|
||||||
}
|
if (cmd[k])).toObject(),
|
||||||
for ([k, cmd] in Iterator(commands._exCommands))
|
arguments: [cmd.name],
|
||||||
if (cmd.user && cmd.persist)
|
literalArg: cmd.action,
|
||||||
]
|
ignoreDefaults: true
|
||||||
|
}
|
||||||
|
for (cmd in hive) if (cmd.persist)
|
||||||
|
], this)
|
||||||
|
.flatten().array
|
||||||
});
|
});
|
||||||
|
|
||||||
commands.add(["comc[lear]"],
|
commands.add(["comc[lear]"],
|
||||||
@@ -1449,8 +1482,14 @@ var Commands = Module("commands", {
|
|||||||
name: ["listc[ommands]", "lc"],
|
name: ["listc[ommands]", "lc"],
|
||||||
description: "List all Ex commands along with their short descriptions",
|
description: "List all Ex commands along with their short descriptions",
|
||||||
index: "ex-cmd",
|
index: "ex-cmd",
|
||||||
iterate: function (args) commands,
|
iterate: function (args) commands.iterator().map(function (cmd) ({
|
||||||
|
__proto__: cmd,
|
||||||
|
columns: [
|
||||||
|
cmd.hive == commands.builtin ? "" : <span highlight="Object" style="padding-right: 1em;">{cmd.hive.group.name}</span>
|
||||||
|
]
|
||||||
|
})),
|
||||||
format: {
|
format: {
|
||||||
|
headings: ["Command", "Group", "Description"],
|
||||||
description: function (cmd) template.linkifyHelp(cmd.description + (cmd.replacementText ? ": " + cmd.action : "")),
|
description: function (cmd) template.linkifyHelp(cmd.description + (cmd.replacementText ? ": " + cmd.action : "")),
|
||||||
help: function (cmd) ":" + cmd.name
|
help: function (cmd) ":" + cmd.name
|
||||||
}
|
}
|
||||||
@@ -1471,8 +1510,8 @@ var Commands = Module("commands", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
javascript: function () {
|
javascript: function () {
|
||||||
JavaScript.setCompleter([commands.get, commands.removeUserCommand],
|
JavaScript.setCompleter([commands.user.get, commands.user.remove],
|
||||||
[function () ([c.name, c.description] for (c in commands))]);
|
[function () ([c.name, c.description] for (c in this))]);
|
||||||
},
|
},
|
||||||
mappings: function () {
|
mappings: function () {
|
||||||
mappings.add(config.browserModes,
|
mappings.add(config.browserModes,
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ var Group = Class("Group", {
|
|||||||
|
|
||||||
hiveMap: {},
|
hiveMap: {},
|
||||||
|
|
||||||
Hive: Class("Hive", Class.Property, {
|
Hives: Class("Hives", Class.Property, {
|
||||||
init: function init(name, constructor) {
|
init: function init(name, constructor) {
|
||||||
const self = this;
|
const self = this;
|
||||||
if (this.Group)
|
if (this.Group)
|
||||||
@@ -116,13 +116,18 @@ var Contexts = Module("contexts", {
|
|||||||
|
|
||||||
get hives() Group.hiveMap,
|
get hives() Group.hiveMap,
|
||||||
|
|
||||||
addGroup: function addGroup(name, description, filter, persist) {
|
addGroup: function addGroup(name, description, filter, persist, replace) {
|
||||||
this.removeGroup(name);
|
if (replace)
|
||||||
|
this.removeGroup(name);
|
||||||
|
|
||||||
let group = Group(name, description, filter, persist);
|
let group = this.groupMap[name];
|
||||||
this.groupList.unshift(group);
|
if (!group) {
|
||||||
this.groupMap[name] = group;
|
group = Group(name, description, filter, persist);
|
||||||
this.hiveProto.__defineGetter__(name, function () group[this._hive]);
|
this.groupList.unshift(group);
|
||||||
|
this.groupMap[name] = group;
|
||||||
|
this.hiveProto.__defineGetter__(name, function () group[this._hive]);
|
||||||
|
delete this.groups;
|
||||||
|
}
|
||||||
return group;
|
return group;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -248,7 +253,8 @@ var Contexts = Module("contexts", {
|
|||||||
delete plugins[this.NAME];
|
delete plugins[this.NAME];
|
||||||
if (plugins[this.PATH] === this)
|
if (plugins[this.PATH] === this)
|
||||||
delete plugins[this.PATH];
|
delete plugins[this.PATH];
|
||||||
contexts.removeGroup(this.GROUP);
|
if (!this.GROUP.builtin)
|
||||||
|
contexts.removeGroup(this.GROUP);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
Class.replaceProperty(plugins, file.path, self);
|
Class.replaceProperty(plugins, file.path, self);
|
||||||
@@ -264,12 +270,15 @@ var Contexts = Module("contexts", {
|
|||||||
|
|
||||||
let path = isRuntime ? file.getRelativeDescriptor(isRuntime) : file.path;
|
let path = isRuntime ? file.getRelativeDescriptor(isRuntime) : file.path;
|
||||||
|
|
||||||
self.GROUP = group ||
|
if (!group)
|
||||||
contexts.addGroup((isRuntime ? "" : "script-") +
|
group = contexts.addGroup((isRuntime ? "" : "script-") +
|
||||||
commands.nameRegexp.iterate(path.replace(/\..*/, ""))
|
commands.nameRegexp.iterate(path.replace(/\..*/, ""))
|
||||||
.join("-"),
|
.join("-"),
|
||||||
"Script group for " + file.path,
|
"Script group for " + file.path,
|
||||||
null, false);
|
null, false);
|
||||||
|
|
||||||
|
Class.replaceProperty(self, "GROUP", group);
|
||||||
|
Class.replaceProperty(self, "group", group);
|
||||||
|
|
||||||
return plugins.contexts[file.path] = self;
|
return plugins.contexts[file.path] = self;
|
||||||
},
|
},
|
||||||
@@ -297,8 +306,8 @@ var Contexts = Module("contexts", {
|
|||||||
dactyl.assert(group || name, "No current group");
|
dactyl.assert(group || name, "No current group");
|
||||||
|
|
||||||
let filter = Group.compileFilter(args["-locations"]);
|
let filter = Group.compileFilter(args["-locations"]);
|
||||||
if (!group)
|
if (!group || args.bang)
|
||||||
group = contexts.addGroup(name, args["-description"], filter, !args["-nopersist"]);
|
group = contexts.addGroup(name, args["-description"], filter, !args["-nopersist"], args.bang);
|
||||||
else if (!group.builtin) {
|
else if (!group.builtin) {
|
||||||
if (args.has("-locations"))
|
if (args.has("-locations"))
|
||||||
group.filter = filter;
|
group.filter = filter;
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ var Mappings = Module("mappings", {
|
|||||||
|
|
||||||
repeat: Modes.boundProperty(),
|
repeat: Modes.boundProperty(),
|
||||||
|
|
||||||
hives: Group.Hive("mappings", MapHive),
|
hives: Group.Hives("mappings", MapHive),
|
||||||
|
|
||||||
get allHives() contexts.allGroups.mappings,
|
get allHives() contexts.allGroups.mappings,
|
||||||
|
|
||||||
@@ -668,6 +668,7 @@ var Mappings = Module("mappings", {
|
|||||||
iterate: function (args) {
|
iterate: function (args) {
|
||||||
let mainMode = this.getMode(args);
|
let mainMode = this.getMode(args);
|
||||||
let seen = {};
|
let seen = {};
|
||||||
|
// Bloody hell. --Kris
|
||||||
for (let mode in values([mainMode].concat(mainMode.bases)))
|
for (let mode in values([mainMode].concat(mainMode.bases)))
|
||||||
for (let hive in mappings.hives.iterValues())
|
for (let hive in mappings.hives.iterValues())
|
||||||
for (let map in array.iterValues(hive.getStack(mode)))
|
for (let map in array.iterValues(hive.getStack(mode)))
|
||||||
@@ -677,7 +678,7 @@ var Mappings = Module("mappings", {
|
|||||||
name: name,
|
name: name,
|
||||||
columns: [
|
columns: [
|
||||||
mode == mainMode ? "" : <span highlight="Object" style="padding-right: 1em;">{mode.name}</span>,
|
mode == mainMode ? "" : <span highlight="Object" style="padding-right: 1em;">{mode.name}</span>,
|
||||||
hive.name == "builtin" ? "" : <span highlight="Object" style="padding-right: 1em;">{hive.name}</span>
|
hive == mappings.builtin ? "" : <span highlight="Object" style="padding-right: 1em;">{hive.group.name}</span>
|
||||||
],
|
],
|
||||||
__proto__: map
|
__proto__: map
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -612,7 +612,7 @@ var IO = Module("io", {
|
|||||||
"E189: " + file.path.quote() + " exists (add ! to override)");
|
"E189: " + file.path.quote() + " exists (add ! to override)");
|
||||||
|
|
||||||
// TODO: Use a set/specifiable list here:
|
// TODO: Use a set/specifiable list here:
|
||||||
let lines = [cmd.serialize().map(commands.commandToString, cmd) for (cmd in commands.iterator()) if (cmd.serialize)];
|
let lines = [cmd.serialize().map(commands.commandToString, cmd) for (cmd in commands.iterator(true)) if (cmd.serialize)];
|
||||||
lines = array.flatten(lines);
|
lines = array.flatten(lines);
|
||||||
|
|
||||||
lines.unshift('"' + config.version + "\n");
|
lines.unshift('"' + config.version + "\n");
|
||||||
|
|||||||
@@ -600,7 +600,7 @@ var Styles = Module("Styles", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
contexts: function (dactyl, modules, window) {
|
contexts: function (dactyl, modules, window) {
|
||||||
modules.Group.Hive("styles", function (group) styles.addHive(group.name));
|
modules.Group.Hives("styles", function (group) styles.addHive(group.name));
|
||||||
},
|
},
|
||||||
completion: function (dactyl, modules, window) {
|
completion: function (dactyl, modules, window) {
|
||||||
const names = Array.slice(util.computedStyle(window.document.createElement("div")));
|
const names = Array.slice(util.computedStyle(window.document.createElement("div")));
|
||||||
|
|||||||
Reference in New Issue
Block a user