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

Move Command's property definitions outside init.

--HG--
extra : rebase_source : 2237c2350957975938140d4f4c556898763ef7d3
This commit is contained in:
Doug Kearns
2009-11-16 02:32:28 +11:00
parent fd37a5deb0
commit 01a04a9d9f
2 changed files with 119 additions and 112 deletions

View File

@@ -1,4 +1,6 @@
// Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org> // Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2009 by Doug Kearns <dougkearns@gmail.com>
// Copyright (c) 2008-2009 by Kris Maglione <maglione.k at Gmail>
// //
// This work is licensed for reuse under an MIT license. Details are // This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file. // given in the LICENSE.txt file included with this file.
@@ -36,96 +38,24 @@ const Command = Class("Command", {
requires: ["config"], requires: ["config"],
init: function (specs, description, action, extraInfo) { init: function (specs, description, action, extraInfo) {
specs = Array.concat(specs); specs = Array.concat(specs); // XXX
let expandedSpecs = Command.parseSpecs(specs);
if (!extraInfo) if (!extraInfo)
extraInfo = {}; extraInfo = {};
let expandedSpecs = Command.parseSpecs(specs);
/**
* @property {string[]} All of this command's name specs. e.g., "com[mand]"
*/
this.specs = specs; this.specs = specs;
/** @property {string[]} All of this command's short names, e.g., "com" */ this.shortNames = expandedSpecs.map(function (n) n[1]);
this.shortNames = expandedSpecs.shortNames; this.longNames = expandedSpecs.map(function (n) n[0]);
/**
* @property {string[]} All of this command's long names, e.g., "command"
*/
this.longNames = expandedSpecs.longNames;
/** @property {string} The command's canonical name. */
this.name = this.longNames[0]; this.name = this.longNames[0];
/** @property {string[]} All of this command's long and short names. */ this.names = array(expandedSpecs).flatten();
this.names = expandedSpecs.names; // return all command name aliases this.description = description;
/** @property {string} This command's description, as shown in :exusage */
this.description = description || "";
/**
* @property {function (Args)} The function called to execute this command.
*/
this.action = action; this.action = action;
/**
* @property {string} This command's argument count spec.
* @see Commands#parseArguments
*/
this.argCount = extraInfo.argCount || 0;
/**
* @property {function (CompletionContext, Args)} This command's completer.
* @see CompletionContext
*/
this.completer = extraInfo.completer || null;
/** @property {boolean} Whether this command accepts a here document. */
this.hereDoc = extraInfo.hereDoc || false;
/**
* @property {Array} The options this command takes.
* @see Commands@parseArguments
*/
this.options = extraInfo.options || [];
/**
* @property {boolean} Whether this command may be called with a bang,
* e.g., :com!
*/
this.bang = extraInfo.bang || false;
/**
* @property {boolean} Whether this command may be called with a count,
* e.g., :12bdel
*/
this.count = extraInfo.count || false;
/**
* @property {boolean} At what index this command's literal arguments
* begin. For instance, with a value of 2, all arguments starting with
* the third are parsed as a single string, with all quoting characters
* passed literally. This is especially useful for commands which take
* key mappings or Ex command lines as arguments.
*/
this.literal = extraInfo.literal == null ? null : extraInfo.literal;
/**
* @property {function} Should return an array of <b>Object</b>s suitable
* to be passed to {@link Commands#commandToString}, one for each past
* invocation which should be restored on subsequent @liberator
* startups.
*/
this.serial = extraInfo.serial;
/**
* @property {boolean} When true, invocations of this command
* may contain private data which should be purged from
* saved histories when clearing private data.
*/
this.privateData = Boolean(extraInfo.privateData);
/** extraInfo.privateData = Boolean(extraInfo.privateData); // XXX
* @property {boolean} Specifies whether this is a user command. User update(this, extraInfo);
* commands may be created by plugins, or directly by users, and,
* unlike basic commands, may be overwritten. Users and plugin authors
* should create only user commands.
*/
this.user = extraInfo.user || false;
/**
* @property {string} For commands defined via :command, contains the Ex
* command line to be executed upon invocation.
*/
this.replacementText = extraInfo.replacementText || null;
}, },
/** /**
* Execute this command. * Execute this command.
* *
@@ -199,40 +129,108 @@ const Command = Class("Command", {
* @returns {Args} * @returns {Args}
* @see Commands#parseArgs * @see Commands#parseArgs
*/ */
parseArgs: function (args, complete, extra) commands.parseArgs(args, this.options, this.argCount, false, this.literal, complete, extra) parseArgs: function (args, complete, extra) commands.parseArgs(args, this.options, this.argCount, false, this.literal, complete, extra),
}, {
/** /**
* convert command name abbreviation specs of the form * @property {string[]} All of this command's name specs. e.g., "com[mand]"
* 'shortname[optional-tail]' to short and long versions Eg. 'abc[def]' -> */
* 'abc', 'abcdef' specs: null,
/** @property {string[]} All of this command's short names, e.g., "com" */
shortNames: null,
/**
* @property {string[]} All of this command's long names, e.g., "command"
*/
longNames: null,
/** @property {string} The command's canonical name. */
name: null,
/** @property {string[]} All of this command's long and short names. */
names: null,
/** @property {string} This command's description, as shown in :exusage */
description: "",
/**
* @property {function (Args)} The function called to execute this command.
*/
action: null,
/**
* @property {string} This command's argument count spec.
* @see Commands#parseArguments
*/
argCount: 0,
/**
* @property {function (CompletionContext, Args)} This command's completer.
* @see CompletionContext
*/
completer: null,
/** @property {boolean} Whether this command accepts a here document. */
hereDoc: false,
/**
* @property {Array} The options this command takes.
* @see Commands@parseArguments
*/
options: [],
/**
* @property {boolean} Whether this command may be called with a bang,
* e.g., :com!
*/
bang: false,
/**
* @property {boolean} Whether this command may be called with a count,
* e.g., :12bdel
*/
count: false,
/**
* @property {boolean} At what index this command's literal arguments
* begin. For instance, with a value of 2, all arguments starting with
* the third are parsed as a single string, with all quoting characters
* passed literally. This is especially useful for commands which take
* key mappings or Ex command lines as arguments.
*/
literal: null,
/**
* @property {function} Should return an array of <b>Object</b>s suitable
* to be passed to {@link Commands#commandToString}, one for each past
* invocation which should be restored on subsequent @liberator
* startups.
*/
serial: null,
/**
* @property {boolean} When true, invocations of this command
* may contain private data which should be purged from
* saved histories when clearing private data.
*/
privateData: false,
/**
* @property {boolean} Specifies whether this is a user command. User
* commands may be created by plugins, or directly by users, and,
* unlike basic commands, may be overwritten. Users and plugin authors
* should create only user commands.
*/
user: false,
/**
* @property {string} For commands defined via :command, contains the Ex
* command line to be executed upon invocation.
*/
replacementText: null
}, {
// TODO: do we really need more than longNames as a convenience anyway?
/**
* Converts command name abbreviation specs of the form
* 'shortname[optional-tail]' to short and long versions:
* ["abc[def]", "ghijkl"] -> [["abcdef", "abc"], ["ghijlk"]]
*
* @param {Array} specs An array of command name specs to parse.
* @returns {Array}
*/ */
parseSpecs: function (specs) { parseSpecs: function (specs) {
// Whoever wrote the following should be ashamed. :( return specs.map(function (spec) {
// Good grief! I have no words... -- djk ;-) let long = spec.replace(/[[\]]/g, "");
// let shortNames = longNames = names = []; let short = spec.replace(/\[.*]/, "");
let names = []; return short == long ? [long] : [long, short];
let longNames = []; });
let shortNames = [];
for (let [, spec] in Iterator(specs)) {
let matches = spec.match(/(\w+)\[(\w+)\](\w*)/);
if (matches) {
shortNames.push(matches[1] + matches[3]);
longNames.push(matches[1] + matches[2] + matches[3]);
// order as long1, short1, long2, short2
names.push(matches[1] + matches[2]);
names.push(matches[1]);
}
else {
longNames.push(spec);
names.push(spec);
}
}
return { names: names, longNames: longNames, shortNames: shortNames };
} }
}); });

View File

@@ -805,6 +805,15 @@ const Util = Module("util", {
return obj; return obj;
}, },
/**
* Compacts an array, removing all elements that are null or undefined:
* ["foo", null, "bar", undefined] -> ["foo", "bar"]
*
* @param {Array} ary
* @returns {Array}
*/
compact: function compact(ary) ary.filter(function (item) item != null),
/** /**
* Flattens an array, such that all elements of the array are * Flattens an array, such that all elements of the array are
* joined into a single array: * joined into a single array: