]> git.donarmstrong.com Git - dactyl.git/blobdiff - common/modules/options.jsm
Imported Upstream version 1.1+hg7904
[dactyl.git] / common / modules / options.jsm
index 77439afe11273f8c0c7a6513efd7d1ed204d45f9..302a1d3400abd40c711470f66dfa84262083566e 100644 (file)
@@ -1,6 +1,6 @@
 // Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
 // Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
-// Copyright (c) 2008-2013 by Kris Maglione <maglione.k@gmail.com>
+// Copyright (c) 2008-2014 by Kris Maglione <maglione.k@gmail.com>
 //
 // This work is licensed for reuse under an MIT license. Details are
 // given in the LICENSE.txt file included with this file.
@@ -65,7 +65,7 @@ var Option = Class("Option", {
             this.globalValue = this.defaultValue;
     },
 
-    magicalProperties: Set(["cleanupValue"]),
+    magicalProperties: RealSet(["cleanupValue"]),
 
     /**
      * @property {string} This option's description, as shown in :listoptions.
@@ -95,7 +95,9 @@ var Option = Class("Option", {
         return this.globalValue = this.defaultValue;
     },
     set globalValue(val) {
-        options.store.set(this.name, { value: val, time: Date.now() });
+        options.store.set(this.name,
+                          { value: this.parse(this.stringify(val)),
+                            time: Date.now() });
     },
 
     /**
@@ -107,6 +109,8 @@ var Option = Class("Option", {
      */
     parse: function parse(value) Option.dequote(value),
 
+    parseKey: function parseKey(value) value,
+
     /**
      * Returns *values* packed in the appropriate format for the option type.
      *
@@ -140,6 +144,9 @@ var Option = Class("Option", {
         if ((scope & Option.SCOPE_GLOBAL) && (values == undefined))
             values = this.globalValue;
 
+        if (hasOwnProperty(this, "_value"))
+            values = this._value;
+
         if (this.getter)
             return util.trapErrors(this.getter, this, values);
 
@@ -169,6 +176,7 @@ var Option = Class("Option", {
         */
         if ((scope & Option.SCOPE_GLOBAL) && !skipGlobal)
             this.globalValue = newValues;
+        this._value = newValues;
 
         this.hasChanged = true;
         this.setFrom = null;
@@ -329,7 +337,7 @@ var Option = Class("Option", {
         let defaultValue = this._defaultValue;
         delete this._defaultValue;
 
-        if (Set.has(this.modules.config.optionDefaults, this.name))
+        if (hasOwnProperty(this.modules.config.optionDefaults, this.name))
             defaultValue = this.modules.config.optionDefaults[this.name];
 
         if (defaultValue == null && this.getter)
@@ -558,6 +566,11 @@ var Option = Class("Option", {
             }, this))
     },
 
+    parseKey: {
+        number: Number,
+        boolean: function boolean(value) value == "true" || value == true ? true : false,
+    },
+
     testValues: {
         regexpmap:  function regexpmap(vals, validator) vals.every(re => validator(re.result)),
         get sitemap() this.regexpmap,
@@ -671,8 +684,8 @@ var Option = Class("Option", {
             values = Array.concat(values);
 
             function uniq(ary) {
-                let seen = {};
-                return ary.filter(elem => !Set.add(seen, elem));
+                let seen = RealSet();
+                return ary.filter(elem => !seen.add(elem));
             }
 
             switch (operator) {
@@ -682,11 +695,11 @@ var Option = Class("Option", {
                 // NOTE: Vim doesn't prepend if there's a match in the current value
                 return uniq(Array.concat(values, this.value), true);
             case "-":
-                return this.value.filter(function (item) !Set.has(this, item), Set(values));
+                return this.value.filter(function (item) !this.has(item), RealSet(values));
             case "=":
                 if (invert) {
-                    let keepValues = this.value.filter(function (item) !Set.has(this, item), Set(values));
-                    let addValues  = values.filter(function (item) !Set.has(this, item), Set(this.value));
+                    let keepValues = this.value.filter(function (item) !this.has(item), RealSet(values));
+                    let addValues  = values.filter(function (item) !this.has(item), RealSet(this.value));
                     return addValues.concat(keepValues);
                 }
                 return values;
@@ -723,7 +736,9 @@ var Option = Class("Option", {
         if (isObject(vals) && !isArray(vals)) {
             let k = values(completions.call(this, { values: {} })).toObject();
             let v = values(completions.call(this, { value: "" })).toObject();
-            return Object.keys(vals).every(Set.has(k)) && values(vals).every(Set.has(v));
+
+            return Object.keys(vals).every(hasOwnProperty.bind(null, k)) &&
+                   values(vals).every(hasOwnProperty.bind(null, v));
         }
 
         if (this.values)
@@ -732,12 +747,15 @@ var Option = Class("Option", {
             acceptable = completions.call(this);
 
         if (isArray(acceptable))
-            acceptable = Set(acceptable.map(([k]) => (k)));
+            acceptable = RealSet(acceptable.map(([k]) => k));
+        else
+            acceptable = RealSet(this.parseKey(k)
+                                 for (k of Object.keys(acceptable)));
 
         if (this.type === "regexpmap" || this.type === "sitemap")
-            return Array.concat(vals).every(re => Set.has(acceptable, re.result));
+            return Array.concat(vals).every(re => acceptable.has(re.result));
 
-        return Array.concat(vals).every(Set.has(acceptable));
+        return Array.concat(vals).every(v => acceptable.has(v));
     },
 
     types: {}
@@ -766,6 +784,9 @@ var Option = Class("Option", {
     if (type in Option.parse)
         class_.prototype.parse = Option.parse[type];
 
+    if (type in Option.parseKey)
+        class_.prototype.parseKey = Option.parse[type];
+
     if (type in Option.stringify)
         class_.prototype.stringify = Option.stringify[type];
 
@@ -789,7 +810,7 @@ var OptionHive = Class("OptionHive", Contexts.Hive, {
     init: function init(group) {
         init.supercall(this, group);
         this.values = {};
-        this.has = Set.has(this.values);
+        this.has = v => hasOwnProperty(this.values, v);
     },
 
     add: function add(names, description, type, defaultValue, extraInfo) {
@@ -822,17 +843,18 @@ var Options = Module("options", {
                     opt.set(opt.globalValue, Option.SCOPE_GLOBAL, true);
             }, window);
 
-            modules.cache.register("options.dtd", () =>
-                util.makeDTD(
-                    iter(([["option", o.name, "default"].join("."),
-                           o.type === "string" ? o.defaultValue.replace(/'/g, "''") :
-                           o.defaultValue === true  ? "on"  :
-                           o.defaultValue === false ? "off" : o.stringDefaultValue]
-                          for (o in self)),
+            modules.cache.register("options.dtd",
+                () => util.makeDTD(
+                        iter(([["option", o.name, "default"].join("."),
+                               o.type === "string" ? o.defaultValue.replace(/'/g, "''") :
+                               o.defaultValue === true  ? "on"  :
+                               o.defaultValue === false ? "off" : o.stringDefaultValue]
+                              for (o in self)),
 
-                         ([["option", o.name, "type"].join("."), o.type] for (o in self)),
+                             ([["option", o.name, "type"].join("."), o.type] for (o in self)),
 
-                         config.dtd)));
+                             config.dtd)),
+                true);
         },
 
         signals: {
@@ -1098,13 +1120,13 @@ var Options = Module("options", {
 
             let list = [];
             function flushList() {
-                let names = Set(list.map(opt => opt.option ? opt.option.name : ""));
+                let names = RealSet(list.map(opt => opt.option ? opt.option.name : ""));
                 if (list.length)
                     if (list.some(opt => opt.all))
                         options.list(opt => !(list[0].onlyNonDefault && opt.isDefault),
                                      list[0].scope);
                     else
-                        options.list(opt => Set.has(names, opt.name),
+                        options.list(opt => names.has(opt.name),
                                      list[0].scope);
                 list = [];
             }
@@ -1279,12 +1301,12 @@ var Options = Module("options", {
 
             // Fill in the current values if we're removing
             if (opt.operator == "-" && isArray(opt.values)) {
-                let have = Set([i.text for (i in values(context.allItems.items))]);
+                let have = RealSet((i.text for (i in values(context.allItems.items))));
                 context = context.fork("current-values", 0);
                 context.anchored = optcontext.anchored;
                 context.maxItems = optcontext.maxItems;
 
-                context.filters.push(i => !Set.has(have, i.text));
+                context.filters.push(i => !have.has(i.text));
                 modules.completion.optionValue(context, opt.name, opt.operator, null,
                                        function (context) {
                                            context.generate = () => option.value.map(o => [o, ""]);
@@ -1313,7 +1335,7 @@ var Options = Module("options", {
 
                     util.assert(scope == "g:" || scope == null,
                                 _("command.let.illegalVar", scope + name));
-                    util.assert(Set.has(globalVariables, name) || (expr && !op),
+                    util.assert(hasOwnProperty(globalVariables, name) || (expr && !op),
                                 _("command.let.undefinedVar", fullName));
 
                     if (!expr)
@@ -1411,7 +1433,7 @@ var Options = Module("options", {
             function (args) {
                 for (let [, name] in args) {
                     name = name.replace(/^g:/, ""); // throw away the scope prefix
-                    if (!Set.has(dactyl._globalVariables, name)) {
+                    if (!hasOwnProperty(dactyl._globalVariables, name)) {
                         if (!args.bang)
                             dactyl.echoerr(_("command.let.noSuch", name));
                         return;
@@ -1493,11 +1515,10 @@ var Options = Module("options", {
 
             function val(obj) {
                 if (isArray(opt.defaultValue)) {
-                    let val = array.nth(obj, re => (re.key == extra.key),
-                                        0);
+                    let val = [].find.call(obj, re => (re.key == extra.key));
                     return val && val.result;
                 }
-                if (Set.has(opt.defaultValue, extra.key))
+                if (hasOwnProperty(opt.defaultValue, extra.key))
                     return obj[extra.key];
             }