mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-20 10:17:59 +01:00
Deal with some duplicated code, plus some collateral optimization.
This commit is contained in:
@@ -258,6 +258,31 @@ const Command = Class("Command", {
|
||||
optionMap: Class.memoize(function () array(this.options)
|
||||
.map(function (opt) opt.names.map(function (name) [name, opt]))
|
||||
.flatten.toObject()),
|
||||
newArgs: function () {
|
||||
let res = [];
|
||||
res.__proto__ = this.argsPrototype;
|
||||
return res;
|
||||
},
|
||||
argsPrototype: Class.memoize(function () update([],
|
||||
array([opt, opt.default] for (opt in values(this.options)) if (set.has(opt, "default")))
|
||||
.toObject(),
|
||||
{
|
||||
__iterator__: function () array.iterItems(this),
|
||||
command: this,
|
||||
get literalArg() this.command.literal != null && this[this.command.literal] || "",
|
||||
// TODO: string: Class.memoize(function () { ... }),
|
||||
verify: function verify() {
|
||||
if (this.argCount) {
|
||||
dactyl.assert((this.length > 0 || !/^[1+]$/.test(this.command.argCount)) &&
|
||||
(this.literal == null || !/[1+]/.test(this.command.argCount) || /\S/.test(this.literalArg || "")),
|
||||
"E471: Argument required");
|
||||
|
||||
dactyl.assert((this.length == 0 || this.command.argCount !== "0") &&
|
||||
(this.length <= 1 || !/^[01?]$/.test(this.command.argCount)),
|
||||
"E488: Trailing characters");
|
||||
}
|
||||
}
|
||||
})),
|
||||
/**
|
||||
* @property {boolean|function(args)} When true, invocations of this
|
||||
* command may contain private data which should be purged from
|
||||
@@ -355,35 +380,26 @@ const ex = {
|
||||
let cmd = commands.get(meth);
|
||||
dactyl.assert(cmd, "No such command");
|
||||
|
||||
let res = cmd.newArgs();
|
||||
if (isObject(args[0]))
|
||||
for (let [k, v] in Iterator(args.shift()))
|
||||
if (k == "!")
|
||||
args.bang = v;
|
||||
res.bang = v;
|
||||
else if (k == "#")
|
||||
args.count = v;
|
||||
res.count = v;
|
||||
else {
|
||||
let opt = cmd.optionMap["-" + k];
|
||||
let val = opt.type && opt.type.parse(v);
|
||||
dactyl.assert(val != null && (typeof val !== "number" || !isNaN(val)),
|
||||
"No such option: " + k);
|
||||
args[opt.names[0]] = val;
|
||||
res[opt.names[0]] = val;
|
||||
}
|
||||
if (cmd.literal != null)
|
||||
args.literalArg = args[cmd.literal];
|
||||
for (let [i, val] in array.iterItems(args))
|
||||
res[i] = String(val);
|
||||
|
||||
// FIXME: Duplicated in parseArgs.
|
||||
res.verify();
|
||||
|
||||
dactyl.assert((args.length > 0 || !/^[1+]$/.test(this.argCount)) &&
|
||||
(this.literal == null || !/[1+]/.test(this.argCount) || /\S/.test(args.literalArg || "")),
|
||||
"E471: Argument required");
|
||||
|
||||
// This logic eludes me... --Kris
|
||||
dactyl.assert((args.length == 0 || this.argCount !== "0") &&
|
||||
(args.length <= 1 || !/^[01?]$/.test(this.argCount)),
|
||||
"E488: Trailing characters");
|
||||
|
||||
// TODO: memoize(args, "string", function () { ... });
|
||||
return cmd.execute(args);
|
||||
return cmd.execute(res);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -683,6 +699,7 @@ const Commands = Module("commands", {
|
||||
* @returns {Args}
|
||||
*/
|
||||
parseArgs: function (str, params) {
|
||||
try {
|
||||
function getNextArg(str) {
|
||||
if (str.substr(0, 2) === "<<" && hereDoc) {
|
||||
let arg = /^<<(\S*)/.exec(str)[1];
|
||||
@@ -707,10 +724,8 @@ const Commands = Module("commands", {
|
||||
if (!argCount)
|
||||
argCount = "*";
|
||||
|
||||
var args = []; // parsed options
|
||||
args.__iterator__ = function () array.iterItems(this);
|
||||
var args = (params.newArgs || Array).call(params); // parsed options
|
||||
args.string = str; // for access to the unparsed string
|
||||
args.literalArg = "";
|
||||
|
||||
// FIXME!
|
||||
for (let [k, v] in Iterator(extra || []))
|
||||
@@ -873,7 +888,6 @@ const Commands = Module("commands", {
|
||||
sub = arg + sub.substr(count);
|
||||
}
|
||||
|
||||
args.literalArg = sub;
|
||||
args.push(sub);
|
||||
args.quote = null;
|
||||
break;
|
||||
@@ -923,21 +937,15 @@ const Commands = Module("commands", {
|
||||
complete.completions = completeOpts;
|
||||
}
|
||||
|
||||
// check for correct number of arguments
|
||||
if (args.length == 0 && /^[1+]$/.test(argCount) ||
|
||||
literal != null && /[1+]/.test(argCount) && !/\S/.test(args.literalArg || "")) {
|
||||
if (!complete)
|
||||
fail("E471: Argument required");
|
||||
}
|
||||
else if (args.length == 1 && (argCount == "0") ||
|
||||
args.length > 1 && /^[01?]$/.test(argCount))
|
||||
fail("E488: Trailing characters");
|
||||
|
||||
for (let opt in values(options))
|
||||
if (set.has(opt, "default") && args[opt.names[0]] === undefined)
|
||||
args[opt.names[0]] = opt.default;
|
||||
if (args.verify)
|
||||
args.verify();
|
||||
|
||||
return args;
|
||||
}
|
||||
catch (e if complete && e instanceof FailedAssertion) {
|
||||
complete.message = e;
|
||||
return args;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -528,6 +528,8 @@ function memoize(obj, key, getter) {
|
||||
obj.__defineGetter__(key, function replace() (
|
||||
Class.replaceProperty(this.instance || this, key, null),
|
||||
Class.replaceProperty(this.instance || this, key, getter.call(this, key))));
|
||||
obj.__defineSetter__(key, function replace(val)
|
||||
Class.replaceProperty(this.instance || this, key, val));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user