]> git.donarmstrong.com Git - dactyl.git/blobdiff - common/modules/commands.jsm
Import r6923 from upstream hg supporting Firefox up to 22.0a1
[dactyl.git] / common / modules / commands.jsm
index eca375bfd65d502493183bbd545ff34a871f07ce..199cfff13eca5e0b999b0a74c6d1a77504d36661 100644 (file)
@@ -1,18 +1,21 @@
 // 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.
@@ -106,6 +109,7 @@ update(CommandOption, {
  * @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}
@@ -240,28 +244,41 @@ var Command = Class("Command", {
      * @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
@@ -269,6 +286,7 @@ var Command = Class("Command", {
      *     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
@@ -277,6 +295,7 @@ var Command = Class("Command", {
      *     key mappings or Ex command lines as arguments.
      */
     literal: null,
+
     /**
      * @property {Array} The options this command takes.
      * @see Commands@parseArguments
@@ -485,7 +504,7 @@ var CommandHive = Class("CommandHive", Contexts.Hive, {
         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");
 
@@ -750,38 +769,34 @@ var Commands = Module("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);
         }
     }),
 
@@ -900,7 +915,8 @@ var Commands = Module("commands", {
     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;
     },
 
@@ -1226,14 +1242,14 @@ var Commands = Module("commands", {
         }
     },
 
-    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
@@ -1256,12 +1272,12 @@ var Commands = Module("commands", {
             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]*)
@@ -1276,7 +1292,7 @@ var Commands = Module("commands", {
                 (?:. | \n)*?
             )?
             $
-        ]]>, "x", {
+        */), "x", {
             name: this.nameRegexp
         })),
 
@@ -1705,7 +1721,8 @@ var Commands = Module("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.name}</span>
+                    cmd.hive == commands.builtin ? "" : ["span", { highlight: "Object", style: "padding-right: 1em;" },
+                                                            cmd.hive.name]
                 ]
             })),
             iterateIndex: function (args) let (tags = help.tags)
@@ -1760,39 +1777,37 @@ var Commands = Module("commands", {
     }
 });
 
-(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();