summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKris Maglione <maglione.k@gmail.com>2011-02-10 21:36:03 -0500
committerKris Maglione <maglione.k@gmail.com>2011-02-10 21:36:03 -0500
commit30e29714247c58dc011bbf69a31cef9450fb8f9d (patch)
tree5f0f8f4b47e783d4a06cdb8ad736b9d405a32b27
parent56a28ec0faa3fc5dc218fece57fed1c6d6463d5e (diff)
downloadpentadactyl-30e29714247c58dc011bbf69a31cef9450fb8f9d.tar.gz
Experimentally move contexts.js to contexts.jsm.
--HG-- branch : groups rename : common/content/contexts.js => common/modules/contexts.jsm
-rw-r--r--common/content/autocommands.js12
-rw-r--r--common/content/events.js16
-rw-r--r--common/content/mappings.js39
-rw-r--r--common/modules/base.jsm3
-rw-r--r--common/modules/commands.jsm252
-rw-r--r--common/modules/contexts.jsm (renamed from common/content/contexts.js)380
-rw-r--r--common/modules/io.jsm6
-rw-r--r--common/modules/overlay.jsm4
-rw-r--r--common/modules/styles.jsm10
-rw-r--r--common/modules/util.jsm5
10 files changed, 401 insertions, 326 deletions
diff --git a/common/content/autocommands.js b/common/content/autocommands.js
index e24d2e6e..c5357fe1 100644
--- a/common/content/autocommands.js
+++ b/common/content/autocommands.js
@@ -17,7 +17,7 @@ update(AutoCommand.prototype, {
}
});
-var AutoCmdHive = Class("AutoCmdHive", Group.Hive, {
+var AutoCmdHive = Class("AutoCmdHive", Contexts.Hive, {
init: function init(group) {
init.supercall(this, group);
this._store = [];
@@ -69,12 +69,14 @@ var AutoCmdHive = Class("AutoCmdHive", Group.Hive, {
*/
var AutoCommands = Module("autocommands", {
init: function () {
- this.user = contexts.hives.autocmd.user;
+ update(this, {
+ hives: contexts.Hives("autocmd", AutoCmdHive),
+ user: contexts.hives.autocmd.user
+ });
},
- hives: Group.Hives("autocmd", AutoCmdHive),
-
- get activeHives() contexts.activeGroups("autocmd").map(function (h) h.autocmd).filter(function (h) h._store.length),
+ get activeHives() contexts.initializedGroups("autocmd")
+ .filter(function (h) h._store.length),
add: deprecated("autocommand.user.add", { get: function add() autocommands.user.closure.add }),
get: deprecated("autocommand.user.get", { get: function get() autocommands.user.closure.get }),
diff --git a/common/content/events.js b/common/content/events.js
index de6a65aa..dbbb0f34 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -255,7 +255,7 @@ var KeyArgProcessor = Class("KeyArgProcessor", KeyProcessor, {
}
});
-var EventHive = Class("EventHive", Group.Hive, {
+var EventHive = Class("EventHive", Contexts.Hive, {
init: function init(group) {
init.supercall(this, group);
this.sessionListeners = [];
@@ -321,6 +321,14 @@ var Events = Module("events", {
init: function () {
const self = this;
+ update(this, {
+ hives: contexts.Hives("events", EventHive),
+ user: contexts.hives.events.user,
+ builtin: contexts.hives.events.builtin
+ });
+
+ EventHive.prototype.wrapListener = this.closure.wrapListener;
+
XML.ignoreWhitespace = true;
util.overlayWindow(window, {
append: <e4x xmlns={XUL}>
@@ -342,10 +350,6 @@ var Events = Module("events", {
this._macroKeys = [];
this._lastMacro = "";
- EventHive.prototype.wrapListener = this.closure.wrapListener;
- this.user = contexts.hives.events.user;
- this.builtin = contexts.hives.events.builtin;
-
this._macros = storage.newMap("macros", { privateData: true, store: true });
for (let [k, m] in this._macros)
if (isString(m))
@@ -411,8 +415,6 @@ var Events = Module("events", {
});
},
- hives: Group.Hives("events", EventHive),
-
/**
* Adds an event listener for this session and removes it on
* dactyl shutdown.
diff --git a/common/content/mappings.js b/common/content/mappings.js
index 86ff72ca..5ab10f3c 100644
--- a/common/content/mappings.js
+++ b/common/content/mappings.js
@@ -138,7 +138,7 @@ var Map = Class("Map", {
id: 0
});
-var MapHive = Class("MapHive", Group.Hive, {
+var MapHive = Class("MapHive", Contexts.Hive, {
init: function init(group) {
init.supercall(this, group);
this.stacks = {};
@@ -297,14 +297,10 @@ var MapHive = Class("MapHive", Group.Hive, {
*/
var Mappings = Module("mappings", {
init: function () {
- this.user = contexts.hives.mappings.user;
- this.builtin = contexts.hives.mappings.builtin;
},
repeat: Modes.boundProperty(),
- hives: Group.Hives("mappings", MapHive),
-
get allHives() contexts.allGroups.mappings,
get userHives() this.allHives.filter(function (h) h !== this.builtin, this),
@@ -436,7 +432,14 @@ var Mappings = Module("mappings", {
}
}, {
}, {
- commands: function () {
+ contexts: function initContexts(dactyl, modules, window) {
+ update(Mappings.prototype, {
+ hives: contexts.Hives("mappings", MapHive),
+ user: contexts.hives.mappings.user,
+ builtin: contexts.hives.mappings.builtin
+ });
+ },
+ commands: function initCommands(dactyl, modules, window) {
function addMapCommands(ch, mapmodes, modeDescription) {
function map(args, noremap) {
let mapmodes = array.uniq(args["-modes"].map(findMode));
@@ -454,7 +457,7 @@ var Mappings = Module("mappings", {
if (!rhs) // list the mapping
mappings.list(mapmodes, mappings.expandLeader(lhs), hives);
else {
- util.assert(args["-group"] !== mappings.builtin,
+ util.assert(args["-group"].modifiable,
"Cannot change mappings in the builtin group");
args["-group"].add(mapmodes, [lhs],
@@ -575,7 +578,7 @@ var Mappings = Module("mappings", {
commands.add([ch + "mapc[lear]"],
"Remove all mappings" + modeDescription,
function (args) {
- util.assert(args["-group"] !== mappings.builtin,
+ util.assert(args["-group"].modifiable,
"Cannot change mappings in the builtin group");
let mapmodes = array.uniq(args["-modes"].map(findMode));
@@ -599,7 +602,7 @@ var Mappings = Module("mappings", {
commands.add([ch + "unm[ap]"],
"Remove a mapping" + modeDescription,
function (args) {
- util.assert(args["-group"] !== mappings.builtin,
+ util.assert(args["-group"].modifiable,
"Cannot change mappings in the builtin group");
let mapmodes = array.uniq(args["-modes"].map(findMode));
@@ -668,6 +671,12 @@ var Mappings = Module("mappings", {
addMapCommands("", [modes.NORMAL, modes.VISUAL], "");
+ for (let mode in modes.mainModes)
+ if (mode.char && !commands.get(mode.char + "map", true))
+ addMapCommands(mode.char,
+ [m.mask for (m in modes.mainModes) if (m.char == mode.char)],
+ [mode.name.toLowerCase()]);
+
let args = {
getMode: function (args) findMode(args["-mode"]),
iterate: function (args) {
@@ -729,14 +738,8 @@ var Mappings = Module("mappings", {
options: []
});
});
-
- for (let mode in modes.mainModes)
- if (mode.char && !commands.get(mode.char + "map", true))
- addMapCommands(mode.char,
- [m.mask for (m in modes.mainModes) if (m.char == mode.char)],
- [mode.name.toLowerCase()]);
},
- completion: function () {
+ completion: function initCompletion(dactyl, modules, window) {
completion.userMapping = function userMapping(context, modes, hive) {
// FIXME: have we decided on a 'standard' way to handle this clash? --djk
hive = hive || mappings.user;
@@ -745,14 +748,14 @@ var Mappings = Module("mappings", {
context.completions = hive.iterate(modes);
};
},
- javascript: function () {
+ javascript: function initJavascript(dactyl, modules, window) {
JavaScript.setCompleter([mappings.get, mappings.builtin.get],
[
null,
function (context, obj, args) [[m.names, m.description] for (m in this.iterate(args[0]))]
]);
},
- options: function () {
+ options: function initOptions(dactyl, modules, window) {
options.add(["mapleader", "ml"],
"Define the replacement keys for the <Leader> pseudo-key",
"string", "\\", {
diff --git a/common/modules/base.jsm b/common/modules/base.jsm
index ea894b8c..56d86a3b 100644
--- a/common/modules/base.jsm
+++ b/common/modules/base.jsm
@@ -981,7 +981,8 @@ let StructBase = Class("StructBase", Array, {
}
}, {
fromArray: function (ary) {
- ary.__proto__ = this.prototype;
+ if (!(ary instanceof this))
+ ary.__proto__ = this.prototype;
return ary;
},
diff --git a/common/modules/commands.jsm b/common/modules/commands.jsm
index a7bfde9c..4f63fb64 100644
--- a/common/modules/commands.jsm
+++ b/common/modules/commands.jsm
@@ -11,12 +11,10 @@ try {
Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("commands", {
exports: ["ArgType", "Command", "Commands", "CommandOption", "Ex", "commands"],
+ require: ["contexts"],
use: ["config", "options", "template", "util"]
}, this);
-
-/** @scope modules */
-
/**
* A structure representing the options available for a command.
*
@@ -273,20 +271,20 @@ var Command = Class("Command", {
* @see Commands@parseArguments
*/
options: [],
+
optionMap: Class.memoize(function () array(this.options)
.map(function (opt) opt.names.map(function (name) [name, opt]))
.flatten().toObject()),
+
newArgs: function (base) {
let res = [];
update(res, base);
res.__proto__ = this.argsPrototype;
return res;
},
- argsPrototype: Class.memoize(function () update([],
- array(this.options).filter(function (opt) opt.default !== undefined)
- .map(function (opt) [opt.names[0], Class.Property(Object.getOwnPropertyDescriptor(opt, "default"))])
- .toObject(),
- {
+
+ argsPrototype: Class.memoize(function () {
+ let res = update([], {
__iterator__: function () array.iterItems(this),
command: this,
@@ -298,6 +296,7 @@ var Command = Class("Command", {
get literalArg() this.command.literal != null && this[this.command.literal] || "",
// TODO: string: Class.memoize(function () { ... }),
+
verify: function verify() {
if (this.command.argCount) {
util.assert((this.length > 0 || !/^[1+]$/.test(this.command.argCount)) &&
@@ -309,7 +308,18 @@ var Command = Class("Command", {
"E488: Trailing characters");
}
}
- })),
+ });
+
+ this.options.forEach(function (opt) {
+ if (opt.default !== undefined)
+ Object.defineProperty(res, opt.names[0],
+ Object.getOwnPropertyDescriptor(opt, "default") ||
+ { configurable: true, enumerable: true, get: function () opt.default });
+ });
+
+ return res;
+ }),
+
/**
* @property {boolean|function(args)} When true, invocations of this
* command may contain private data which should be purged from
@@ -416,6 +426,113 @@ var Ex = Module("Ex", {
__noSuchMethod__: function (meth, args) this._run(meth).apply(this, args)
});
+var CommandHive = Class("CommandHive", Contexts.Hive, {
+ init: function init(group) {
+ init.supercall(this, group);
+ this._map = {};
+ this._list = [];
+ },
+
+ /** @property {Iterator(Command)} @private */
+ __iterator__: function () array.iterValues(this._list.sort(function (a, b) a.name > b.name)),
+
+ /** @property {string} The last executed Ex command line. */
+ repeat: null,
+
+ /**
+ * Adds a new command.
+ *
+ * @param {string[]} names The names by which this command can be
+ * invoked. The first name specified is the command's canonical
+ * name.
+ * @param {string} description A description of the command.
+ * @param {function} action The action invoked by this command.
+ * @param {Object} extra An optional extra configuration hash.
+ * @optional
+ */
+ add: function (names, description, action, extra, replace) {
+ const { commands, contexts } = this.modules;
+
+ extra = extra || {};
+ if (!extra.definedAt)
+ extra.definedAt = contexts.getCaller(Components.stack.caller);
+
+ extra.hive = this;
+ extra.parsedSpecs = Command.parseSpecs(names);
+
+ let names = array.flatten(extra.parsedSpecs);
+ let name = names[0];
+
+ util.assert(!names.some(function (name) name in commands.builtin._map),
+ "E182: Can't replace non-user command: " + name);
+
+ util.assert(replace || names.every(function (name) !(name in this._map), this),
+ "Not replacing command " + name);
+
+ for (let name in values(names)) {
+ ex.__defineGetter__(name, function () this._run(name));
+ if (name in this._map)
+ this.remove(name);
+ }
+
+ let self = this;
+ let closure = function () self._map[name];
+
+ memoize(this._map, name, function () commands.Command(names, description, action, extra));
+ memoize(this._list, this._list.length, closure);
+ for (let alias in values(names.slice(1)))
+ memoize(this._map, alias, closure);
+
+ return name;
+ },
+
+ _add: function (names, description, action, extra, replace) {
+ const { contexts } = this.modules;
+
+ extra = extra || {};
+ extra.definedAt = contexts.getCaller(Components.stack.caller.caller);
+ return this.add.apply(this, arguments);
+ },
+
+ /**
+ * Clear all commands.
+ * @returns {Command}
+ */
+ clear: function clear() {
+ util.assert(this.group.modifiable, "Cannot delete non-user commands");
+ this._map = {};
+ this._list = [];
+ },
+
+ /**
+ * Returns the command with matching *name*.
+ *
+ * @param {string} name The name of the command to return. This can be
+ * any of the command's names.
+ * @param {boolean} full If true, only return a command if one of
+ * its names matches *name* exactly.
+ * @returns {Command}
+ */
+ get: function get(name, full) this._map[name]
+ || !full && array.nth(this._list, function (cmd) cmd.hasName(name), 0)
+ || null,
+
+ /**
+ * Remove the user-defined command with matching *name*.
+ *
+ * @param {string} name The name of the command to remove. This can be
+ * any of the command's names.
+ */
+ remove: function remove(name) {
+ util.assert(this.group.modifiable, "Cannot delete non-user commands");
+
+ let cmd = this.get(name);
+ this._list = this._list.filter(function (c) c !== cmd);
+ for (let name in values(cmd.names))
+ delete this._map[name];
+ }
+});
+
/**
* @instance commands
*/
@@ -425,121 +542,17 @@ var Commands = Module("commands", {
Local: function Local(dactyl, modules, window) let ({ Group, contexts } = modules) ({
init: function () {
this.Command = Class("Command", Command, { modules: modules });
- this.user = contexts.hives.commands.user;
- this.builtin = contexts.hives.commands.builtin;
+ update(this, {
+ hives: contexts.Hives("commands", Class("CommandHive", CommandHive, { modules: modules })),
+ user: contexts.hives.commands.user,
+ builtin: contexts.hives.commands.builtin
+ });
},
get context() contexts.context,
get readHeredoc() modules.io.readHeredoc,
- hives: Group.Hives("commands", Class("CommandHive", Group.Hive, {
- init: function init(group) {
- init.supercall(this, group);
- this._map = {};
- this._list = [];
- },
-
- /** @property {Iterator(Command)} @private */
- __iterator__: function () array.iterValues(this._list.sort(function (a, b) a.name > b.name)),
-
- /** @property {string} The last executed Ex command line. */
- repeat: null,
-
- /**
- * Adds a new command.
- *
- * @param {string[]} names The names by which this command can be
- * invoked. The first name specified is the command's canonical
- * name.
- * @param {string} description A description of the command.
- * @param {function} action The action invoked by this command.
- * @param {Object} extra An optional extra configuration hash.
- * @optional
- */
- add: function (names, description, action, extra, replace) {
- const { commands } = modules;
-
- extra = extra || {};
- if (!extra.definedAt)
- extra.definedAt = contexts.getCaller(Components.stack.caller);
-
- extra.hive = this;
- extra.parsedSpecs = Command.parseSpecs(names);
-
- let names = array.flatten(extra.parsedSpecs);
- let name = names[0];
-
- util.assert(!names.some(function (name) name in commands.builtin._map),
- "E182: Can't replace non-user command: " + name);
-
- util.assert(replace || names.every(function (name) !(name in this._map), this),
- "Not replacing command " + name);
-
- for (let name in values(names)) {
- ex.__defineGetter__(name, function () this._run(name));
- if (name in this._map)
- this.remove(name);
- }
-
- let self = this;
- let closure = function () self._map[name];
-
- memoize(this._map, name, function () commands.Command(names, description, action, extra));
- memoize(this._list, this._list.length, closure);
- for (let alias in values(names.slice(1)))
- memoize(this._map, alias, closure);
-
- return name;
- },
-
- _add: function (names, description, action, extra, replace) {
- extra = extra || {};
- extra.definedAt = contexts.getCaller(Components.stack.caller.caller);
- return this.add.apply(this, arguments);
- },
-
- /**
- * Clear all commands.
- * @returns {Command}
- */
- clear: function clear() {
- util.assert(this.group !== contexts.default,
- "Cannot delete non-user commands");
- this._map = {};
- this._list = [];
- },
-
- /**
- * Returns the command with matching *name*.
- *
- * @param {string} name The name of the command to return. This can be
- * any of the command's names.
- * @param {boolean} full If true, only return a command if one of
- * its names matches *name* exactly.
- * @returns {Command}
- */
- get: function get(name, full) this._map[name]
- || !full && array.nth(this._list, function (cmd) cmd.hasName(name), 0)
- || null,
-
- /**
- * Remove the user-defined command with matching *name*.
- *
- * @param {string} name The name of the command to remove. This can be
- * any of the command's names.
- */
- remove: function remove(name) {
- util.assert(this.group !== contexts.default,
- "Cannot delete non-user commands");
-
- let cmd = this.get(name);
- this._list = this._list.filter(function (c) c !== cmd);
- for (let name in values(cmd.names))
- delete this._map[name];
- }
- })),
-
get allHives() contexts.allGroups.commands,
get userHives() this.allHives.filter(function (h) h !== this.builtin, this),
@@ -689,7 +702,8 @@ var Commands = Module("commands", {
let defaults = {};
if (args.ignoreDefaults)
- defaults = array(this.options).map(function (opt) [opt.names[0], opt.default]).toObject();
+ defaults = array(this.options).map(function (opt) [opt.names[0], opt.default])
+ .toObject();
for (let [opt, val] in Iterator(args.options || {})) {
if (val != null && defaults[opt] === val)
diff --git a/common/content/contexts.js b/common/modules/contexts.jsm
index caa5b8c5..98c130fa 100644
--- a/common/content/contexts.js
+++ b/common/modules/contexts.jsm
@@ -4,34 +4,45 @@
// given in the LICENSE.txt file included with this file.
"use strict";
+try {
+
+Components.utils.import("resource://dactyl/bootstrap.jsm");
+defineModule("contexts", {
+ exports: ["Contexts", "Group", "contexts"],
+ use: ["commands", "options", "services", "storage", "styles", "util"]
+}, this);
+
var Group = Class("Group", {
init: function init(name, description, filter, persist) {
const self = this;
+
this.name = name;
this.description = description;
- this.filter = filter || Group.defaultFilter;
+ this.filter = filter || this.constructor.defaultFilter;
this.persist = persist || false;
this.hives = [];
},
+ modifiable: true,
+
cleanup: function cleanup() {
for (let hive in values(this.hives))
- dactyl.trapErrors("cleanup", hive);
+ util.trapErrors("cleanup", hive);
this.hives = [];
- for (let hive in keys(Group.hiveMap))
+ for (let hive in keys(this.hiveMap))
delete this[hive];
},
destroy: function destroy() {
for (let hive in values(this.hives))
- dactyl.trapErrors("destroy", hive);
+ util.trapErrors("destroy", hive);
},
argsExtra: function argsExtra() ({}),
get toStringParams() [this.name],
- get builtin() contexts.builtinGroups.indexOf(this) >= 0,
+ get builtin() this.modules.contexts.builtinGroups.indexOf(this) >= 0,
}, {
compileFilter: function (patterns) {
@@ -44,7 +55,10 @@ var Group = Class("Group", {
return update(siteFilter, {
toString: function () this.filters.join(","),
- toXML: function () template.map(this.filters, function (f) <span highlight={f(buffer.uri) ? "Filter" : ""}>{f}</span>, <>,</>),
+ toXML: function (modules) let (uri = modules && modules.buffer.uri)
+ template.map(this.filters,
+ function (f) <span highlight={uri && f(uri) ? "Filter" : ""}>{f}</span>,
+ <>,</>),
filters: patterns.map(function (pattern) {
let [, res, filter] = /^(!?)(.*)/.exec(pattern);
@@ -57,93 +71,170 @@ var Group = Class("Group", {
});
},
- groupsProto: {},
+ defaultFilter: Class.memoize(function () this.compileFilter(["*"]))
+});
- defaultFilter: Class.memoize(function () this.compileFilter(["*"])),
+var Contexts = Module("contexts", {
+ Local: function Local(dactyl, modules, window) ({
+ init: function () {
+ const contexts = this;
+ this.modules = modules;
+
+ this.groupList = [];
+ this.groupMap = {};
+ this.groupsProto = {};
+ this.hives = {};
+ this.hiveProto = {};
+
+ this.user = this.addGroup("user", "User-defined items", null, true);
+ this.builtin = this.addGroup("builtin", "Builtin items");
+ this.builtinGroups = [this.builtin, this.user];
+ this.builtin.modifiable = false;
+
+ this.GroupFlag = Class("GroupFlag", CommandOption, {
+ init: function (name) {
+ this.name = name;
+
+ this.type = ArgType("group", function (group) {
+ return isString(group) ? contexts.getGroup(group, name)
+ : group[name];
+ });
+ },
- hiveMap: {},
+ get toStringParams() [this.name],
- Hive: Class("Hive", {
- init: function init(group) {
- this.group = group;
+ names: ["-group", "-g"],
+
+ description: "Group to which to add",
+
+ get default() (contexts.context && contexts.context.group || contexts.user)[this.name],
+
+ completer: function (context) modules.completion.group(context)
+ });
},
- cleanup: function cleanup() {},
- destroy: function destroy() {},
+ cleanup: function () {
+ for (let hive in values(this.groupList))
+ util.trapErrors("cleanup", hive);
+ },
- get argsExtra() this.group.argsExtra,
- get builtin() this.group.builtin,
+ destroy: function () {
+ for (let hive in values(this.groupList))
+ util.trapErrors("destroy", hive);
- get name() this.group.name,
- set name(val) this.group.name = val,
+ for (let plugin in values(plugins.contexts))
+ if (plugin.onUnload)
+ util.trapErrors("onUnload", plugin);
+ },
- get description() this.group.description,
- set description(val) this.group.description = val,
+ Group: Class("Group", Group, { modules: modules, get hiveMap() modules.contexts.hives }),
- get filter() this.group.filter,
- set filter(val) this.group.filter = val,
+ Hives: Class("Hives", Class.Property, {
+ init: function init(name, constructor) {
+ const { contexts } = modules;
+ const self = this;
- get persist() this.group.persist,
- set persist(val) this.group.persist = val,
+ if (this.Hive)
+ return {
+ enumerable: true,
- get toStringParams() [this.name]
+ get: function () array(contexts.groups[self.name])
+ };
+
+
+ this.Hive = constructor;
+ this.name = name;
+ memoize(contexts.Group.prototype, name, function () {
+ let group = constructor(this);
+ this.hives.push(group);
+ delete contexts.groups;
+ return group;
+ });
+
+ memoize(contexts.hives, name,
+ function () Object.create(Object.create(contexts.hiveProto,
+ { _hive: { value: name } })));
+
+ memoize(contexts.groupsProto, name,
+ function () [group[name] for (group in values(this.groups)) if (set.has(group, name))]);
+ },
+
+ get toStringParams() [this.name, this.Hive]
+ })
}),
- Hives: Class("Hives", Class.Property, {
- init: function init(name, constructor) {
- const self = this;
- if (this.Group)
- return {
- enumerable: true,
+ Context: function Context(file, group, args) {
+ const { contexts, io, newContext, plugins, userContext } = this.modules;
- get: function () array(contexts.groups[self.name])
- };
+ function Const(val) Class.Property({ enumerable: true, value: val });
+ let isPlugin = array.nth(io.getRuntimeDirectories("plugins"),
+ function (dir) dir.contains(file, true),
+ 0);
+ let isRuntime = array.nth(io.getRuntimeDirectories(""),
+ function (dir) dir.contains(file, true),
+ 0);
- this.Group = constructor;
- this.name = name;
- memoize(Group.prototype, name, function () {
- let group = constructor(this);
- this.hives.push(group);
- delete contexts.groups;
- return group;
- });
+ let self = set.has(plugins, file.path) && plugins[file.path];
+ if (self) {
+ if (set.has(self, "onUnload"))
+ self.onUnload();
+ }
+ else {
+ let name = isPlugin ? file.getRelativeDescriptor(isPlugin).replace(File.PATH_SEP, "-")
+ : file.leafName;
+
+ self = update(newContext.apply(null, args || [userContext]), {
+ NAME: Const(name.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase())),
+
+ PATH: Const(file.path),
- memoize(Group.hiveMap, name,
- function () Object.create(Object.create(contexts.hiveProto,
- { _hive: { value: name } })));
+ CONTEXT: Const(self),
- memoize(Group.groupsProto, name,
- function () [group[name] for (group in values(this.groups)) if (set.has(group, name))]);
+ unload: Const(function unload() {
+ if (plugins[this.NAME] === this || plugins[this.PATH] === this)
+ if (this.onUnload)
+ this.onUnload();
+
+ if (plugins[this.NAME] === this)
+ delete plugins[this.NAME];
+
+ if (plugins[this.PATH] === this)
+ delete plugins[this.PATH];
+
+ if (!this.GROUP.builtin)
+ contexts.removeGroup(this.GROUP);
+ })
+ });
+ Class.replaceProperty(plugins, file.path, self);
+
+ // This belongs elsewhere
+ if (isPlugin && args)
+ Object.defineProperty(plugins, self.NAME, {
+ configurable: true,
+ enumerable: true,
+ value: self
+ });
}
- })
-});
-plugins.contexts = {};
+ let path = isRuntime ? file.getRelativeDescriptor(isRuntime) : file.path;
+ let name = isRuntime ? path.replace(/^(plugin|color)s([\\\/])/, "$1$2") : "script-" + path;
-var Contexts = Module("contexts", {
- init: function () {
- this.groupList = [];
- this.groupMap = {};
- this.hiveProto = {};
-
- this.builtin = this.addGroup("builtin", "Builtin items");
- this.user = this.addGroup("user", "User-defined items", null, true);
- this.builtinGroups = [this.builtin, this.user];
- },
+ if (!group)
+ group = this.addGroup(commands.nameRegexp
+ .iterate(name.replace(/\.[^.]*$/, ""))
+ .join("-"),
+ "Script group for " + file.path,
+ null, false);
- cleanup: function () {
- for (let hive in values(this.groupList))
- dactyl.trapErrors("cleanup", hive);
- },
+ Class.replaceProperty(self, "GROUP", group);
+ Class.replaceProperty(self, "group", group);
- destroy: function () {
- for (let hive in values(this.groupList))
- dactyl.trapErrors("destroy", hive);
+ return plugins.contexts[file.path] = self;
+ },
- for (let plugin in values(plugins.contexts))
- if (plugin.onUnload)
- dactyl.trapErrors("onUnload", plugin);
+ Script: function Script(file, group) {
+ return this.Context(file, group, [this.modules.plugins, true]);
},
context: null,
@@ -165,34 +256,34 @@ var Contexts = Module("contexts", {
return frame;
},
- groups: Class.memoize(function () Object.create(Group.groupsProto, {
- groups: { value: this.activeGroups().filter(function (g) g.filter(buffer.uri)) }
+ groups: Class.memoize(function () Object.create(this.groupsProto, {
+ groups: { value: this.activeGroups() },
})),
- allGroups: Class.memoize(function () Object.create(Group.groupsProto, {
- groups: { value: this.activeGroups() }
+ allGroups: Class.memoize(function () Object.create(this.groupsProto, {
+ groups: { value: this.initializedGroups() }
})),
- activeGroups: function (hive)
+ activeGroups: function (hive) this.initializedGroups().filter(function (g) g.filter(this), this.modules.buffer.uri),
+
+ initializedGroups: function (hive)
let (need = hive ? [hive] : Object.keys(this.hives))
this.groupList.filter(function (group) need.some(function (name) set.has(group, name))),
- get hives() Group.hiveMap,
-
addGroup: function addGroup(name, description, filter, persist, replace) {
let group = this.getGroup(name);
if (group)
name = group.name;
if (!group) {
- group = Group(name, description, filter, persist);
+ group = this.Group(name, description, filter, persist);
this.groupList.unshift(group);
this.groupMap[name] = group;
this.hiveProto.__defineGetter__(name, function () group[this._hive]);
}
if (replace) {
- dactyl.trapErrors("cleanup", group);
+ util.trapErrors("cleanup", group);
if (description)
group.description = description;
if (filter)
@@ -213,12 +304,12 @@ var Contexts = Module("contexts", {
let group = this.getGroup(name);
- dactyl.assert(!group || !group.builtin, "Cannot remove builtin group");
+ util.assert(!group || !group.builtin, "Cannot remove builtin group");
if (group) {
name = group.name;
this.groupList.splice(this.groupList.indexOf(group), 1);
- dactyl.trapErrors("destroy", group);
+ util.trapErrors("destroy", group);
}
if (this.context && this.context.group === group)
@@ -242,6 +333,8 @@ var Contexts = Module("contexts", {
},
bindMacro: function (args, default_, params) {
+ const { dactyl, events } = this.modules;
+
let process = util.identity;
if (callable(params))
@@ -286,111 +379,59 @@ var Contexts = Module("contexts", {
return action;
},
- GroupFlag: function (name) ({
- names: ["-group", "-g"],
-
- description: "Group to which to add",
-
- type: ArgType("group", function (group) isString(group) ? contexts.getGroup(group, name) : group[name]),
-
- get default() (contexts.context && contexts.context.group || contexts.user)[name],
-
- completer: function (context) completion.group(context)
- }),
-
withContext: function withContext(defaults, callback, self)
this.withSavedValues(["context"], function () {
this.context = defaults && update({}, defaults);
return callback.call(self, this.context);
})
}, {
- Context: modules.Script = function Context(file, group, args) {
- function Const(val) Class.Property({ enumerable: true, value: val });
-
- let isPlugin = array.nth(io.getRuntimeDirectories("plugins"),
- function (dir) dir.contains(file, true),
- 0);
- let isRuntime = array.nth(io.getRuntimeDirectories(""),
- function (dir) dir.contains(file, true),
- 0);
-
- let self = set.has(plugins, file.path) && plugins[file.path];
- if (self) {
- if (set.has(self, "onUnload"))
- self.onUnload();
- }
- else {
- let name = isPlugin ? file.getRelativeDescriptor(isPlugin).replace(File.PATH_SEP, "-") : file.leafName;
-
- self = update(modules.newContext.apply(null, args || [userContext]), {
- NAME: Const(name.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase())),
-
- PATH: Const(file.path),
-
- CONTEXT: Const(self),
-
- unload: Const(function unload() {
- if (plugins[this.NAME] === this || plugins[this.PATH] === this)
- if (this.onUnload)
- this.onUnload();
+ Hive: Class("Hive", {
+ init: function init(group) {
+ this.group = group;
+ },
- if (plugins[this.NAME] === this)
- delete plugins[this.NAME];
+ cleanup: function cleanup() {},
+ destroy: function destroy() {},
- if (plugins[this.PATH] === this)
- delete plugins[this.PATH];
+ get modifiable() this.group.modifiable,
- if (!this.GROUP.builtin)
- contexts.removeGroup(this.GROUP);
- })
- });
- Class.replaceProperty(plugins, file.path, self);
+ get argsExtra() this.group.argsExtra,
+ get builtin() this.group.builtin,
- // This belongs elsewhere
- if (isPlugin && args)
- Object.defineProperty(plugins, self.NAME, {
- configurable: true,
- enumerable: true,
- value: self
- });
- }
+ get name() this.group.name,
+ set name(val) this.group.name = val,
- let path = isRuntime ? file.getRelativeDescriptor(isRuntime) : file.path;
+ get description() this.group.description,
+ set description(val) this.group.description = val,
- if (!group)
- group = contexts.addGroup((isRuntime ? "" : "script-") +
- commands.nameRegexp.iterate(path.replace(/\.[^.]*$/, ""))
- .join("-"),
- "Script group for " + file.path,
- null, false);
+ get filter() this.group.filter,
+ set filter(val) this.group.filter = val,
- Class.replaceProperty(self, "GROUP", group);
- Class.replaceProperty(self, "group", group);
+ get persist() this.group.persist,
+ set persist(val) this.group.persist = val,
- return plugins.contexts[file.path] = self;
- },
- Script: function Script(file, group) {
- return this.Context(file, group, [plugins, true]);
- }
+ get toStringParams() [this.name]
+ })
}, {
- commands: function initCommands() {
+ commands: function initCommands(dactyl, modules, window) {
+ const { commands, contexts } = modules;
commands.add(["gr[oup]"],
"Create or select a group",
function (args) {
if (args.length > 0) {
var name = Option.dequote(args[0]);
- dactyl.assert(name !== "builtin", "Cannot modify builtin group");
- dactyl.assert(commands.validName.test(name), "Invalid group name");
+ util.assert(name !== "builtin", "Cannot modify builtin group");
+ util.assert(commands.validName.test(name), "Invalid group name");
var group = contexts.getGroup(name);
}
else if (args.bang)
var group = args.context && args.context.group;
else
- return void completion.listCompleter("group", "", null, null);
+ return void modules.completion.listCompleter("group", "", null, null);
- dactyl.assert(group || name, "No current group");
+ util.assert(group || name, "No current group");
let filter = Group.compileFilter(args["-locations"]);
if (!group || args.bang)
@@ -418,7 +459,7 @@ var Contexts = Module("contexts", {
bang: true,
completer: function (context, args) {
if (args.length == 1)
- completion.group(context);
+ modules.completion.group(context);
},
keepQuotes: true,
options: [
@@ -460,7 +501,7 @@ var Contexts = Module("contexts", {
arguments: [group.name],
ignoreDefaults: true
}
- for (group in values(contexts.activeGroups()))
+ for (group in values(contexts.initializedGroups()))
if (!group.builtin && group.persist)
].concat([{ command: this.name, arguments: ["user"] }])
});
@@ -468,13 +509,13 @@ var Contexts = Module("contexts", {
commands.add(["delg[roup]"],
"Delete a group",
function (args) {
- dactyl.assert(contexts.getGroup(args[0]), "No such group: " + args[0]);
+ util.assert(contexts.getGroup(args[0]), "No such group: " + args[0]);
contexts.removeGroup(args[0]);
},
{
argCount: "1",
completer: function (context, args) {
- completion.group(context);
+ modules.completion.group(context);
context.filters.push(function ({ item }) !item.builtin);
}
});
@@ -483,7 +524,7 @@ var Contexts = Module("contexts", {
commands.add(["fini[sh]"],
"Stop sourcing a script file",
function (args) {
- dactyl.assert(args.context, "E168: :finish used outside of a sourced file");
+ util.assert(args.context, "E168: :finish used outside of a sourced file");
args.context.finished = true;
},
{ argCount: "0" });
@@ -545,16 +586,18 @@ var Contexts = Module("contexts", {
argCount: "0"
});
},
- completion: function initCompletion() {
+ completion: function initCompletion(dactyl, modules, window) {
+ const { completion, contexts } = modules;
+
completion.group = function group(context, active) {
context.title = ["Group"];
- let uri = buffer.uri;
+ let uri = modules.buffer.uri;
context.keys = {
active: function (group) group.filter(uri),
text: "name",
- description: function (g) <>{g.filter.toXML ? g.filter.toXML() + <>&#xa0;</> : ""}{g.description || ""}</>
+ description: function (g) <>{g.filter.toXML ? g.filter.toXML(modules) + <>&#xa0;</> : ""}{g.description || ""}</>
};
- context.completions = (active === undefined ? contexts.groupList : contexts.activeGroups(active))
+ context.completions = (active === undefined ? contexts.groupList : contexts.initializedGroups(active))
.slice(0, -1);
iter({ Active: true, Inactive: false }).forEach(function ([name, active]) {
@@ -567,3 +610,8 @@ var Contexts = Module("contexts", {
}
});
+endModule();
+
+} catch(e){ if (!e.stack) e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
+
+// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
diff --git a/common/modules/io.jsm b/common/modules/io.jsm
index bb52400c..585b8e63 100644
--- a/common/modules/io.jsm
+++ b/common/modules/io.jsm
@@ -145,7 +145,7 @@ var IO = Module("io", {
* silent: Whether errors should not be reported.
*/
source: function source(filename, params) {
- const { Contexts, contexts } = modules;
+ const { contexts } = modules;
defineModule.loadLog.push("sourcing " + filename);
params = params || {};
@@ -167,7 +167,7 @@ var IO = Module("io", {
// handle pure JavaScript files specially
if (/\.js$/.test(filename)) {
try {
- var context = Contexts.Script(file, params.group);
+ var context = contexts.Script(file, params.group);
dactyl.loadScript(uri.spec, context);
dactyl.helpInitialized = false;
}
@@ -186,7 +186,7 @@ var IO = Module("io", {
else if (/\.css$/.test(filename))
styles.registerSheet(uri.spec, false, true);
else {
- context = Contexts.Context(file, params.group);
+ context = contexts.Context(file, params.group);
modules.commands.execute(file.read(), null, params.silent,
null, {
context: context,
diff --git a/common/modules/overlay.jsm b/common/modules/overlay.jsm
index c878c724..fe8ea1fd 100644
--- a/common/modules/overlay.jsm
+++ b/common/modules/overlay.jsm
@@ -157,6 +157,7 @@ var Overlay = Module("Overlay", {
"commands",
"completion",
"config",
+ "contexts",
"downloads",
"finder",
"highlight",
@@ -172,8 +173,7 @@ var Overlay = Module("Overlay", {
"util"
].forEach(function (name) defineModule.time("load", name, require, null, jsmodules, name));
- ["contexts",
- "dactyl",
+ ["dactyl",
"modes",
"commandline",
"abbreviations",
diff --git a/common/modules/styles.jsm b/common/modules/styles.jsm
index 245feccd..aee8f4c0 100644
--- a/common/modules/styles.jsm
+++ b/common/modules/styles.jsm
@@ -8,13 +8,13 @@ Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("styles", {
exports: ["Style", "Styles", "styles"],
require: ["services", "util"],
- use: ["template"]
+ use: ["contexts", "template"]
}, this);
function cssUri(css) "chrome-data:text/css," + encodeURI(css);
var namespace = "@namespace html " + XHTML.uri.quote() + ";\n" +
- "@namespace xul " + XUL.uri.quote() + ";\n" +
- "@namespace dactyl " + NS.uri.quote() + ";\n";
+ "@namespace xul " + XUL.uri.quote() + ";\n" +
+ "@namespace dactyl " + NS.uri.quote() + ";\n";
var Sheet = Struct("name", "id", "sites", "css", "hive", "agent");
Sheet.liveProperty = function (name) {
@@ -614,8 +614,8 @@ var Styles = Module("Styles", {
});
},
contexts: function (dactyl, modules, window) {
- modules.Group.Hives("styles",
- Class("LocalHive", modules.Group.Hive, {
+ modules.contexts.Hives("styles",
+ Class("LocalHive", Contexts.Hive, {
init: function init(group) {
init.superapply(this, arguments);
diff --git a/common/modules/util.jsm b/common/modules/util.jsm
index 18f7e83a..de87279a 100644
--- a/common/modules/util.jsm
+++ b/common/modules/util.jsm
@@ -1405,6 +1405,9 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
}
catch (e) { dump(e + "\n"); }
}
+
+ // ctypes.open("libc.so.6").declare("kill", ctypes.default_abi, ctypes.void_t, ctypes.int, ctypes.int)(
+ // ctypes.open("libc.so.6").declare("getpid", ctypes.default_abi, ctypes.int)(), 2)
},
/**
@@ -1596,6 +1599,8 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
*/
trapErrors: function trapErrors(func, self) {
try {
+ if (isString(func))
+ func = self[func];
return func.apply(self || this, Array.slice(arguments, 2));
}
catch (e) {