// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
-// Copyright (c) 2008-2011 by Kris Maglione <maglione.k at Gmail>
+// Copyright (c) 2008-2012 Kris Maglione <maglione.k at Gmail>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-/* use strict */
+"use strict";
try {
-Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("commands", {
exports: ["ArgType", "Command", "Commands", "CommandOption", "Ex", "commands"],
require: ["contexts", "messages", "util"]
-}, this);
+});
+
+lazyRequire("help", ["help"]);
+lazyRequire("options", ["Option"]);
+lazyRequire("template", ["template"]);
/**
* A structure representing the options available for a command.
* @param {function} action The action invoked by this command when executed.
* @param {Object} extraInfo An optional extra configuration hash. The
* following properties are supported.
+ * always - see {@link Command#always}
* argCount - see {@link Command#argCount}
* bang - see {@link Command#bang}
* completer - see {@link Command#completer}
* @property {function (Args)} The function called to execute this command.
*/
action: null,
+
+ /**
+ * @property {function (Args)} A function which is called when this
+ * command is encountered, even if we are ignoring commands. Used to
+ * implement control structures.
+ */
+ always: 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 {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 {function(args)} A function which should return a list
* of domains referenced in the given args. Used in determining
* private data.
*/
domains: function (args) [],
+
/**
* @property {boolean} At what index this command's literal arguments
* begin. For instance, with a value of 2, all arguments starting with
* key mappings or Ex command lines as arguments.
*/
literal: null,
+
/**
* @property {Array} The options this command takes.
* @see Commands@parseArguments
let { cache } = this.modules;
this.cached = true;
- cache.register(this.cacheKey, function () {
+ let cached = cache.get(this.cacheKey, function () {
self.cached = false;
this.modules.moduleManager.initDependencies("commands");
let hives = (hives || this.userHives).map(function (h) [h, cmds(h)]).filter(function ([h, c]) c.length);
- let list = <table>
- <tr highlight="Title">
- <td/>
- <td style="padding-right: 1em;"></td>
- <td style="padding-right: 1ex;">{_("title.Name")}</td>
- <td style="padding-right: 1ex;">{_("title.Args")}</td>
- <td style="padding-right: 1ex;">{_("title.Range")}</td>
- <td style="padding-right: 1ex;">{_("title.Complete")}</td>
- <td style="padding-right: 1ex;">{_("title.Definition")}</td>
- </tr>
- <col style="min-width: 6em; padding-right: 1em;"/>
- {
- template.map(hives, function ([hive, cmds]) let (i = 0)
- <tr style="height: .5ex;"/> +
- template.map(cmds, function (cmd)
- <tr>
- <td highlight="Title">{!i++ ? hive.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>;
-
- if (list.*.length() === list.text().length() + 2)
- dactyl.echomsg(_("command.none"));
- else
- commandline.commandOutput(list);
+ let list = ["table", {},
+ ["tr", { highlight: "Title" },
+ ["td"],
+ ["td", { style: "padding-right: 1em;" }],
+ ["td", { style: "padding-right: 1ex;" }, _("title.Name")],
+ ["td", { style: "padding-right: 1ex;" }, _("title.Args")],
+ ["td", { style: "padding-right: 1ex;" }, _("title.Range")],
+ ["td", { style: "padding-right: 1ex;" }, _("title.Complete")],
+ ["td", { style: "padding-right: 1ex;" }, _("title.Definition")]],
+ ["col", { style: "min-width: 6em; padding-right: 1em;" }],
+ hives.map(function ([hive, cmds]) let (i = 0) [
+ ["tr", { style: "height: .5ex;" }],
+ cmds.map(function (cmd)
+ ["tr", {},
+ ["td", { highlight: "Title" }, !i++ ? hive.name : ""],
+ ["td", {}, cmd.bang ? "!" : " "],
+ ["td", {}, cmd.name],
+ ["td", {}, cmd.argCount],
+ ["td", {}, cmd.count ? "0c" : ""],
+ ["td", {}, completerToString(cmd.completer)],
+ ["td", {}, cmd.replacementText || "function () { ... }"]]),
+ ["tr", { style: "height: .5ex;" }]])];
+
+ // E4X-FIXME
+ // if (list.*.length() === list.text().length() + 2)
+ // dactyl.echomsg(_("command.none"));
+ // else
+ commandline.commandOutput(list);
}
}),
hasPrivateData: function hasPrivateData(command) {
for (let [cmd, args] in this.subCommands(command))
if (cmd.privateData)
- return !callable(cmd.privateData) || cmd.privateData(args);
+ return !callable(cmd.privateData) ? cmd.privateData
+ : cmd.privateData(args);
return false;
},
}
},
- nameRegexp: util.regexp(<![CDATA[
+ nameRegexp: util.regexp(literal(/*
[^
0-9
<forbid>
]
[^ <forbid> ]*
- ]]>, "gx", {
- forbid: util.regexp(String.replace(<![CDATA[
+ */), "gx", {
+ forbid: util.regexp(String.replace(literal(/*
U0000-U002c // U002d -
U002e-U002f
U003a-U0040 // U0041-U005a a-z
Ufe70-Ufeff // Arabic Presentation Forms-B
Uff00-Uffef // Halfwidth and Fullwidth Forms
Ufff0-Uffff // Specials
- ]]>, /U/g, "\\u"), "x")
+ */), /U/g, "\\u"), "x")
}),
validName: Class.Memoize(function validName() util.regexp("^" + this.nameRegexp.source + "$")),
- commandRegexp: Class.Memoize(function commandRegexp() util.regexp(<![CDATA[
+ commandRegexp: Class.Memoize(function commandRegexp() util.regexp(literal(/*
^
(?P<spec>
(?P<prespace> [:\s]*)
(?:. | \n)*?
)?
$
- ]]>, "x", {
+ */), "x", {
name: this.nameRegexp
})),
iterate: function (args) commands.iterator().map(function (cmd) ({
__proto__: cmd,
columns: [
- cmd.hive == commands.builtin ? "" : <span highlight="Object" style="padding-right: 1em;">{cmd.hive.name}</span>
+ cmd.hive == commands.builtin ? "" : ["span", { highlight: "Object", style: "padding-right: 1em;" },
+ cmd.hive.name]
]
})),
iterateIndex: function (args) let (tags = help.tags)
}
});
-(function () {
-
- Commands.quoteMap = {
- "\n": "\\n",
- "\t": "\\t",
- };
- function quote(q, list, map) {
- map = map || Commands.quoteMap;
- let re = RegExp("[" + list + "]", "g");
- function quote(str) q + String.replace(str, re, function ($0) $0 in map ? map[$0] : ("\\" + $0)) + q;
- quote.list = list;
- return quote;
- };
-
- Commands.quoteArg = {
- '"': quote('"', '\n\t"\\\\'),
- "'": quote("'", "'", { "'": "''" }),
- "": quote("", "|\\\\\\s'\"")
- };
- Commands.complQuote = {
- '"': ['"', quote("", Commands.quoteArg['"'].list), '"'],
- "'": ["'", quote("", Commands.quoteArg["'"].list), "'"],
- "": ["", Commands.quoteArg[""], ""]
- };
-
- Commands.parseBool = function (arg) {
- if (/^(true|1|on)$/i.test(arg))
- return true;
- if (/^(false|0|off)$/i.test(arg))
- return false;
- return NaN;
- };
-})();
+let quote = function quote(q, list, map) {
+ map = map || Commands.quoteMap;
+ let re = RegExp("[" + list + "]", "g");
+ function quote(str) q + String.replace(str, re, function ($0) $0 in map ? map[$0] : ("\\" + $0)) + q;
+ quote.list = list;
+ return quote;
+};
+
+Commands.quoteMap = {
+ "\n": "\\n",
+ "\t": "\\t",
+};
+
+Commands.quoteArg = {
+ '"': quote('"', '\n\t"\\\\'),
+ "'": quote("'", "'", { "'": "''" }),
+ "": quote("", "|\\\\\\s'\"")
+};
+Commands.complQuote = {
+ '"': ['"', quote("", Commands.quoteArg['"'].list), '"'],
+ "'": ["'", quote("", Commands.quoteArg["'"].list), "'"],
+ "": ["", Commands.quoteArg[""], ""]
+};
+
+Commands.parseBool = function (arg) {
+ if (/^(true|1|on)$/i.test(arg))
+ return true;
+ if (/^(false|0|off)$/i.test(arg))
+ return false;
+ return NaN;
+};
endModule();