mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-21 20:57:59 +01:00
Experimentally move commands.js and options.js to modules. Fix some bugs.
--HG-- branch : groups rename : common/content/commands.js => common/modules/commands.jsm rename : common/content/options.js => common/modules/options.jsm
This commit is contained in:
@@ -148,6 +148,23 @@ var Contexts = Module("contexts", {
|
|||||||
|
|
||||||
context: null,
|
context: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a frame object describing the currently executing
|
||||||
|
* command, if applicable, otherwise returns the passed frame.
|
||||||
|
*
|
||||||
|
* @param {nsIStackFrame} frame
|
||||||
|
*/
|
||||||
|
getCaller: function getCaller(frame) {
|
||||||
|
if (this.context && this.context.file)
|
||||||
|
return {
|
||||||
|
__proto__: frame,
|
||||||
|
filename: this.context.file[0] == "[" ? this.context.file
|
||||||
|
: services.io.newFileURI(File(this.context.file)).spec,
|
||||||
|
lineNumber: this.context.line
|
||||||
|
};
|
||||||
|
return frame;
|
||||||
|
},
|
||||||
|
|
||||||
groups: Class.memoize(function () Object.create(Group.groupsProto, {
|
groups: Class.memoize(function () Object.create(Group.groupsProto, {
|
||||||
groups: { value: this.activeGroups().filter(function (g) g.filter(buffer.uri)) }
|
groups: { value: this.activeGroups().filter(function (g) g.filter(buffer.uri)) }
|
||||||
})),
|
})),
|
||||||
@@ -216,8 +233,8 @@ var Contexts = Module("contexts", {
|
|||||||
getGroup: function getGroup(name, hive) {
|
getGroup: function getGroup(name, hive) {
|
||||||
if (name === "default")
|
if (name === "default")
|
||||||
var group = this.context && this.context.context && this.context.context.GROUP;
|
var group = this.context && this.context.context && this.context.context.GROUP;
|
||||||
else
|
else if (set.has(this.groupMap, name))
|
||||||
group = set.has(this.groupMap, name) && this.groupMap[name];
|
group = this.groupMap[name];
|
||||||
|
|
||||||
if (group && hive)
|
if (group && hive)
|
||||||
return group[hive];
|
return group[hive];
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ var MapHive = Class("MapHive", Group.Hive, {
|
|||||||
extra = extra || {};
|
extra = extra || {};
|
||||||
|
|
||||||
let map = Map(modes, keys, description, action, extra);
|
let map = Map(modes, keys, description, action, extra);
|
||||||
map.definedAt = Commands.getCaller(Components.stack.caller);
|
map.definedAt = contexts.getCaller(Components.stack.caller);
|
||||||
map.hive = this;
|
map.hive = this;
|
||||||
|
|
||||||
if (this.name !== "builtin")
|
if (this.name !== "builtin")
|
||||||
@@ -341,7 +341,7 @@ var Mappings = Module("mappings", {
|
|||||||
*/
|
*/
|
||||||
add: function () {
|
add: function () {
|
||||||
let map = this.builtin.add.apply(this.builtin, arguments);
|
let map = this.builtin.add.apply(this.builtin, arguments);
|
||||||
map.definedAt = Commands.getCaller(Components.stack.caller);
|
map.definedAt = contexts.getCaller(Components.stack.caller);
|
||||||
return map;
|
return map;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -358,7 +358,7 @@ var Mappings = Module("mappings", {
|
|||||||
*/
|
*/
|
||||||
addUserMap: function () {
|
addUserMap: function () {
|
||||||
let map = this.user.add.apply(this.user, arguments);
|
let map = this.user.add.apply(this.user, arguments);
|
||||||
map.definedAt = Commands.getCaller(Components.stack.caller);
|
map.definedAt = contexts.getCaller(Components.stack.caller);
|
||||||
return map;
|
return map;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -454,6 +454,9 @@ var Mappings = Module("mappings", {
|
|||||||
if (!rhs) // list the mapping
|
if (!rhs) // list the mapping
|
||||||
mappings.list(mapmodes, mappings.expandLeader(lhs), hives);
|
mappings.list(mapmodes, mappings.expandLeader(lhs), hives);
|
||||||
else {
|
else {
|
||||||
|
util.assert(args["-group"] !== mappings.builtin,
|
||||||
|
"Cannot change mappings in the builtin group");
|
||||||
|
|
||||||
args["-group"].add(mapmodes, [lhs],
|
args["-group"].add(mapmodes, [lhs],
|
||||||
args["-description"],
|
args["-description"],
|
||||||
contexts.bindMacro(args, "-keys", function (params) params),
|
contexts.bindMacro(args, "-keys", function (params) params),
|
||||||
@@ -572,6 +575,9 @@ var Mappings = Module("mappings", {
|
|||||||
commands.add([ch + "mapc[lear]"],
|
commands.add([ch + "mapc[lear]"],
|
||||||
"Remove all mappings" + modeDescription,
|
"Remove all mappings" + modeDescription,
|
||||||
function (args) {
|
function (args) {
|
||||||
|
util.assert(args["-group"] !== mappings.builtin,
|
||||||
|
"Cannot change mappings in the builtin group");
|
||||||
|
|
||||||
let mapmodes = array.uniq(args["-modes"].map(findMode));
|
let mapmodes = array.uniq(args["-modes"].map(findMode));
|
||||||
mapmodes.forEach(function (mode) {
|
mapmodes.forEach(function (mode) {
|
||||||
args["-group"].clear(mode);
|
args["-group"].clear(mode);
|
||||||
@@ -593,6 +599,9 @@ var Mappings = Module("mappings", {
|
|||||||
commands.add([ch + "unm[ap]"],
|
commands.add([ch + "unm[ap]"],
|
||||||
"Remove a mapping" + modeDescription,
|
"Remove a mapping" + modeDescription,
|
||||||
function (args) {
|
function (args) {
|
||||||
|
util.assert(args["-group"] !== mappings.builtin,
|
||||||
|
"Cannot change mappings in the builtin group");
|
||||||
|
|
||||||
let mapmodes = array.uniq(args["-modes"].map(findMode));
|
let mapmodes = array.uniq(args["-modes"].map(findMode));
|
||||||
|
|
||||||
let found = false;
|
let found = false;
|
||||||
|
|||||||
@@ -6,6 +6,15 @@
|
|||||||
// given in the LICENSE.txt file included with this file.
|
// 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"],
|
||||||
|
use: ["config", "options", "template", "util"]
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
|
||||||
/** @scope modules */
|
/** @scope modules */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,6 +150,8 @@ var Command = Class("Command", {
|
|||||||
* @param {Object} modifiers Any modifiers to be passed to {@link #action}.
|
* @param {Object} modifiers Any modifiers to be passed to {@link #action}.
|
||||||
*/
|
*/
|
||||||
execute: function (args, modifiers) {
|
execute: function (args, modifiers) {
|
||||||
|
const { dactyl } = this.modules;
|
||||||
|
|
||||||
let context = args.context;
|
let context = args.context;
|
||||||
if (this.deprecated && !set.add(this.complained, context ? context.file : "[Command Line]")) {
|
if (this.deprecated && !set.add(this.complained, context ? context.file : "[Command Line]")) {
|
||||||
let loc = contexts.context ? context.file + ":" + context.line + ": " : "";
|
let loc = contexts.context ? context.file + ":" + context.line + ": " : "";
|
||||||
@@ -190,7 +201,7 @@ var Command = Class("Command", {
|
|||||||
* @returns {Args}
|
* @returns {Args}
|
||||||
* @see Commands#parseArgs
|
* @see Commands#parseArgs
|
||||||
*/
|
*/
|
||||||
parseArgs: function (args, complete, extra) commands.parseArgs(args, {
|
parseArgs: function parseArgs(args, complete, extra) this.modules.commands.parseArgs(args, {
|
||||||
__proto__: this,
|
__proto__: this,
|
||||||
complete: complete,
|
complete: complete,
|
||||||
extra: extra
|
extra: extra
|
||||||
@@ -265,8 +276,9 @@ var Command = Class("Command", {
|
|||||||
optionMap: Class.memoize(function () array(this.options)
|
optionMap: Class.memoize(function () array(this.options)
|
||||||
.map(function (opt) opt.names.map(function (name) [name, opt]))
|
.map(function (opt) opt.names.map(function (name) [name, opt]))
|
||||||
.flatten().toObject()),
|
.flatten().toObject()),
|
||||||
newArgs: function () {
|
newArgs: function (base) {
|
||||||
let res = [];
|
let res = [];
|
||||||
|
update(res, base);
|
||||||
res.__proto__ = this.argsPrototype;
|
res.__proto__ = this.argsPrototype;
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
@@ -279,8 +291,6 @@ var Command = Class("Command", {
|
|||||||
|
|
||||||
command: this,
|
command: this,
|
||||||
|
|
||||||
get context() contexts.context,
|
|
||||||
|
|
||||||
explicitOpts: Class.memoize(function () ({})),
|
explicitOpts: Class.memoize(function () ({})),
|
||||||
|
|
||||||
has: function (opt) set.has(this.explicitOpts, opt) || typeof opt === "number" && set.has(this, opt),
|
has: function (opt) set.has(this.explicitOpts, opt) || typeof opt === "number" && set.has(this, opt),
|
||||||
@@ -290,11 +300,11 @@ var Command = Class("Command", {
|
|||||||
// TODO: string: Class.memoize(function () { ... }),
|
// TODO: string: Class.memoize(function () { ... }),
|
||||||
verify: function verify() {
|
verify: function verify() {
|
||||||
if (this.command.argCount) {
|
if (this.command.argCount) {
|
||||||
dactyl.assert((this.length > 0 || !/^[1+]$/.test(this.command.argCount)) &&
|
util.assert((this.length > 0 || !/^[1+]$/.test(this.command.argCount)) &&
|
||||||
(this.literal == null || !/[1+]/.test(this.command.argCount) || /\S/.test(this.literalArg || "")),
|
(this.literal == null || !/[1+]/.test(this.command.argCount) || /\S/.test(this.literalArg || "")),
|
||||||
"E471: Argument required");
|
"E471: Argument required");
|
||||||
|
|
||||||
dactyl.assert((this.length == 0 || this.command.argCount !== "0") &&
|
util.assert((this.length == 0 || this.command.argCount !== "0") &&
|
||||||
(this.length <= 1 || !/^[01?]$/.test(this.command.argCount)),
|
(this.length <= 1 || !/^[01?]$/.test(this.command.argCount)),
|
||||||
"E488: Trailing characters");
|
"E488: Trailing characters");
|
||||||
}
|
}
|
||||||
@@ -352,11 +362,16 @@ var Command = Class("Command", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Prototype.
|
// Prototype.
|
||||||
var ex = {
|
var Ex = Module("Ex", {
|
||||||
|
Local: function Local(dactyl, modules, window) ({
|
||||||
|
get commands() modules.commands,
|
||||||
|
get context() modules.contexts.context
|
||||||
|
}),
|
||||||
|
|
||||||
_args: function (cmd, args) {
|
_args: function (cmd, args) {
|
||||||
args = Array.slice(args);
|
args = Array.slice(args);
|
||||||
|
|
||||||
let res = cmd.newArgs();
|
let res = cmd.newArgs({ context: this.context });
|
||||||
if (isObject(args[0]))
|
if (isObject(args[0]))
|
||||||
for (let [k, v] in Iterator(args.shift()))
|
for (let [k, v] in Iterator(args.shift()))
|
||||||
if (k == "!")
|
if (k == "!")
|
||||||
@@ -366,7 +381,7 @@ var ex = {
|
|||||||
else {
|
else {
|
||||||
let opt = cmd.optionMap["-" + k];
|
let opt = cmd.optionMap["-" + k];
|
||||||
let val = opt.type && opt.type.parse(v);
|
let val = opt.type && opt.type.parse(v);
|
||||||
dactyl.assert(val != null && (typeof val !== "number" || !isNaN(val)),
|
util.assert(val != null && (typeof val !== "number" || !isNaN(val)),
|
||||||
"No such option: " + k);
|
"No such option: " + k);
|
||||||
Class.replaceProperty(args, opt.names[0], val);
|
Class.replaceProperty(args, opt.names[0], val);
|
||||||
args.explicitOpts[opt.names[0]] = val;
|
args.explicitOpts[opt.names[0]] = val;
|
||||||
@@ -376,31 +391,49 @@ var ex = {
|
|||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
_complete: function (cmd)
|
_complete: function (cmd) let (self = this)
|
||||||
function _complete(context, func, obj, args) {
|
function _complete(context, func, obj, args) {
|
||||||
args = ex._args(cmd, args);
|
args = self._args(cmd, args);
|
||||||
args.completeArg = args.length - 1;
|
args.completeArg = args.length - 1;
|
||||||
if (cmd.completer && args.length)
|
if (cmd.completer && args.length)
|
||||||
return cmd.completer(context, args);
|
return cmd.completer(context, args);
|
||||||
},
|
},
|
||||||
|
|
||||||
_run: function (name) {
|
_run: function (name) {
|
||||||
let cmd = commands.get(name);
|
const self = this;
|
||||||
dactyl.assert(cmd, "No such command");
|
let cmd = this.commands.get(name);
|
||||||
|
util.assert(cmd, "No such command");
|
||||||
|
|
||||||
return update(function exCommand(options) {
|
return update(function exCommand(options) {
|
||||||
let args = ex._args(cmd, arguments);
|
let args = self._args(cmd, arguments);
|
||||||
args.verify();
|
args.verify();
|
||||||
return cmd.execute(args);
|
return cmd.execute(args);
|
||||||
}, {
|
}, {
|
||||||
dactylCompleter: ex._complete(cmd)
|
dactylCompleter: self._complete(cmd)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
__noSuchMethod__: function (meth, args) this._run(meth).apply(this, args)
|
__noSuchMethod__: function (meth, args) this._run(meth).apply(this, args)
|
||||||
};
|
});
|
||||||
|
|
||||||
var CommandHive = Class("CommandHive", Group.Hive, {
|
/**
|
||||||
|
* @instance commands
|
||||||
|
*/
|
||||||
|
var Commands = Module("commands", {
|
||||||
|
lazyInit: true,
|
||||||
|
|
||||||
|
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;
|
||||||
|
},
|
||||||
|
|
||||||
|
get context() contexts.context,
|
||||||
|
|
||||||
|
get readHeredoc() modules.io.readHeredoc,
|
||||||
|
|
||||||
|
hives: Group.Hives("commands", Class("CommandHive", Group.Hive, {
|
||||||
init: function init(group) {
|
init: function init(group) {
|
||||||
init.supercall(this, group);
|
init.supercall(this, group);
|
||||||
this._map = {};
|
this._map = {};
|
||||||
@@ -425,9 +458,11 @@ var CommandHive = Class("CommandHive", Group.Hive, {
|
|||||||
* @optional
|
* @optional
|
||||||
*/
|
*/
|
||||||
add: function (names, description, action, extra, replace) {
|
add: function (names, description, action, extra, replace) {
|
||||||
|
const { commands } = modules;
|
||||||
|
|
||||||
extra = extra || {};
|
extra = extra || {};
|
||||||
if (!extra.definedAt)
|
if (!extra.definedAt)
|
||||||
extra.definedAt = Commands.getCaller(Components.stack.caller);
|
extra.definedAt = contexts.getCaller(Components.stack.caller);
|
||||||
|
|
||||||
extra.hive = this;
|
extra.hive = this;
|
||||||
extra.parsedSpecs = Command.parseSpecs(names);
|
extra.parsedSpecs = Command.parseSpecs(names);
|
||||||
@@ -435,10 +470,10 @@ var CommandHive = Class("CommandHive", Group.Hive, {
|
|||||||
let names = array.flatten(extra.parsedSpecs);
|
let names = array.flatten(extra.parsedSpecs);
|
||||||
let name = names[0];
|
let name = names[0];
|
||||||
|
|
||||||
dactyl.assert(!names.some(function (name) name in commands.builtin._map),
|
util.assert(!names.some(function (name) name in commands.builtin._map),
|
||||||
"E182: Can't replace non-user command: " + name);
|
"E182: Can't replace non-user command: " + name);
|
||||||
|
|
||||||
dactyl.assert(replace || names.every(function (name) !(name in this._map), this),
|
util.assert(replace || names.every(function (name) !(name in this._map), this),
|
||||||
"Not replacing command " + name);
|
"Not replacing command " + name);
|
||||||
|
|
||||||
for (let name in values(names)) {
|
for (let name in values(names)) {
|
||||||
@@ -450,19 +485,31 @@ var CommandHive = Class("CommandHive", Group.Hive, {
|
|||||||
let self = this;
|
let self = this;
|
||||||
let closure = function () self._map[name];
|
let closure = function () self._map[name];
|
||||||
|
|
||||||
memoize(this._map, name, function () Command(names, description, action, extra));
|
memoize(this._map, name, function () commands.Command(names, description, action, extra));
|
||||||
memoize(this._list, this._list.length, closure);
|
memoize(this._list, this._list.length, closure);
|
||||||
for (let alias in values(names.slice(1)))
|
for (let alias in values(names.slice(1)))
|
||||||
memoize(this._map, alias, closure);
|
memoize(this._map, alias, closure);
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
},
|
},
|
||||||
|
|
||||||
_add: function (names, description, action, extra, replace) {
|
_add: function (names, description, action, extra, replace) {
|
||||||
extra = extra || {};
|
extra = extra || {};
|
||||||
extra.definedAt = Commands.getCaller(Components.stack.caller.caller);
|
extra.definedAt = contexts.getCaller(Components.stack.caller.caller);
|
||||||
return this.add.apply(this, arguments);
|
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*.
|
* Returns the command with matching *name*.
|
||||||
*
|
*
|
||||||
@@ -472,7 +519,7 @@ var CommandHive = Class("CommandHive", Group.Hive, {
|
|||||||
* its names matches *name* exactly.
|
* its names matches *name* exactly.
|
||||||
* @returns {Command}
|
* @returns {Command}
|
||||||
*/
|
*/
|
||||||
get: function (name, full) this._map[name]
|
get: function get(name, full) this._map[name]
|
||||||
|| !full && array.nth(this._list, function (cmd) cmd.hasName(name), 0)
|
|| !full && array.nth(this._list, function (cmd) cmd.hasName(name), 0)
|
||||||
|| null,
|
|| null,
|
||||||
|
|
||||||
@@ -482,8 +529,8 @@ var CommandHive = Class("CommandHive", Group.Hive, {
|
|||||||
* @param {string} name The name of the command to remove. This can be
|
* @param {string} name The name of the command to remove. This can be
|
||||||
* any of the command's names.
|
* any of the command's names.
|
||||||
*/
|
*/
|
||||||
remove: function (name) {
|
remove: function remove(name) {
|
||||||
dactyl.assert(this.group !== contexts.default,
|
util.assert(this.group !== contexts.default,
|
||||||
"Cannot delete non-user commands");
|
"Cannot delete non-user commands");
|
||||||
|
|
||||||
let cmd = this.get(name);
|
let cmd = this.get(name);
|
||||||
@@ -491,23 +538,118 @@ var CommandHive = Class("CommandHive", Group.Hive, {
|
|||||||
for (let name in values(cmd.names))
|
for (let name in values(cmd.names))
|
||||||
delete this._map[name];
|
delete this._map[name];
|
||||||
}
|
}
|
||||||
});
|
})),
|
||||||
|
|
||||||
/**
|
|
||||||
* @instance commands
|
|
||||||
*/
|
|
||||||
var Commands = Module("commands", {
|
|
||||||
init: function () {
|
|
||||||
this.user = contexts.hives.commands.user;
|
|
||||||
this.builtin = contexts.hives.commands.builtin;
|
|
||||||
},
|
|
||||||
|
|
||||||
hives: Group.Hives("commands", CommandHive),
|
|
||||||
|
|
||||||
get allHives() contexts.allGroups.commands,
|
get allHives() contexts.allGroups.commands,
|
||||||
|
|
||||||
get userHives() this.allHives.filter(function (h) h !== this.builtin, this),
|
get userHives() this.allHives.filter(function (h) h !== this.builtin, this),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes an Ex command script.
|
||||||
|
*
|
||||||
|
* @param {string} string A string containing the commands to execute.
|
||||||
|
* @param {object} tokens An optional object containing tokens to be
|
||||||
|
* interpolated into the command string.
|
||||||
|
* @param {object} args Optional arguments object to be passed to
|
||||||
|
* command actions.
|
||||||
|
* @param {object} context An object containing information about
|
||||||
|
* the file that is being or has been sourced to obtain the
|
||||||
|
* command string.
|
||||||
|
*/
|
||||||
|
execute: function (string, tokens, silent, args, context) {
|
||||||
|
contexts.withContext(context || this.context || { file: "[Command Line]", line: 1 },
|
||||||
|
function (context) {
|
||||||
|
modules.io.withSavedValues(["readHeredoc"], function () {
|
||||||
|
this.readHeredoc = function (end) {
|
||||||
|
let res = [];
|
||||||
|
contexts.context.line++;
|
||||||
|
while (++i < lines.length) {
|
||||||
|
if (lines[i] === end)
|
||||||
|
return res.join("\n");
|
||||||
|
res.push(lines[i]);
|
||||||
|
}
|
||||||
|
util.assert(false, "Unexpected end of file waiting for " + end);
|
||||||
|
};
|
||||||
|
|
||||||
|
args = update({}, args || {});
|
||||||
|
|
||||||
|
if (tokens && !callable(string))
|
||||||
|
string = util.compileMacro(string, true);
|
||||||
|
if (callable(string))
|
||||||
|
string = string(tokens || {});
|
||||||
|
|
||||||
|
let lines = string.split(/\r\n|[\r\n]/);
|
||||||
|
let startLine = context.line;
|
||||||
|
|
||||||
|
for (var i = 0; i < lines.length && !context.finished; i++) {
|
||||||
|
// Deal with editors from Silly OSs.
|
||||||
|
let line = lines[i].replace(/\r$/, "");
|
||||||
|
|
||||||
|
context.line = startLine + i;
|
||||||
|
|
||||||
|
// Process escaped new lines
|
||||||
|
while (i < lines.length && /^\s*\\/.test(lines[i + 1]))
|
||||||
|
line += "\n" + lines[++i].replace(/^\s*\\/, "");
|
||||||
|
|
||||||
|
try {
|
||||||
|
dactyl.execute(line, args);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
if (!silent) {
|
||||||
|
e.message = context.file + ":" + context.line + ": " + e.message;
|
||||||
|
dactyl.reportError(e, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a list of user-defined commands.
|
||||||
|
*/
|
||||||
|
list: function list() {
|
||||||
|
function completerToString(completer) {
|
||||||
|
if (completer)
|
||||||
|
return [k for ([k, v] in Iterator(config.completers)) if (completer == completion.closure[v])][0] || "custom";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.userHives.some(function (h) h._list.length))
|
||||||
|
dactyl.echomsg("No user-defined commands found");
|
||||||
|
else
|
||||||
|
modules.commandline.commandOutput(
|
||||||
|
<table>
|
||||||
|
<tr highlight="Title">
|
||||||
|
<td/>
|
||||||
|
<td style="padding-right: 1em;"></td>
|
||||||
|
<td style="padding-right: 1ex;">Name</td>
|
||||||
|
<td style="padding-right: 1ex;">Args</td>
|
||||||
|
<td style="padding-right: 1ex;">Range</td>
|
||||||
|
<td style="padding-right: 1ex;">Complete</td>
|
||||||
|
<td style="padding-right: 1ex;">Definition</td>
|
||||||
|
</tr>
|
||||||
|
<col style="min-width: 6em; padding-right: 1em;"/>
|
||||||
|
{
|
||||||
|
template.map(this.userHives, function (hive) let (i = 0)
|
||||||
|
<tr style="height: .5ex;"/> +
|
||||||
|
template.map(hive, function (cmd)
|
||||||
|
template.map(cmd.names, function (name)
|
||||||
|
<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>);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property Indicates that no count was specified for this
|
* @property Indicates that no count was specified for this
|
||||||
* command invocation.
|
* command invocation.
|
||||||
@@ -532,7 +674,7 @@ var Commands = Module("commands", {
|
|||||||
|
|
||||||
add: function () this.builtin._add.apply(this.builtin, arguments),
|
add: function () this.builtin._add.apply(this.builtin, arguments),
|
||||||
addUserCommand: deprecated("commands.user.add", { get: function addUserCommand() this.user.closure._add }),
|
addUserCommand: deprecated("commands.user.add", { get: function addUserCommand() this.user.closure._add }),
|
||||||
getUserCommands: deprecated("iter(commands.user)", function getUserCommands() iter(commands.user).toArray()),
|
getUserCommands: deprecated("iter(commands.user)", function getUserCommands() iter(this.user).toArray()),
|
||||||
removeUserCommand: deprecated("commands.user.remove", { get: function removeUserCommand() this.user.closure.remove }),
|
removeUserCommand: deprecated("commands.user.remove", { get: function removeUserCommand() this.user.closure.remove }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -578,111 +720,6 @@ var Commands = Module("commands", {
|
|||||||
get: function (name, full) iter(this.hives).map(function ([i, hive]) hive.get(name, full))
|
get: function (name, full) iter(this.hives).map(function ([i, hive]) hive.get(name, full))
|
||||||
.nth(util.identity, 0),
|
.nth(util.identity, 0),
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays a list of user-defined commands.
|
|
||||||
*/
|
|
||||||
list: function list() {
|
|
||||||
function completerToString(completer) {
|
|
||||||
if (completer)
|
|
||||||
return [k for ([k, v] in Iterator(config.completers)) if (completer == completion.closure[v])][0] || "custom";
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!commands.userHives.some(function (h) h._list.length))
|
|
||||||
dactyl.echomsg("No user-defined commands found");
|
|
||||||
else
|
|
||||||
commandline.commandOutput(
|
|
||||||
<table>
|
|
||||||
<tr highlight="Title">
|
|
||||||
<td/>
|
|
||||||
<td style="padding-right: 1em;"></td>
|
|
||||||
<td style="padding-right: 1ex;">Name</td>
|
|
||||||
<td style="padding-right: 1ex;">Args</td>
|
|
||||||
<td style="padding-right: 1ex;">Range</td>
|
|
||||||
<td style="padding-right: 1ex;">Complete</td>
|
|
||||||
<td style="padding-right: 1ex;">Definition</td>
|
|
||||||
</tr>
|
|
||||||
<col style="min-width: 6em; padding-right: 1em;"/>
|
|
||||||
{
|
|
||||||
template.map(commands.userHives, function (hive) let (i = 0)
|
|
||||||
<tr style="height: .5ex;"/> +
|
|
||||||
template.map(hive, function (cmd)
|
|
||||||
template.map(cmd.names, function (name)
|
|
||||||
<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>);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes an Ex command script.
|
|
||||||
*
|
|
||||||
* @param {string} string A string containing the commands to execute.
|
|
||||||
* @param {object} tokens An optional object containing tokens to be
|
|
||||||
* interpolated into the command string.
|
|
||||||
* @param {object} args Optional arguments object to be passed to
|
|
||||||
* command actions.
|
|
||||||
* @param {object} context An object containing information about
|
|
||||||
* the file that is being or has been sourced to obtain the
|
|
||||||
* command string.
|
|
||||||
*/
|
|
||||||
execute: function (string, tokens, silent, args, context) {
|
|
||||||
contexts.withContext(context || this.context || { file: "[Command Line]", line: 1 },
|
|
||||||
function (context) {
|
|
||||||
io.withSavedValues(["readHeredoc"], function () {
|
|
||||||
this.readHeredoc = function (end) {
|
|
||||||
let res = [];
|
|
||||||
contexts.context.line++;
|
|
||||||
while (++i < lines.length) {
|
|
||||||
if (lines[i] === end)
|
|
||||||
return res.join("\n");
|
|
||||||
res.push(lines[i]);
|
|
||||||
}
|
|
||||||
dactyl.assert(false, "Unexpected end of file waiting for " + end);
|
|
||||||
};
|
|
||||||
|
|
||||||
args = update({}, args || {});
|
|
||||||
|
|
||||||
if (tokens && !callable(string))
|
|
||||||
string = util.compileMacro(string, true);
|
|
||||||
if (callable(string))
|
|
||||||
string = string(tokens || {});
|
|
||||||
|
|
||||||
let lines = string.split(/\r\n|[\r\n]/);
|
|
||||||
let startLine = context.line;
|
|
||||||
|
|
||||||
for (var i = 0; i < lines.length && !context.finished; i++) {
|
|
||||||
// Deal with editors from Silly OSs.
|
|
||||||
let line = lines[i].replace(/\r$/, "");
|
|
||||||
|
|
||||||
context.line = startLine + i;
|
|
||||||
|
|
||||||
// Process escaped new lines
|
|
||||||
while (i < lines.length && /^\s*\\/.test(lines[i + 1]))
|
|
||||||
line += "\n" + lines[++i].replace(/^\s*\\/, "");
|
|
||||||
|
|
||||||
try {
|
|
||||||
dactyl.execute(line, args);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
if (!silent) {
|
|
||||||
e.message = context.file + ":" + context.line + ": " + e.message;
|
|
||||||
dactyl.reportError(e, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a command invocation contains a URL referring to the
|
* Returns true if a command invocation contains a URL referring to the
|
||||||
* domain *host*.
|
* domain *host*.
|
||||||
@@ -698,7 +735,7 @@ var Commands = Module("commands", {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
dactyl.reportError(e);
|
util.reportError(e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
@@ -764,7 +801,9 @@ var Commands = Module("commands", {
|
|||||||
* Args object.
|
* Args object.
|
||||||
* @returns {Args}
|
* @returns {Args}
|
||||||
*/
|
*/
|
||||||
parseArgs: function (str, params) {
|
parseArgs: function parseArgs(str, params) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
function getNextArg(str, _keepQuotes) {
|
function getNextArg(str, _keepQuotes) {
|
||||||
if (arguments.length < 2)
|
if (arguments.length < 2)
|
||||||
_keepQuotes = keepQuotes;
|
_keepQuotes = keepQuotes;
|
||||||
@@ -774,7 +813,7 @@ var Commands = Module("commands", {
|
|||||||
let count = arg.length + 2;
|
let count = arg.length + 2;
|
||||||
if (complete)
|
if (complete)
|
||||||
return [count, "", ""];
|
return [count, "", ""];
|
||||||
return [count, io.readHeredoc(arg), ""];
|
return [count, self.readHeredoc(arg), ""];
|
||||||
}
|
}
|
||||||
|
|
||||||
let [count, arg, quote] = Commands.parseArg(str, null, _keepQuotes);
|
let [count, arg, quote] = Commands.parseArg(str, null, _keepQuotes);
|
||||||
@@ -795,7 +834,7 @@ var Commands = Module("commands", {
|
|||||||
if (!argCount)
|
if (!argCount)
|
||||||
argCount = "*";
|
argCount = "*";
|
||||||
|
|
||||||
var args = (params.newArgs || Array).call(params); // parsed options
|
var args = params.newArgs ? params.newArgs() : [];
|
||||||
args.string = str; // for access to the unparsed string
|
args.string = str; // for access to the unparsed string
|
||||||
|
|
||||||
// FIXME!
|
// FIXME!
|
||||||
@@ -832,7 +871,7 @@ var Commands = Module("commands", {
|
|||||||
if (complete)
|
if (complete)
|
||||||
complete.message = error;
|
complete.message = error;
|
||||||
else
|
else
|
||||||
dactyl.assert(false, error);
|
util.assert(false, error);
|
||||||
};
|
};
|
||||||
|
|
||||||
outer:
|
outer:
|
||||||
@@ -873,7 +912,7 @@ var Commands = Module("commands", {
|
|||||||
if (sep == "=" || /\s/.test(sep) && opt.type != CommandOption.NOARG) {
|
if (sep == "=" || /\s/.test(sep) && opt.type != CommandOption.NOARG) {
|
||||||
[count, quoted, quote, error] = getNextArg(sub.substr(optname.length + 1), true);
|
[count, quoted, quote, error] = getNextArg(sub.substr(optname.length + 1), true);
|
||||||
arg = Option.dequote(quoted);
|
arg = Option.dequote(quoted);
|
||||||
dactyl.assert(!error, error);
|
util.assert(!error, error);
|
||||||
|
|
||||||
// if we add the argument to an option after a space, it MUST not be empty
|
// if we add the argument to an option after a space, it MUST not be empty
|
||||||
if (sep != "=" && !quote && arg.length == 0)
|
if (sep != "=" && !quote && arg.length == 0)
|
||||||
@@ -974,7 +1013,7 @@ var Commands = Module("commands", {
|
|||||||
|
|
||||||
// if not an option, treat this token as an argument
|
// if not an option, treat this token as an argument
|
||||||
let [count, arg, quote, error] = getNextArg(sub);
|
let [count, arg, quote, error] = getNextArg(sub);
|
||||||
dactyl.assert(!error, error);
|
util.assert(!error, error);
|
||||||
|
|
||||||
if (complete) {
|
if (complete) {
|
||||||
args.quote = Commands.complQuote[quote] || Commands.complQuote[""];
|
args.quote = Commands.complQuote[quote] || Commands.complQuote[""];
|
||||||
@@ -1127,7 +1166,7 @@ var Commands = Module("commands", {
|
|||||||
parseCommands: function (str, complete) {
|
parseCommands: function (str, complete) {
|
||||||
do {
|
do {
|
||||||
let [count, cmd, bang, args, len] = commands.parseCommand(str);
|
let [count, cmd, bang, args, len] = commands.parseCommand(str);
|
||||||
let command = commands.get(cmd || "");
|
let command = this.get(cmd || "");
|
||||||
|
|
||||||
if (command == null) {
|
if (command == null) {
|
||||||
yield [null, { commandString: str }];
|
yield [null, { commandString: str }];
|
||||||
@@ -1142,7 +1181,8 @@ var Commands = Module("commands", {
|
|||||||
if (!complete || /(\w|^)[!\s]/.test(str))
|
if (!complete || /(\w|^)[!\s]/.test(str))
|
||||||
args = command.parseArgs(args, context, { count: count, bang: bang });
|
args = command.parseArgs(args, context, { count: count, bang: bang });
|
||||||
else
|
else
|
||||||
args = commands.parseArgs(args, { extra: { count: count, bang: bang } });
|
args = this.parseArgs(args, { extra: { count: count, bang: bang } });
|
||||||
|
args.context = this.context;
|
||||||
args.commandName = cmd;
|
args.commandName = cmd;
|
||||||
args.commandString = str.substr(0, len) + args.string;
|
args.commandString = str.substr(0, len) + args.string;
|
||||||
str = args.trailing;
|
str = args.trailing;
|
||||||
@@ -1175,23 +1215,6 @@ var Commands = Module("commands", {
|
|||||||
get quoteArg() Commands.quoteArg // XXX: better somewhere else?
|
get quoteArg() Commands.quoteArg // XXX: better somewhere else?
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
/**
|
|
||||||
* Returns a frame object describing the currently executing
|
|
||||||
* command, if applicable, otherwise returns the passed frame.
|
|
||||||
*
|
|
||||||
* @param {nsIStackFrame} frame
|
|
||||||
*/
|
|
||||||
getCaller: function (frame) {
|
|
||||||
if (contexts.context)
|
|
||||||
return {
|
|
||||||
__proto__: frame,
|
|
||||||
filename: contexts.context.file[0] == "[" ? contexts.context.file :
|
|
||||||
services.io.newFileURI(File(contexts.context.file)).spec,
|
|
||||||
lineNumber: contexts.context.line
|
|
||||||
};
|
|
||||||
return frame;
|
|
||||||
},
|
|
||||||
|
|
||||||
// returns [count, parsed_argument]
|
// returns [count, parsed_argument]
|
||||||
parseArg: function parseArg(str, sep, keepQuotes) {
|
parseArg: function parseArg(str, sep, keepQuotes) {
|
||||||
let arg = "";
|
let arg = "";
|
||||||
@@ -1233,15 +1256,19 @@ var Commands = Module("commands", {
|
|||||||
/[\s"'\\]|^$|^-/.test(str) ? "'"
|
/[\s"'\\]|^$|^-/.test(str) ? "'"
|
||||||
: ""](str)
|
: ""](str)
|
||||||
}, {
|
}, {
|
||||||
completion: function () {
|
completion: function initCompletion(dactyl, modules, window) {
|
||||||
|
const { completion } = modules;
|
||||||
|
|
||||||
completion.command = function command(context) {
|
completion.command = function command(context) {
|
||||||
context.title = ["Command"];
|
context.title = ["Command"];
|
||||||
context.keys = { text: "longNames", description: "description" };
|
context.keys = { text: "longNames", description: "description" };
|
||||||
context.generate = function () commands.hives.map(function (h) h._list).flatten();
|
context.generate = function () modules.commands.hives.map(function (h) h._list).flatten();
|
||||||
};
|
};
|
||||||
|
|
||||||
// provides completions for ex commands, including their arguments
|
// provides completions for ex commands, including their arguments
|
||||||
completion.ex = function ex(context) {
|
completion.ex = function ex(context) {
|
||||||
|
const { commands } = modules;
|
||||||
|
|
||||||
// if there is no space between the command name and the cursor
|
// if there is no space between the command name and the cursor
|
||||||
// then get completions of the command name
|
// then get completions of the command name
|
||||||
for (var [command, args] in commands.parseCommands(context.filter, context))
|
for (var [command, args] in commands.parseCommands(context.filter, context))
|
||||||
@@ -1280,18 +1307,20 @@ var Commands = Module("commands", {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
dactyl.reportError(e);
|
util.reportError(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
completion.userCommand = function userCommand(context) {
|
completion.userCommand = function userCommand(context, group) {
|
||||||
context.title = ["User Command", "Definition"];
|
context.title = ["User Command", "Definition"];
|
||||||
context.keys = { text: "name", description: "replacementText" };
|
context.keys = { text: "name", description: "replacementText" };
|
||||||
context.completions = commands.getUserCommands();
|
context.completions = group || modules.commands.user;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
commands: function () {
|
commands: function (dactyl, modules, window) {
|
||||||
|
const { commands, contexts } = modules;
|
||||||
|
|
||||||
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s
|
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s
|
||||||
// specified - useful?
|
// specified - useful?
|
||||||
commands.add(["com[mand]"],
|
commands.add(["com[mand]"],
|
||||||
@@ -1299,12 +1328,15 @@ var Commands = Module("commands", {
|
|||||||
function (args) {
|
function (args) {
|
||||||
let cmd = args[0];
|
let cmd = args[0];
|
||||||
|
|
||||||
dactyl.assert(!cmd || cmd.split(",").every(commands.validName.closure.test),
|
util.assert(!cmd || cmd.split(",").every(commands.validName.closure.test),
|
||||||
"E182: Invalid command name");
|
"E182: Invalid command name");
|
||||||
|
|
||||||
if (!args.literalArg)
|
if (!args.literalArg)
|
||||||
commands.list();
|
commands.list();
|
||||||
else {
|
else {
|
||||||
|
util.assert(args["-group"] !== commands.builtin,
|
||||||
|
"Cannot change commands in the builtin group");
|
||||||
|
|
||||||
let completer = args["-complete"];
|
let completer = args["-complete"];
|
||||||
let completerFunc = null; // default to no completion for user commands
|
let completerFunc = null; // default to no completion for user commands
|
||||||
|
|
||||||
@@ -1333,7 +1365,7 @@ var Commands = Module("commands", {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
completerFunc = function (context) completion.closure[config.completers[completer]](context);
|
completerFunc = function (context) modules.completion.closure[config.completers[completer]](context);
|
||||||
}
|
}
|
||||||
|
|
||||||
let added = args["-group"].add(cmd.split(","),
|
let added = args["-group"].add(cmd.split(","),
|
||||||
@@ -1364,8 +1396,9 @@ var Commands = Module("commands", {
|
|||||||
}, {
|
}, {
|
||||||
bang: true,
|
bang: true,
|
||||||
completer: function (context, args) {
|
completer: function (context, args) {
|
||||||
|
const { completion } = modules;
|
||||||
if (args.completeArg == 0)
|
if (args.completeArg == 0)
|
||||||
completion.userCommand(context);
|
completion.userCommand(context, args["-group"]);
|
||||||
else
|
else
|
||||||
args["-javascript"] ? completion.javascript(context) : completion.ex(context);
|
args["-javascript"] ? completion.javascript(context) : completion.ex(context);
|
||||||
},
|
},
|
||||||
@@ -1442,17 +1475,20 @@ var Commands = Module("commands", {
|
|||||||
|
|
||||||
commands.add(["comc[lear]"],
|
commands.add(["comc[lear]"],
|
||||||
"Delete all user-defined commands",
|
"Delete all user-defined commands",
|
||||||
function () {
|
function (args) {
|
||||||
commands.getUserCommands().forEach(function (cmd) { commands.removeUserCommand(cmd.name); });
|
args["-group"].clear();
|
||||||
},
|
},
|
||||||
{ argCount: "0" });
|
{
|
||||||
|
argCount: "0",
|
||||||
|
options: [contexts.GroupFlag("commands")]
|
||||||
|
});
|
||||||
|
|
||||||
commands.add(["comp[letions]"],
|
commands.add(["comp[letions]"],
|
||||||
"List the completion results for a given command substring",
|
"List the completion results for a given command substring",
|
||||||
function (args) { completion.listCompleter("ex", args[0]); },
|
function (args) { modules.completion.listCompleter("ex", args[0]); },
|
||||||
{
|
{
|
||||||
argCount: "1",
|
argCount: "1",
|
||||||
completer: function (context, args) completion.ex(context),
|
completer: function (context, args) modules.completion.ex(context),
|
||||||
literal: 0
|
literal: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1461,13 +1497,14 @@ var Commands = Module("commands", {
|
|||||||
function (args) {
|
function (args) {
|
||||||
let name = args[0];
|
let name = args[0];
|
||||||
|
|
||||||
if (commands.get(name))
|
if (args["-group"].get(name))
|
||||||
commands.removeUserCommand(name);
|
args["-group"].remove(name);
|
||||||
else
|
else
|
||||||
dactyl.echoerr("E184: No such user-defined command: " + name);
|
dactyl.echoerr("E184: No such user-defined command: " + name);
|
||||||
}, {
|
}, {
|
||||||
argCount: "1",
|
argCount: "1",
|
||||||
completer: function (context) completion.userCommand(context)
|
completer: function (context, args) modules.completion.userCommand(context, args["-group"]),
|
||||||
|
options: [contexts.GroupFlag("commands")]
|
||||||
});
|
});
|
||||||
|
|
||||||
dactyl.addUsageCommand({
|
dactyl.addUsageCommand({
|
||||||
@@ -1491,22 +1528,29 @@ var Commands = Module("commands", {
|
|||||||
"Yank the output of the given command to the clipboard",
|
"Yank the output of the given command to the clipboard",
|
||||||
function (args) {
|
function (args) {
|
||||||
let cmd = /^:/.test(args[0]) ? args[0] : ":echo " + args[0];
|
let cmd = /^:/.test(args[0]) ? args[0] : ":echo " + args[0];
|
||||||
let res = commandline.withOutputToString(commands.execute, commands, cmd);
|
|
||||||
|
let res = modules.commandline.withOutputToString(commands.execute, commands, cmd);
|
||||||
|
|
||||||
dactyl.clipboardWrite(res);
|
dactyl.clipboardWrite(res);
|
||||||
|
|
||||||
let lines = res.split("\n").length;
|
let lines = res.split("\n").length;
|
||||||
dactyl.echomsg("Yanked " + lines + " line" + (lines == 1 ? "" : "s"));
|
dactyl.echomsg("Yanked " + lines + " line" + (lines == 1 ? "" : "s"));
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
completer: function (context) completion[/^:/.test(context.filter) ? "ex" : "javascript"](context),
|
completer: function (context) modules.completion[/^:/.test(context.filter) ? "ex" : "javascript"](context),
|
||||||
literal: 0
|
literal: 0
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
javascript: function () {
|
javascript: function (dactyl, modules, window) {
|
||||||
|
const { JavaScript, commands } = modules;
|
||||||
|
|
||||||
JavaScript.setCompleter([commands.user.get, commands.user.remove],
|
JavaScript.setCompleter([commands.user.get, commands.user.remove],
|
||||||
[function () ([c.name, c.description] for (c in this))]);
|
[function () [[c.name, c.description] for (c in this)]]);
|
||||||
},
|
},
|
||||||
mappings: function () {
|
mappings: function (dactyl, modules, window) {
|
||||||
mappings.add(config.browserModes,
|
const { commands, mappings, modes } = modules;
|
||||||
|
|
||||||
|
mappings.add([modes.COMMAND],
|
||||||
["@:"], "Repeat the last Ex command",
|
["@:"], "Repeat the last Ex command",
|
||||||
function (args) {
|
function (args) {
|
||||||
if (commands.repeat) {
|
if (commands.repeat) {
|
||||||
@@ -1554,4 +1598,8 @@ var Commands = Module("commands", {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// vim: set fdm=marker sw=4 ts=4 et:
|
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:
|
||||||
@@ -42,9 +42,11 @@ var CompletionContext = Class("CompletionContext", {
|
|||||||
let parent = editor;
|
let parent = editor;
|
||||||
name = parent.name + "/" + name;
|
name = parent.name + "/" + name;
|
||||||
|
|
||||||
|
if (this.options) {
|
||||||
this.autoComplete = this.options.get("autocomplete").getKey(name);
|
this.autoComplete = this.options.get("autocomplete").getKey(name);
|
||||||
this.sortResults = this.options.get("wildsort").getKey(name);
|
this.sortResults = this.options.get("wildsort").getKey(name);
|
||||||
this.wildcase = this.options.get("wildcase").getKey(name);
|
this.wildcase = this.options.get("wildcase").getKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
this.contexts = parent.contexts;
|
this.contexts = parent.contexts;
|
||||||
if (name in this.contexts)
|
if (name in this.contexts)
|
||||||
@@ -448,7 +450,7 @@ var CompletionContext = Class("CompletionContext", {
|
|||||||
let self = this;
|
let self = this;
|
||||||
delete this._substrings;
|
delete this._substrings;
|
||||||
|
|
||||||
if (!this.forceAnchored)
|
if (!this.forceAnchored && this.options)
|
||||||
this.anchored = this.options.get("wildanchor").getKey(this.name, this.anchored);
|
this.anchored = this.options.get("wildanchor").getKey(this.name, this.anchored);
|
||||||
|
|
||||||
// Item matchers
|
// Item matchers
|
||||||
|
|||||||
@@ -748,16 +748,17 @@ unlet s:cpo_save
|
|||||||
return lines.map(function (l) l.join("")).join("\n").replace(/\s+\n/gm, "\n");
|
return lines.map(function (l) l.join("")).join("\n").replace(/\s+\n/gm, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { commands, options } = modules;
|
||||||
file.write(template({
|
file.write(template({
|
||||||
name: config.name,
|
name: config.name,
|
||||||
autocommands: wrap("syn keyword " + config.name + "AutoEvent ",
|
autocommands: wrap("syn keyword " + config.name + "AutoEvent ",
|
||||||
keys(config.autocommands)),
|
keys(config.autocommands)),
|
||||||
commands: wrap("syn keyword " + config.name + "Command ",
|
commands: wrap("syn keyword " + config.name + "Command ",
|
||||||
array(c.specs for (c in commands)).flatten()),
|
array(c.specs for (c in commands.iterator())).flatten()),
|
||||||
options: wrap("syn keyword " + config.name + "Option ",
|
options: wrap("syn keyword " + config.name + "Option ",
|
||||||
array(o.names for (o in modules.options) if (o.type != "boolean")).flatten()),
|
array(o.names for (o in options) if (o.type != "boolean")).flatten()),
|
||||||
toggleoptions: wrap("let s:toggleOptions = [",
|
toggleoptions: wrap("let s:toggleOptions = [",
|
||||||
array(o.realNames for (o in modules.options) if (o.type == "boolean"))
|
array(o.realNames for (o in options) if (o.type == "boolean"))
|
||||||
.flatten().map(String.quote),
|
.flatten().map(String.quote),
|
||||||
", ") + "]"
|
", ") + "]"
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -6,6 +6,16 @@
|
|||||||
// given in the LICENSE.txt file included with this file.
|
// given in the LICENSE.txt file included with this file.
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
Components.utils.import("resource://dactyl/bootstrap.jsm");
|
||||||
|
defineModule("options", {
|
||||||
|
exports: ["Option", "Options", "ValueError", "options"],
|
||||||
|
require: ["storage"],
|
||||||
|
use: ["commands", "completion", "prefs", "services", "template", "util"]
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
|
||||||
/** @scope modules */
|
/** @scope modules */
|
||||||
|
|
||||||
let ValueError = Class("ValueError", ErrorBase);
|
let ValueError = Class("ValueError", ErrorBase);
|
||||||
@@ -83,7 +93,7 @@ var Option = Class("Option", {
|
|||||||
get helpTag() "'" + this.name + "'",
|
get helpTag() "'" + this.name + "'",
|
||||||
|
|
||||||
initValue: function () {
|
initValue: function () {
|
||||||
dactyl.trapErrors(function () this.value = this.value, this);
|
util.trapErrors(function () this.value = this.value, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
get isDefault() this.stringValue === this.stringDefaultValue,
|
get isDefault() this.stringValue === this.stringDefaultValue,
|
||||||
@@ -127,13 +137,15 @@ var Option = Class("Option", {
|
|||||||
|
|
||||||
let values;
|
let values;
|
||||||
|
|
||||||
if (dactyl.has("tabs") && (scope & Option.SCOPE_LOCAL))
|
/*
|
||||||
|
if (config.has("tabs") && (scope & Option.SCOPE_LOCAL))
|
||||||
values = tabs.options[this.name];
|
values = tabs.options[this.name];
|
||||||
|
*/
|
||||||
if ((scope & Option.SCOPE_GLOBAL) && (values == undefined))
|
if ((scope & Option.SCOPE_GLOBAL) && (values == undefined))
|
||||||
values = this.globalValue;
|
values = this.globalValue;
|
||||||
|
|
||||||
if (this.getter)
|
if (this.getter)
|
||||||
return dactyl.trapErrors(this.getter, this, values);
|
return util.trapErrors(this.getter, this, values);
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
},
|
},
|
||||||
@@ -151,19 +163,21 @@ var Option = Class("Option", {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.setter)
|
if (this.setter)
|
||||||
newValues = dactyl.trapErrors(this.setter, this, newValues);
|
newValues = this.modules.dactyl.trapErrors(this.setter, this, newValues);
|
||||||
if (newValues === undefined)
|
if (newValues === undefined)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dactyl.has("tabs") && (scope & Option.SCOPE_LOCAL))
|
/*
|
||||||
|
if (config.has("tabs") && (scope & Option.SCOPE_LOCAL))
|
||||||
tabs.options[this.name] = newValues;
|
tabs.options[this.name] = newValues;
|
||||||
|
*/
|
||||||
if ((scope & Option.SCOPE_GLOBAL) && !skipGlobal)
|
if ((scope & Option.SCOPE_GLOBAL) && !skipGlobal)
|
||||||
this.globalValue = newValues;
|
this.globalValue = newValues;
|
||||||
|
|
||||||
this.hasChanged = true;
|
this.hasChanged = true;
|
||||||
this.setFrom = null;
|
this.setFrom = null;
|
||||||
|
|
||||||
dactyl.triggerObserver("options." + this.name, newValues);
|
// dactyl.triggerObserver("options." + this.name, newValues);
|
||||||
},
|
},
|
||||||
|
|
||||||
getValues: deprecated("Option#get", "get"),
|
getValues: deprecated("Option#get", "get"),
|
||||||
@@ -239,7 +253,7 @@ var Option = Class("Option", {
|
|||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
if (!(e instanceof ValueError))
|
if (!(e instanceof ValueError))
|
||||||
dactyl.reportError(e);
|
util.reportError(e);
|
||||||
return this.invalidArgument(str || this.stringify(values), operator) + ": " + e.message;
|
return this.invalidArgument(str || this.stringify(values), operator) + ": " + e.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,6 +494,7 @@ var Option = Class("Option", {
|
|||||||
Option._splitAt = 0;
|
Option._splitAt = 0;
|
||||||
return arg;
|
return arg;
|
||||||
},
|
},
|
||||||
|
|
||||||
splitList: function (value, keepQuotes) {
|
splitList: function (value, keepQuotes) {
|
||||||
let res = [];
|
let res = [];
|
||||||
Option._splitAt = 0;
|
Option._splitAt = 0;
|
||||||
@@ -495,6 +510,7 @@ var Option = Class("Option", {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
quote: function quote(str, re)
|
quote: function quote(str, re)
|
||||||
Commands.quoteArg[/[\s|"'\\,]|^$/.test(str) || re && re.test && re.test(str)
|
Commands.quoteArg[/[\s|"'\\,]|^$/.test(str) || re && re.test && re.test(str)
|
||||||
? (/[\b\f\n\r\t]/.test(str) ? '"' : "'")
|
? (/[\b\f\n\r\t]/.test(str) ? '"' : "'")
|
||||||
@@ -514,7 +530,7 @@ var Option = Class("Option", {
|
|||||||
values = values[(values.indexOf(String(this.value)) + 1) % values.length];
|
values = values[(values.indexOf(String(this.value)) + 1) % values.length];
|
||||||
|
|
||||||
let value = parseInt(values);
|
let value = parseInt(values);
|
||||||
dactyl.assert(Number(values) % 1 == 0,
|
util.assert(Number(values) % 1 == 0,
|
||||||
"E521: Number required after =: " + this.name + "=" + values);
|
"E521: Number required after =: " + this.name + "=" + values);
|
||||||
|
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
@@ -627,7 +643,7 @@ var Option = Class("Option", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
validateXPath: function (values) {
|
validateXPath: function (values) {
|
||||||
let evaluator = XPathEvaluator();
|
let evaluator = services.XPathEvaluator();
|
||||||
return this.testValues(values,
|
return this.testValues(values,
|
||||||
function (value) evaluator.createExpression(value, util.evaluateXPath.resolver));
|
function (value) evaluator.createExpression(value, util.evaluateXPath.resolver));
|
||||||
}
|
}
|
||||||
@@ -637,102 +653,24 @@ var Option = Class("Option", {
|
|||||||
* @instance options
|
* @instance options
|
||||||
*/
|
*/
|
||||||
var Options = Module("options", {
|
var Options = Module("options", {
|
||||||
init: function () {
|
Local: function (dactyl, modules, window) let ({ contexts } = modules) ({
|
||||||
|
init: function init() {
|
||||||
|
const self = this;
|
||||||
this.needInit = [];
|
this.needInit = [];
|
||||||
this._options = [];
|
this._options = [];
|
||||||
this._optionMap = {};
|
this._optionMap = {};
|
||||||
|
this.Option = Class("Option", Option, { modules: modules });
|
||||||
|
|
||||||
storage.newMap("options", { store: false });
|
storage.newMap("options", { store: false });
|
||||||
storage.addObserver("options", function optionObserver(key, event, option) {
|
storage.addObserver("options", function optionObserver(key, event, option) {
|
||||||
// Trigger any setters.
|
// Trigger any setters.
|
||||||
let opt = options.get(option);
|
let opt = self.get(option);
|
||||||
if (event == "change" && opt)
|
if (event == "change" && opt)
|
||||||
opt.set(opt.globalValue, Option.SCOPE_GLOBAL, true);
|
opt.set(opt.globalValue, Option.SCOPE_GLOBAL, true);
|
||||||
}, window);
|
}, window);
|
||||||
},
|
},
|
||||||
|
|
||||||
cleanup: function cleanup() {
|
dactyl: dactyl,
|
||||||
for (let opt in this)
|
|
||||||
if (opt.cleanupValue != null)
|
|
||||||
opt.value = opt.parse(opt.cleanupValue);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** @property {Iterator(Option)} @private */
|
|
||||||
__iterator__: function ()
|
|
||||||
values(this._options.sort(function (a, b) String.localeCompare(a.name, b.name))),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a new option.
|
|
||||||
*
|
|
||||||
* @param {string[]} names All names for the option.
|
|
||||||
* @param {string} description A description of the option.
|
|
||||||
* @param {string} type The option type (see {@link Option#type}).
|
|
||||||
* @param {value} defaultValue The option's default value.
|
|
||||||
* @param {Object} extra An optional extra configuration hash (see
|
|
||||||
* {@link Map#extraInfo}).
|
|
||||||
* @optional
|
|
||||||
*/
|
|
||||||
add: function (names, description, type, defaultValue, extraInfo) {
|
|
||||||
if (!extraInfo)
|
|
||||||
extraInfo = {};
|
|
||||||
|
|
||||||
extraInfo.definedAt = Commands.getCaller(Components.stack.caller);
|
|
||||||
|
|
||||||
let name = names[0];
|
|
||||||
if (name in this._optionMap) {
|
|
||||||
dactyl.log("Warning: " + name.quote() + " already exists: replacing existing option.", 1);
|
|
||||||
this.remove(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
let closure = function () options._optionMap[name];
|
|
||||||
|
|
||||||
memoize(this._optionMap, name, function () Option(names, description, type, defaultValue, extraInfo));
|
|
||||||
for (let alias in values(names.slice(1)))
|
|
||||||
memoize(this._optionMap, alias, closure);
|
|
||||||
|
|
||||||
if (extraInfo.setter && (!extraInfo.scope || extraInfo.scope & Option.SCOPE_GLOBAL))
|
|
||||||
if (dactyl.initialized)
|
|
||||||
closure().initValue();
|
|
||||||
else
|
|
||||||
memoize(this.needInit, this.needInit.length, closure);
|
|
||||||
|
|
||||||
this._floptions = (this._floptions || []).concat(name);
|
|
||||||
memoize(this._options, this._options.length, closure);
|
|
||||||
|
|
||||||
// quickly access options with options["wildmode"]:
|
|
||||||
this.__defineGetter__(name, function () this._optionMap[name].value);
|
|
||||||
this.__defineSetter__(name, function (value) { this._optionMap[name].value = value; });
|
|
||||||
},
|
|
||||||
|
|
||||||
allPrefs: deprecated("prefs.getNames", function allPrefs() prefs.getNames.apply(prefs, arguments)),
|
|
||||||
getPref: deprecated("prefs.get", function getPref() prefs.get.apply(prefs, arguments)),
|
|
||||||
invertPref: deprecated("prefs.invert", function invertPref() prefs.invert.apply(prefs, arguments)),
|
|
||||||
listPrefs: deprecated("prefs.list", function listPrefs() { commandline.commandOutput(prefs.list.apply(prefs, arguments)); }),
|
|
||||||
observePref: deprecated("prefs.observe", function observePref() prefs.observe.apply(prefs, arguments)),
|
|
||||||
popContext: deprecated("prefs.popContext", function popContext() prefs.popContext.apply(prefs, arguments)),
|
|
||||||
pushContext: deprecated("prefs.pushContext", function pushContext() prefs.pushContext.apply(prefs, arguments)),
|
|
||||||
resetPref: deprecated("prefs.reset", function resetPref() prefs.reset.apply(prefs, arguments)),
|
|
||||||
safeResetPref: deprecated("prefs.safeReset", function safeResetPref() prefs.safeReset.apply(prefs, arguments)),
|
|
||||||
safeSetPref: deprecated("prefs.safeSet", function safeSetPref() prefs.safeSet.apply(prefs, arguments)),
|
|
||||||
setPref: deprecated("prefs.set", function setPref() prefs.set.apply(prefs, arguments)),
|
|
||||||
withContext: deprecated("prefs.withContext", function withContext() prefs.withContext.apply(prefs, arguments)),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the option with *name* in the specified *scope*.
|
|
||||||
*
|
|
||||||
* @param {string} name The option's name.
|
|
||||||
* @param {number} scope The option's scope (see {@link Option#scope}).
|
|
||||||
* @optional
|
|
||||||
* @returns {Option} The matching option.
|
|
||||||
*/
|
|
||||||
get: function (name, scope) {
|
|
||||||
if (!scope)
|
|
||||||
scope = Option.SCOPE_BOTH;
|
|
||||||
|
|
||||||
if (this._optionMap[name] && (this._optionMap[name].scope & scope))
|
|
||||||
return this._optionMap[name];
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists all options in *scope* or only those with changed values if
|
* Lists all options in *scope* or only those with changed values if
|
||||||
@@ -774,7 +712,93 @@ var Options = Module("options", {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
commandline.commandOutput(template.options("Options", opts(), options["verbose"] > 0));
|
modules.commandline.commandOutput(template.options("Options", opts(), options["verbose"] > 0));
|
||||||
|
},
|
||||||
|
|
||||||
|
cleanup: function cleanup() {
|
||||||
|
for (let opt in this)
|
||||||
|
if (opt.cleanupValue != null)
|
||||||
|
opt.value = opt.parse(opt.cleanupValue);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new option.
|
||||||
|
*
|
||||||
|
* @param {string[]} names All names for the option.
|
||||||
|
* @param {string} description A description of the option.
|
||||||
|
* @param {string} type The option type (see {@link Option#type}).
|
||||||
|
* @param {value} defaultValue The option's default value.
|
||||||
|
* @param {Object} extra An optional extra configuration hash (see
|
||||||
|
* {@link Map#extraInfo}).
|
||||||
|
* @optional
|
||||||
|
*/
|
||||||
|
add: function (names, description, type, defaultValue, extraInfo) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
if (!extraInfo)
|
||||||
|
extraInfo = {};
|
||||||
|
|
||||||
|
extraInfo.definedAt = contexts.getCaller(Components.stack.caller);
|
||||||
|
|
||||||
|
let name = names[0];
|
||||||
|
if (name in this._optionMap) {
|
||||||
|
this.dactyl.log("Warning: " + name.quote() + " already exists: replacing existing option.", 1);
|
||||||
|
this.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
let closure = function () self._optionMap[name];
|
||||||
|
|
||||||
|
memoize(this._optionMap, name, function () self.Option(names, description, type, defaultValue, extraInfo));
|
||||||
|
for (let alias in values(names.slice(1)))
|
||||||
|
memoize(this._optionMap, alias, closure);
|
||||||
|
|
||||||
|
if (extraInfo.setter && (!extraInfo.scope || extraInfo.scope & Option.SCOPE_GLOBAL))
|
||||||
|
if (this.dactyl.initialized)
|
||||||
|
closure().initValue();
|
||||||
|
else
|
||||||
|
memoize(this.needInit, this.needInit.length, closure);
|
||||||
|
|
||||||
|
this._floptions = (this._floptions || []).concat(name);
|
||||||
|
memoize(this._options, this._options.length, closure);
|
||||||
|
|
||||||
|
// quickly access options with options["wildmode"]:
|
||||||
|
this.__defineGetter__(name, function () this._optionMap[name].value);
|
||||||
|
this.__defineSetter__(name, function (value) { this._optionMap[name].value = value; });
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
/** @property {Iterator(Option)} @private */
|
||||||
|
__iterator__: function ()
|
||||||
|
values(this._options.sort(function (a, b) String.localeCompare(a.name, b.name))),
|
||||||
|
|
||||||
|
allPrefs: deprecated("prefs.getNames", function allPrefs() prefs.getNames.apply(prefs, arguments)),
|
||||||
|
getPref: deprecated("prefs.get", function getPref() prefs.get.apply(prefs, arguments)),
|
||||||
|
invertPref: deprecated("prefs.invert", function invertPref() prefs.invert.apply(prefs, arguments)),
|
||||||
|
listPrefs: deprecated("prefs.list", function listPrefs() { commandline.commandOutput(prefs.list.apply(prefs, arguments)); }),
|
||||||
|
observePref: deprecated("prefs.observe", function observePref() prefs.observe.apply(prefs, arguments)),
|
||||||
|
popContext: deprecated("prefs.popContext", function popContext() prefs.popContext.apply(prefs, arguments)),
|
||||||
|
pushContext: deprecated("prefs.pushContext", function pushContext() prefs.pushContext.apply(prefs, arguments)),
|
||||||
|
resetPref: deprecated("prefs.reset", function resetPref() prefs.reset.apply(prefs, arguments)),
|
||||||
|
safeResetPref: deprecated("prefs.safeReset", function safeResetPref() prefs.safeReset.apply(prefs, arguments)),
|
||||||
|
safeSetPref: deprecated("prefs.safeSet", function safeSetPref() prefs.safeSet.apply(prefs, arguments)),
|
||||||
|
setPref: deprecated("prefs.set", function setPref() prefs.set.apply(prefs, arguments)),
|
||||||
|
withContext: deprecated("prefs.withContext", function withContext() prefs.withContext.apply(prefs, arguments)),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the option with *name* in the specified *scope*.
|
||||||
|
*
|
||||||
|
* @param {string} name The option's name.
|
||||||
|
* @param {number} scope The option's scope (see {@link Option#scope}).
|
||||||
|
* @optional
|
||||||
|
* @returns {Option} The matching option.
|
||||||
|
*/
|
||||||
|
get: function (name, scope) {
|
||||||
|
if (!scope)
|
||||||
|
scope = Option.SCOPE_BOTH;
|
||||||
|
|
||||||
|
if (this._optionMap[name] && (this._optionMap[name].scope & scope))
|
||||||
|
return this._optionMap[name];
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -801,7 +825,7 @@ var Options = Module("options", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (matches) {
|
if (matches) {
|
||||||
ret.option = options.get(ret.name, ret.scope);
|
ret.option = this.get(ret.name, ret.scope);
|
||||||
if (!ret.option && (ret.option = options.get(prefix + ret.name, ret.scope))) {
|
if (!ret.option && (ret.option = options.get(prefix + ret.name, ret.scope))) {
|
||||||
ret.name = prefix + ret.name;
|
ret.name = prefix + ret.name;
|
||||||
prefix = "";
|
prefix = "";
|
||||||
@@ -849,7 +873,9 @@ var Options = Module("options", {
|
|||||||
get store() storage.options
|
get store() storage.options
|
||||||
}, {
|
}, {
|
||||||
}, {
|
}, {
|
||||||
commands: function () {
|
commands: function initCommands(dactyl, modules, window) {
|
||||||
|
const { commands, contexts, options } = modules;
|
||||||
|
|
||||||
let args = {
|
let args = {
|
||||||
getMode: function (args) findMode(args["-mode"]),
|
getMode: function (args) findMode(args["-mode"]),
|
||||||
iterate: function (args) {
|
iterate: function (args) {
|
||||||
@@ -916,7 +942,7 @@ var Options = Module("options", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (name == "all" && reset)
|
if (name == "all" && reset)
|
||||||
commandline.input("Warning: Resetting all preferences may make " + config.host + " unusable. Continue (yes/[no]): ",
|
modules.commandline.input("Warning: Resetting all preferences may make " + config.host + " unusable. Continue (yes/[no]): ",
|
||||||
function (resp) {
|
function (resp) {
|
||||||
if (resp == "yes")
|
if (resp == "yes")
|
||||||
for (let pref in values(prefs.getNames()))
|
for (let pref in values(prefs.getNames()))
|
||||||
@@ -946,22 +972,21 @@ var Options = Module("options", {
|
|||||||
prefs.set(name, value);
|
prefs.set(name, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
commandline.commandOutput(prefs.list(onlyNonDefault, name));
|
modules.commandline.commandOutput(prefs.list(onlyNonDefault, name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let opt = options.parseOpt(arg, modifiers);
|
let opt = modules.options.parseOpt(arg, modifiers);
|
||||||
dactyl.assert(opt, "Error parsing :set command: " + arg);
|
util.assert(opt, "Error parsing :set command: " + arg);
|
||||||
|
|
||||||
let option = opt.option;
|
let option = opt.option;
|
||||||
dactyl.assert(option != null || opt.all,
|
util.assert(option != null || opt.all, "E518: Unknown option: " + opt.name);
|
||||||
"E518: Unknown option: " + opt.name);
|
|
||||||
|
|
||||||
// reset a variable to its default value
|
// reset a variable to its default value
|
||||||
if (opt.reset) {
|
if (opt.reset) {
|
||||||
flushList();
|
flushList();
|
||||||
if (opt.all) {
|
if (opt.all) {
|
||||||
for (let option in options)
|
for (let option in modules.options)
|
||||||
option.reset();
|
option.reset();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -975,7 +1000,7 @@ var Options = Module("options", {
|
|||||||
else {
|
else {
|
||||||
flushList();
|
flushList();
|
||||||
if (opt.option.type === "boolean") {
|
if (opt.option.type === "boolean") {
|
||||||
dactyl.assert(!opt.valueGiven, "E474: Invalid argument: " + arg);
|
util.assert(!opt.valueGiven, "E474: Invalid argument: " + arg);
|
||||||
opt.values = !opt.unsetBoolean;
|
opt.values = !opt.unsetBoolean;
|
||||||
}
|
}
|
||||||
else if (/^(string|number)$/.test(opt.option.type) && opt.invert)
|
else if (/^(string|number)$/.test(opt.option.type) && opt.invert)
|
||||||
@@ -989,7 +1014,7 @@ var Options = Module("options", {
|
|||||||
}
|
}
|
||||||
if (res)
|
if (res)
|
||||||
dactyl.echoerr(res);
|
dactyl.echoerr(res);
|
||||||
option.setFrom = Commands.getCaller(null);
|
option.setFrom = contexts.getCaller(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flushList();
|
flushList();
|
||||||
@@ -1014,7 +1039,7 @@ var Options = Module("options", {
|
|||||||
return completion.preference(context);
|
return completion.preference(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
let opt = options.parseOpt(filter, modifiers);
|
let opt = modules.options.parseOpt(filter, modifiers);
|
||||||
let prefix = opt.prefix;
|
let prefix = opt.prefix;
|
||||||
|
|
||||||
context.highlight();
|
context.highlight();
|
||||||
@@ -1055,7 +1080,7 @@ var Options = Module("options", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let optcontext = context.fork("values");
|
let optcontext = context.fork("values");
|
||||||
completion.optionValue(optcontext, opt.name, opt.operator);
|
modules.completion.optionValue(optcontext, opt.name, opt.operator);
|
||||||
|
|
||||||
// Fill in the current values if we're removing
|
// Fill in the current values if we're removing
|
||||||
if (opt.operator == "-" && isArray(opt.values)) {
|
if (opt.operator == "-" && isArray(opt.values)) {
|
||||||
@@ -1065,7 +1090,7 @@ var Options = Module("options", {
|
|||||||
context.maxItems = optcontext.maxItems;
|
context.maxItems = optcontext.maxItems;
|
||||||
|
|
||||||
context.filters.push(function (i) !set.has(have, i.text));
|
context.filters.push(function (i) !set.has(have, i.text));
|
||||||
completion.optionValue(context, opt.name, opt.operator, null,
|
modules.completion.optionValue(context, opt.name, opt.operator, null,
|
||||||
function (context) {
|
function (context) {
|
||||||
context.generate = function () option.value.map(function (o) [o, ""]);
|
context.generate = function () option.value.map(function (o) [o, ""]);
|
||||||
});
|
});
|
||||||
@@ -1108,9 +1133,9 @@ var Options = Module("options", {
|
|||||||
let [, scope, name, op, expr] = matches;
|
let [, scope, name, op, expr] = matches;
|
||||||
let fullName = (scope || "") + name;
|
let fullName = (scope || "") + name;
|
||||||
|
|
||||||
dactyl.assert(scope == "g:" || scope == null,
|
util.assert(scope == "g:" || scope == null,
|
||||||
"E461: Illegal variable name: " + scope + name);
|
"E461: Illegal variable name: " + scope + name);
|
||||||
dactyl.assert(set.has(globalVariables, name) || (expr && !op),
|
util.assert(set.has(globalVariables, name) || (expr && !op),
|
||||||
"E121: Undefined variable: " + fullName);
|
"E121: Undefined variable: " + fullName);
|
||||||
|
|
||||||
if (!expr)
|
if (!expr)
|
||||||
@@ -1120,7 +1145,7 @@ var Options = Module("options", {
|
|||||||
var newValue = dactyl.userEval(expr);
|
var newValue = dactyl.userEval(expr);
|
||||||
}
|
}
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
dactyl.assert(newValue !== undefined,
|
util.assert(newValue !== undefined,
|
||||||
"E15: Invalid expression: " + expr);
|
"E15: Invalid expression: " + expr);
|
||||||
|
|
||||||
let value = newValue;
|
let value = newValue;
|
||||||
@@ -1167,7 +1192,7 @@ var Options = Module("options", {
|
|||||||
literalArg: [opt.type == "boolean" ? (opt.value ? "" : "no") + opt.name
|
literalArg: [opt.type == "boolean" ? (opt.value ? "" : "no") + opt.name
|
||||||
: opt.name + "=" + opt.stringValue]
|
: opt.name + "=" + opt.stringValue]
|
||||||
}
|
}
|
||||||
for (opt in options)
|
for (opt in modules.options)
|
||||||
if (!opt.getter && !opt.isDefault && (opt.scope & Option.SCOPE_GLOBAL))
|
if (!opt.getter && !opt.isDefault && (opt.scope & Option.SCOPE_GLOBAL))
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1182,18 +1207,18 @@ var Options = Module("options", {
|
|||||||
completer: setCompleter,
|
completer: setCompleter,
|
||||||
domains: function (args) array.flatten(args.map(function (spec) {
|
domains: function (args) array.flatten(args.map(function (spec) {
|
||||||
try {
|
try {
|
||||||
let opt = options.parseOpt(spec);
|
let opt = modules.options.parseOpt(spec);
|
||||||
if (opt.option && opt.option.domains)
|
if (opt.option && opt.option.domains)
|
||||||
return opt.option.domains(opt.values);
|
return opt.option.domains(opt.values);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
dactyl.reportError(e);
|
util.reportError(e);
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
})),
|
})),
|
||||||
keepQuotes: true,
|
keepQuotes: true,
|
||||||
privateData: function (args) args.some(function (spec) {
|
privateData: function (args) args.some(function (spec) {
|
||||||
let opt = options.parseOpt(spec);
|
let opt = modules.options.parseOpt(spec);
|
||||||
return opt.option && opt.option.privateData &&
|
return opt.option && opt.option.privateData &&
|
||||||
(!callable(opt.option.privateData) ||
|
(!callable(opt.option.privateData) ||
|
||||||
opt.option.privateData(opt.values));
|
opt.option.privateData(opt.values));
|
||||||
@@ -1223,12 +1248,14 @@ var Options = Module("options", {
|
|||||||
deprecated: "the options system"
|
deprecated: "the options system"
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
completion: function () {
|
completion: function initCompletion(dactyl, modules, window) {
|
||||||
|
const { completion } = modules;
|
||||||
|
|
||||||
completion.option = function option(context, scope, prefix) {
|
completion.option = function option(context, scope, prefix) {
|
||||||
context.title = ["Option"];
|
context.title = ["Option"];
|
||||||
context.keys = { text: "names", description: "description" };
|
context.keys = { text: "names", description: "description" };
|
||||||
context.anchored = false;
|
context.anchored = false;
|
||||||
context.completions = options;
|
context.completions = modules.options;
|
||||||
if (prefix == "inv")
|
if (prefix == "inv")
|
||||||
context.keys.text = function (opt)
|
context.keys.text = function (opt)
|
||||||
opt.type == "boolean" || isArray(opt.value) ? opt.names.map(function (n) "inv" + n)
|
opt.type == "boolean" || isArray(opt.value) ? opt.names.map(function (n) "inv" + n)
|
||||||
@@ -1238,7 +1265,7 @@ var Options = Module("options", {
|
|||||||
};
|
};
|
||||||
|
|
||||||
completion.optionValue = function (context, name, op, curValue, completer) {
|
completion.optionValue = function (context, name, op, curValue, completer) {
|
||||||
let opt = options.get(name);
|
let opt = modules.options.get(name);
|
||||||
completer = completer || opt.completer;
|
completer = completer || opt.completer;
|
||||||
if (!completer || !opt)
|
if (!completer || !opt)
|
||||||
return;
|
return;
|
||||||
@@ -1301,15 +1328,18 @@ var Options = Module("options", {
|
|||||||
context.completions = res;
|
context.completions = res;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
javascript: function () {
|
javascript: function initJavascript(dactyl, modules, window) {
|
||||||
|
const { options, JavaScript } = modules;
|
||||||
JavaScript.setCompleter(options.get, [function () ([o.name, o.description] for (o in options))]);
|
JavaScript.setCompleter(options.get, [function () ([o.name, o.description] for (o in options))]);
|
||||||
},
|
},
|
||||||
sanitizer: function () {
|
sanitizer: function initSanitizer(dactyl, modules, window) {
|
||||||
|
const { sanitizer } = modules;
|
||||||
|
|
||||||
sanitizer.addItem("options", {
|
sanitizer.addItem("options", {
|
||||||
description: "Options containing hostname data",
|
description: "Options containing hostname data",
|
||||||
action: function (timespan, host) {
|
action: function (timespan, host) {
|
||||||
if (host)
|
if (host)
|
||||||
for (let opt in values(options._options))
|
for (let opt in values(modules.options._options))
|
||||||
if (timespan.contains(opt.lastSet * 1000) && opt.domains)
|
if (timespan.contains(opt.lastSet * 1000) && opt.domains)
|
||||||
try {
|
try {
|
||||||
opt.value = opt.filterDomain(host, opt.value);
|
opt.value = opt.filterDomain(host, opt.value);
|
||||||
@@ -1319,12 +1349,12 @@ var Options = Module("options", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
privateEnter: function () {
|
privateEnter: function () {
|
||||||
for (let opt in values(options._options))
|
for (let opt in values(modules.options._options))
|
||||||
if (opt.privateData && (!callable(opt.privateData) || opt.privateData(opt.value)))
|
if (opt.privateData && (!callable(opt.privateData) || opt.privateData(opt.value)))
|
||||||
opt.oldValue = opt.value;
|
opt.oldValue = opt.value;
|
||||||
},
|
},
|
||||||
privateLeave: function () {
|
privateLeave: function () {
|
||||||
for (let opt in values(options._options))
|
for (let opt in values(modules.options._options))
|
||||||
if (opt.oldValue != null) {
|
if (opt.oldValue != null) {
|
||||||
opt.value = opt.oldValue;
|
opt.value = opt.oldValue;
|
||||||
opt.oldValue = null;
|
opt.oldValue = null;
|
||||||
@@ -1334,4 +1364,8 @@ var Options = Module("options", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// vim: set fdm=marker sw=4 ts=4 et:
|
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:
|
||||||
@@ -154,6 +154,7 @@ var Overlay = Module("Overlay", {
|
|||||||
defineModule.time("load", null, function _load() {
|
defineModule.time("load", null, function _load() {
|
||||||
["addons",
|
["addons",
|
||||||
"base",
|
"base",
|
||||||
|
"commands",
|
||||||
"completion",
|
"completion",
|
||||||
"config",
|
"config",
|
||||||
"downloads",
|
"downloads",
|
||||||
@@ -161,6 +162,7 @@ var Overlay = Module("Overlay", {
|
|||||||
"highlight",
|
"highlight",
|
||||||
"io",
|
"io",
|
||||||
"javascript",
|
"javascript",
|
||||||
|
"options",
|
||||||
"overlay",
|
"overlay",
|
||||||
"prefs",
|
"prefs",
|
||||||
"services",
|
"services",
|
||||||
@@ -177,14 +179,12 @@ var Overlay = Module("Overlay", {
|
|||||||
"abbreviations",
|
"abbreviations",
|
||||||
"autocommands",
|
"autocommands",
|
||||||
"buffer",
|
"buffer",
|
||||||
"commands",
|
|
||||||
"editor",
|
"editor",
|
||||||
"events",
|
"events",
|
||||||
"hints",
|
"hints",
|
||||||
"mappings",
|
"mappings",
|
||||||
"marks",
|
"marks",
|
||||||
"mow",
|
"mow",
|
||||||
"options",
|
|
||||||
"statusline"
|
"statusline"
|
||||||
].forEach(function (name) defineModule.time("load", name, modules.load, modules, name));
|
].forEach(function (name) defineModule.time("load", name, modules.load, modules, name));
|
||||||
|
|
||||||
@@ -325,6 +325,8 @@ var Overlay = Module("Overlay", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
endModule();
|
||||||
|
|
||||||
} catch(e){ if (!e.stack) e = Error(e); dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack); }
|
} 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:
|
// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ var Services = Module("Services", {
|
|||||||
this.addClass("Timer", "@mozilla.org/timer;1", Ci.nsITimer, "initWithCallback");
|
this.addClass("Timer", "@mozilla.org/timer;1", Ci.nsITimer, "initWithCallback");
|
||||||
this.addClass("StreamCopier", "@mozilla.org/network/async-stream-copier;1",Ci.nsIAsyncStreamCopier, "init");
|
this.addClass("StreamCopier", "@mozilla.org/network/async-stream-copier;1",Ci.nsIAsyncStreamCopier, "init");
|
||||||
this.addClass("Xmlhttp", "@mozilla.org/xmlextras/xmlhttprequest;1", Ci.nsIXMLHttpRequest);
|
this.addClass("Xmlhttp", "@mozilla.org/xmlextras/xmlhttprequest;1", Ci.nsIXMLHttpRequest);
|
||||||
|
this.addClass("XPathEvaluator", "@mozilla.org/dom/xpath-evaluator;1", Ci.nsIDOMXPathEvaluator);
|
||||||
this.addClass("ZipReader", "@mozilla.org/libjar/zip-reader;1", Ci.nsIZipReader, "open");
|
this.addClass("ZipReader", "@mozilla.org/libjar/zip-reader;1", Ci.nsIZipReader, "open");
|
||||||
this.addClass("ZipWriter", "@mozilla.org/zipwriter;1", Ci.nsIZipWriter);
|
this.addClass("ZipWriter", "@mozilla.org/zipwriter;1", Ci.nsIZipWriter);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -623,6 +623,9 @@ var Styles = Module("Styles", {
|
|||||||
this.hive.addRef(this);
|
this.hive.addRef(this);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get names() this.hive.names,
|
||||||
|
get sheets() this.hive.sheets,
|
||||||
|
|
||||||
__noSuchMethod__: function __noSuchMethod__(meth, args) {
|
__noSuchMethod__: function __noSuchMethod__(meth, args) {
|
||||||
return this.hive[meth].apply(this.hive, args);
|
return this.hive[meth].apply(this.hive, args);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Components.utils.import("resource://dactyl/bootstrap.jsm");
|
|||||||
defineModule("util", {
|
defineModule("util", {
|
||||||
exports: ["frag", "FailedAssertion", "Math", "NS", "Point", "Util", "XBL", "XHTML", "XUL", "util"],
|
exports: ["frag", "FailedAssertion", "Math", "NS", "Point", "Util", "XBL", "XHTML", "XUL", "util"],
|
||||||
require: ["services"],
|
require: ["services"],
|
||||||
use: ["config", "highlight", "storage", "template"]
|
use: ["commands", "config", "highlight", "storage", "template"]
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
var XBL = Namespace("xbl", "http://www.mozilla.org/xbl");
|
var XBL = Namespace("xbl", "http://www.mozilla.org/xbl");
|
||||||
@@ -22,13 +22,6 @@ var XUL = Namespace("xul", "http://www.mozilla.org/keymaster/gatekeeper/there.is
|
|||||||
var NS = Namespace("dactyl", "http://vimperator.org/namespaces/liberator");
|
var NS = Namespace("dactyl", "http://vimperator.org/namespaces/liberator");
|
||||||
default xml namespace = XHTML;
|
default xml namespace = XHTML;
|
||||||
|
|
||||||
memoize(this, "Commands", function () {
|
|
||||||
// FIXME
|
|
||||||
let obj = { Module: Class };
|
|
||||||
JSMLoader.loadSubScript("resource://dactyl-content/commands.js", obj);
|
|
||||||
return obj.Commands;
|
|
||||||
});
|
|
||||||
|
|
||||||
var FailedAssertion = Class("FailedAssertion", ErrorBase);
|
var FailedAssertion = Class("FailedAssertion", ErrorBase);
|
||||||
var Point = Struct("x", "y");
|
var Point = Struct("x", "y");
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function Controller(controller) {
|
|||||||
}
|
}
|
||||||
this.errors = [];
|
this.errors = [];
|
||||||
this._countError = function countError(message, highlight) {
|
this._countError = function countError(message, highlight) {
|
||||||
if (/\bErrorMsg\b/.test(highlight))
|
if (/\b(Error|Warning)Msg\b/.test(highlight))
|
||||||
self.errors.push(String(message));
|
self.errors.push(String(message));
|
||||||
}
|
}
|
||||||
this.modules.dactyl.registerObserver("beep", this._countBeep);
|
this.modules.dactyl.registerObserver("beep", this._countBeep);
|
||||||
|
|||||||
@@ -122,7 +122,17 @@ var tests = {
|
|||||||
singleOutput: ["", "foobar"],
|
singleOutput: ["", "foobar"],
|
||||||
noOutput: ["foo bar", "-js bar baz"],
|
noOutput: ["foo bar", "-js bar baz"],
|
||||||
multiOutput: [""],
|
multiOutput: [""],
|
||||||
error: ["foo bar", "-js bar baz"]
|
error: [
|
||||||
|
"foo bar",
|
||||||
|
"-js bar baz",
|
||||||
|
"-group=builtin baz quux",
|
||||||
|
"! -group=builtin baz quux",
|
||||||
|
],
|
||||||
|
completions: [
|
||||||
|
["", hasItems],
|
||||||
|
["-group=", hasItems],
|
||||||
|
["-group=user ", hasItems]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
comclear: {
|
comclear: {
|
||||||
noOutput: [""]
|
noOutput: [""]
|
||||||
@@ -140,6 +150,11 @@ var tests = {
|
|||||||
delcommand: [
|
delcommand: [
|
||||||
{
|
{
|
||||||
init: ["comclear", "command foo bar"],
|
init: ["comclear", "command foo bar"],
|
||||||
|
completions: [
|
||||||
|
["", hasItems],
|
||||||
|
["-group=", hasItems],
|
||||||
|
["-group=user ", hasItems]
|
||||||
|
],
|
||||||
noOutput: ["foo"]
|
noOutput: ["foo"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -152,7 +167,6 @@ var tests = {
|
|||||||
noOutput: ["x"],
|
noOutput: ["x"],
|
||||||
completions: ["", "x"]
|
completions: ["", "x"]
|
||||||
},
|
},
|
||||||
delmapgroup: {}, // Skip for now
|
|
||||||
get delmarks() this.delmacros,
|
get delmarks() this.delmacros,
|
||||||
get delqmarks() this.delmacros,
|
get delqmarks() this.delmacros,
|
||||||
delstyle: {
|
delstyle: {
|
||||||
@@ -233,6 +247,25 @@ var tests = {
|
|||||||
finish: { noOutput: [""] },
|
finish: { noOutput: [""] },
|
||||||
forward: { noOutput: [""] },
|
forward: { noOutput: [""] },
|
||||||
frameonly: { noOutput: [""] },
|
frameonly: { noOutput: [""] },
|
||||||
|
delgroup: {
|
||||||
|
error: ["builtin"],
|
||||||
|
completions: [""]
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
multiOutput: [""],
|
||||||
|
noOutput: [
|
||||||
|
"foo -d='foo group' -nopersist -l 'bar.com','http://bar/*','http://bar','^http:'",
|
||||||
|
"! foo -d='foo group' -nopersist -l 'bar.com','http://bar/*','http://bar','^http:'",
|
||||||
|
"foo",
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
error: ["builtin"],
|
||||||
|
completions: [
|
||||||
|
"",
|
||||||
|
"foo "
|
||||||
|
],
|
||||||
|
cleanup: ["delmapgroup foo"]
|
||||||
|
},
|
||||||
hardcopy: {}, // Skip for now
|
hardcopy: {}, // Skip for now
|
||||||
help: {
|
help: {
|
||||||
noOutput: ["", "intro"],
|
noOutput: ["", "intro"],
|
||||||
@@ -318,7 +351,8 @@ var tests = {
|
|||||||
],
|
],
|
||||||
error: [
|
error: [
|
||||||
"-mode=some-nonexistent-mode <C-a> <C-a>",
|
"-mode=some-nonexistent-mode <C-a> <C-a>",
|
||||||
"-gtroup=some-nonexistent-group <C-a> <C-a>"
|
"-group=some-nonexistent-group <C-a> <C-a>",
|
||||||
|
"-group=builtin <C-a> <C-a>"
|
||||||
],
|
],
|
||||||
completions: [
|
completions: [
|
||||||
["", hasItems],
|
["", hasItems],
|
||||||
@@ -333,25 +367,13 @@ var tests = {
|
|||||||
},
|
},
|
||||||
mapclear: {
|
mapclear: {
|
||||||
noOutput: [""],
|
noOutput: [""],
|
||||||
completions: [""]
|
|
||||||
},
|
|
||||||
mapgroup: {
|
|
||||||
multiOutput: [""],
|
|
||||||
noOutput: [
|
|
||||||
"foo -d='foo group' -nopersist 'bar.com,http://bar/*,http://bar,^http:'",
|
|
||||||
"! foo -d='foo group' -nopersist 'bar.com,http://bar/*,http://bar,^http:'",
|
|
||||||
"foo",
|
|
||||||
"user"
|
|
||||||
],
|
|
||||||
error: [
|
error: [
|
||||||
"some-nonexistent-group",
|
"-group=builtin"
|
||||||
"foo -d='foo group' -nopersist 'bar.com,http://bar/*,http://bar,^http:'"
|
|
||||||
],
|
],
|
||||||
completions: [
|
completions: [
|
||||||
"",
|
"",
|
||||||
"foo "
|
"-group="
|
||||||
],
|
]
|
||||||
cleanup: ["delmapgroup foo"]
|
|
||||||
},
|
},
|
||||||
mark: {
|
mark: {
|
||||||
error: ["", "#", "xy"],
|
error: ["", "#", "xy"],
|
||||||
|
|||||||
Reference in New Issue
Block a user