1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-21 00:28:00 +01:00

Add liberator.assert.

This commit is contained in:
Kris Maglione
2009-11-03 02:36:48 -05:00
parent 34e9b10fb9
commit 1ce498401e
13 changed files with 154 additions and 152 deletions

View File

@@ -1126,11 +1126,9 @@ function QuickMarks() //{{{
function (args)
{
// TODO: finish arg parsing - we really need a proper way to do this. :)
if (!args.bang && !args.string)
return void liberator.echoerr("E471: Argument required");
if (args.bang && args.string)
return void liberator.echoerr("E474: Invalid argument");
// assert(args.bang ^ args.string)
liberator.assert( args.bang || args.string, "E471: Argument required");
liberator.assert(!args.bang || !args.string, "E474: Invalid argument");
if (args.bang)
quickmarks.removeAll();
@@ -1167,8 +1165,7 @@ function QuickMarks() //{{{
args = args.string;
// ignore invalid qmark characters unless there are no valid qmark chars
if (args && !/[a-zA-Z0-9]/.test(args))
return void liberator.echoerr("E283: No QuickMarks matching \"" + args + "\"");
liberator.assert(!args || /[a-zA-Z0-9]/.test(args), "E283: No QuickMarks matching \"" + args + "\"");
let filter = args.replace(/[^a-zA-Z0-9]/g, "");
quickmarks.list(filter);
@@ -1253,14 +1250,12 @@ function QuickMarks() //{{{
marks = Array.concat(lowercaseMarks, uppercaseMarks, numberMarks);
if (marks.length == 0)
return void liberator.echoerr("No QuickMarks set");
liberator.assert(marks.length > 0, "No QuickMarks set");
if (filter.length > 0)
{
marks = marks.filter(function (qmark) filter.indexOf(qmark) >= 0);
if (marks.length == 0)
return void liberator.echoerr("E283: No QuickMarks matching \"" + filter + "\"");
liberator.assert(marks.length >= 0, "E283: No QuickMarks matching \"" + filter + "\"");
}
let items = [[mark, qmarks.get(mark)] for ([k, mark] in Iterator(marks))];

View File

@@ -28,8 +28,8 @@ function Buffer() //{{{
function setZoom(value, fullZoom)
{
if (value < ZOOM_MIN || value > ZOOM_MAX)
return void liberator.echoerr("Zoom value out of range (" + ZOOM_MIN + " - " + ZOOM_MAX + "%)");
liberator.assert(value >= ZOOM_MIN && value <= ZOOM_MAX,
"Zoom value out of range (" + ZOOM_MIN + " - " + ZOOM_MAX + "%)");
ZoomManager.useFullZoom = fullZoom;
ZoomManager.zoom = value / 100;
@@ -534,8 +534,8 @@ function Buffer() //{{{
let arg = args[0];
// FIXME: arg handling is a bit of a mess, check for filename
if (arg && (liberator.has("Win32") || arg[0] != ">"))
return void liberator.echoerr("E488: Trailing characters");
liberator.assert(!arg || arg[0] == ">" && !liberator.has("Win32"),
"E488: Trailing characters");
options.withContext(function () {
if (arg)
@@ -584,8 +584,8 @@ function Buffer() //{{{
let titles = buffer.alternateStyleSheets.map(function (stylesheet) stylesheet.title);
if (arg && titles.indexOf(arg) == -1)
return void liberator.echoerr("E475: Invalid argument: " + arg);
liberator.assert(!arg || titles.indexOf(arg) >= 0,
"E475: Invalid argument: " + arg);
if (options["usermode"])
options["usermode"] = false;
@@ -619,8 +619,8 @@ function Buffer() //{{{
{
let file = io.File(filename);
if (file.exists() && !args.bang)
return void liberator.echoerr("E13: File exists (add ! to override)");
liberator.assert(!file.exists() || args.bang,
"E13: File exists (add ! to override)");
chosenData = { file: file, uri: window.makeURI(doc.location.href, doc.characterSet) };
}
@@ -685,7 +685,7 @@ function Buffer() //{{{
level = util.Math.constrain(level, ZOOM_MIN, ZOOM_MAX);
}
else
return void liberator.echoerr("E488: Trailing characters");
liberator.assert(false, "E488: Trailing characters");
if (args.bang)
buffer.fullZoom = level;
@@ -1701,10 +1701,10 @@ function Marks() //{{{
let special = args.bang;
args = args.string;
if (!special && !args)
return void liberator.echoerr("E471: Argument required");
if (special && args)
return void liberator.echoerr("E474: Invalid argument");
// assert(special ^ args)
liberator.assert( special || args, "E471: Argument required");
liberator.assert(!special || !args, "E474: Invalid argument");
let matches;
if (matches = args.match(/(?:(?:^|[^a-zA-Z0-9])-|-(?:$|[^a-zA-Z0-9])|[^a-zA-Z0-9 -]).*/))
{
@@ -1744,10 +1744,10 @@ function Marks() //{{{
function (args)
{
let mark = args[0];
if (mark.length > 1)
return void liberator.echoerr("E488: Trailing characters");
if (!/[a-zA-Z]/.test(mark))
return void liberator.echoerr("E191: Argument must be a letter or forward/backward quote");
liberator.assert(mark.length <= 1, "E488: Trailing characters");
liberator.assert(/[a-zA-Z]/.test(mark),
"E191: Argument must be a letter or forward/backward quote");
marks.add(mark);
},
@@ -1760,8 +1760,8 @@ function Marks() //{{{
args = args.string;
// ignore invalid mark characters unless there are no valid mark chars
if (args && !/[a-zA-Z]/.test(args))
return void liberator.echoerr("E283: No marks matching " + args.quote());
liberator.assert(!args || /[a-zA-Z]/.test(args),
"E283: No marks matching " + args.quote());
let filter = args.replace(/[^a-zA-Z]/g, "");
marks.list(filter);
@@ -1941,14 +1941,12 @@ function Marks() //{{{
{
let marks = getSortedMarks();
if (marks.length == 0)
return void liberator.echoerr("No marks set");
liberator.assert(marks.length > 0, "No marks set");
if (filter.length > 0)
{
marks = marks.filter(function (mark) filter.indexOf(mark[0]) >= 0);
if (marks.length == 0)
return void liberator.echoerr("E283: No marks matching " + filter.quote());
liberator.assert(marks.length > 0, "E283: No marks matching " + filter.quote());
}
let list = template.tabular(

View File

@@ -189,7 +189,7 @@ Command.prototype = {
return;
args.count = count;
args.bang = bang;
self.action.call(self, args, modifiers);
liberator.trapErrors(self.action, self, args, modifiers)
}
if (this.hereDoc)
@@ -714,8 +714,7 @@ function Commands() //{{{
if (sep == "=" || /\s/.test(sep) && opt[1] != this.OPTION_NOARG)
{
[count, arg, quote, error] = getNextArg(sub.substr(optname.length + 1));
if (error)
return void liberator.echoerr(error);
liberator.assert(!error, error);
// if we add the argument to an option after a space, it MUST not be empty
if (sep != "=" && !quote && arg.length == 0)
@@ -808,8 +807,7 @@ function Commands() //{{{
// if not an option, treat this token as an argument
let [count, arg, quote, error] = getNextArg(sub);
if (error)
return void liberator.echoerr(error);
liberator.assert(!error, error);
if (complete)
{
@@ -1018,8 +1016,7 @@ function Commands() //{{{
{
let cmd = args[0];
if (cmd != null && /\W/.test(cmd))
return void liberator.echoerr("E182: Invalid command name");
liberator.assert(!/\W/.test(cmd || ''), "E182: Invalid command name");
if (args.literalArg)
{

View File

@@ -177,8 +177,8 @@ function Editor() //{{{
function (args)
{
let matches = args.string.match(RegExp("^\\s*($|" + abbrevmatch + ")(?:\\s*$|\\s+(.*))"));
if (!matches)
return void liberator.echoerr("E474: Invalid argument");
liberator.assert(matches, "E474: Invalid argument");
let [, lhs, rhs] = matches;
if (rhs)
editor.addAbbreviation(mode, lhs, rhs);
@@ -844,8 +844,7 @@ function Editor() //{{{
// TODO: save return value in v:shell_error
let args = commands.parseArgs(options["editor"], [], "*", true);
if (args.length < 1)
return void liberator.echoerr("No editor specified");
liberator.assert(args.length >= 1, "No editor specified");
args.push(path);
liberator.callFunctionInThread(null, io.run, io.expandPath(args.shift()), args, true);

View File

@@ -56,7 +56,7 @@ function AutoCommands() //{{{
}
catch (e)
{
return void liberator.echoerr("E475: Invalid argument: " + regex);
liberator.assert(false, "E475: Invalid argument: " + regex);
}
if (event)
@@ -66,8 +66,8 @@ function AutoCommands() //{{{
validEvents.push("*");
events = event.split(",");
if (!events.every(function (event) validEvents.indexOf(event) >= 0))
return void liberator.echoerr("E216: No such group or event: " + event);
liberator.assert(events.every(function (event) validEvents.indexOf(event) >= 0),
"E216: No such group or event: " + event);
}
if (cmd) // add new command, possibly removing all others with the same event/pattern
@@ -124,12 +124,12 @@ function AutoCommands() //{{{
let validEvents = config.autocommands.map(function (e) e[0]);
// TODO: add command validators
if (event == "*")
return void liberator.echoerr("E217: Can't execute autocommands for ALL events");
else if (validEvents.indexOf(event) == -1)
return void liberator.echoerr("E216: No such group or event: " + args);
else if (!autocommands.get(event).some(function (c) c.pattern.test(defaultURL)))
return void liberator.echomsg("No matching autocommands");
liberator.assert(event != "*",
"E217: Can't execute autocommands for ALL events");
liberator.assert(validEvents.indexOf(event) >= 0,
"E216: No such group or event: " + args);
liberator.assert(autocommands.get(event).some(function (c) c.pattern.test(defaultURL)),
"No matching autocommands");
if (this.name == "doautoall" && liberator.has("tabs"))
{
@@ -649,8 +649,7 @@ function Events() //{{{
"Delete macros",
function (args)
{
if (args.bang && args.string)
return void liberator.echoerr("E474: Invalid argument");
liberator.assert(!args.bang || !args.string, "E474: Invalid argument");
if (args.bang)
events.deleteMacros();
@@ -724,9 +723,9 @@ function Events() //{{{
*/
startRecording: function (macro)
{
if (!/[a-zA-Z0-9]/.test(macro))
// TODO: ignore this like Vim?
return void liberator.echoerr("E354: Invalid register name: '" + macro + "'");
liberator.assert(/[a-zA-Z0-9]/.test(macro),
"E354: Invalid register name: '" + macro + "'");
modes.isRecording = true;

View File

@@ -417,10 +417,8 @@ function Finder() //{{{
var pattern = str;
else
{
if (lastSearchPattern)
liberator.assert(lastSearchPattern, "E35: No previous search pattern");
pattern = lastSearchPattern;
else
return void liberator.echoerr("E35: No previous search pattern");
}
this.clear();

View File

@@ -189,10 +189,8 @@ function IO() //{{{
arg = "~";
else if (arg == "-")
{
if (oldcwd)
liberator.assert(oldcwd, "E186: No previous directory");
arg = oldcwd.path;
else
return void liberator.echoerr("E186: No previous directory");
}
arg = io.expandPath(arg);
@@ -252,14 +250,13 @@ function IO() //{{{
"Write current key mappings and changed options to the config file",
function (args)
{
if (args.length > 1)
return void liberator.echoerr("E172: Only one file name allowed");
liberator.assert(args.length <= 1, "E172: Only one file name allowed");
let filename = args[0] || io.getRCFile(null, true).path;
let file = io.File(filename);
if (file.exists() && !args.bang)
return void liberator.echoerr("E189: \"" + filename + "\" exists (add ! to override)");
liberator.assert(!file.exists() || args.bang,
"E189: \"" + filename + "\" exists (add ! to override)");
// TODO: Use a set/specifiable list here:
let lines = [cmd.serial().map(commands.commandToString) for (cmd in commands) if (cmd.serial)];
@@ -341,8 +338,8 @@ function IO() //{{{
arg = "!" + arg;
// replaceable bang and no previous command?
if (/((^|[^\\])(\\\\)*)!/.test(arg) && !lastRunCommand)
return void liberator.echoerr("E34: No previous command");
liberator.assert(!/((^|[^\\])(\\\\)*)!/.test(arg) || lastRunCommand,
"E34: No previous command");
// NOTE: Vim doesn't replace ! preceded by 2 or more backslashes and documents it - desirable?
// pass through a raw bang when escaped or substitute the last command

View File

@@ -15,6 +15,13 @@ const EVAL_ERROR = "__liberator_eval_error";
const EVAL_RESULT = "__liberator_eval_result";
const EVAL_STRING = "__liberator_eval_string";
function FailedAssertion(message) {
this.message = message;
}
FailedAssertion.prototype = {
__proto__: Error.prototype,
};
const liberator = (function () //{{{
{
////////////////////////////////////////////////////////////////////////////////
@@ -363,8 +370,8 @@ const liberator = (function () //{{{
let arg = args.literalArg;
let items = getMenuItems();
if (!items.some(function (i) i.fullMenuPath == arg))
return void liberator.echoerr("E334: Menu not found: " + arg);
liberator.assert(items.some(function (i) i.fullMenuPath == arg),
"E334: Menu not found: " + arg);
for (let [, item] in Iterator(items))
{
@@ -453,8 +460,7 @@ const liberator = (function () //{{{
liberator.extensions.forEach(function (e) { action(e); });
else
{
if (!name)
return void liberator.echoerr("E471: Argument required"); // XXX
liberator.assert(name, "E471: Argument required"); // XXX
let extension = liberator.getExtension(name);
if (extension)
@@ -481,8 +487,8 @@ const liberator = (function () //{{{
function (args)
{
let extension = liberator.getExtension(args[0]);
if (!extension || !extension.options)
return void liberator.echoerr("E474: Invalid argument");
liberator.assert(extension && extension.options,
"E474: Invalid argument");
if (args.bang)
window.openDialog(extension.options, "_blank", "chrome");
else
@@ -554,8 +560,7 @@ const liberator = (function () //{{{
command.description,
function (args)
{
if (args.bang)
return void liberator.echoerr("E478: Don't panic!");
liberator.assert(!args.bang, "E478: Don't panic!");
liberator.help(args.literalArg, unchunked);
},
@@ -665,8 +670,7 @@ const liberator = (function () //{{{
function (args)
{
let toolbar = findToolbar(args[0]);
if (!toolbar)
return void liberator.echoerr("E474: Invalid argument");
liberator.assert(toolbar, "E474: Invalid argument");
action(toolbar);
},
{
@@ -1103,6 +1107,20 @@ const liberator = (function () //{{{
liberator.dump((msg || "Stack") + "\n" + stack);
},
/**
* Tests a condition and throws a FailedAssertion error on
* failure.
*
* @param {boolean} condition The condition to test.
* @param {string} message The message to present to the
* user on failure.
*/
assert: function (condition, message)
{
if (!condition)
throw new FailedAssertion(message);
},
/**
* Outputs a plain message to the command line.
*
@@ -1300,8 +1318,7 @@ const liberator = (function () //{{{
else if (special && !command.bang)
err = "E477: No ! allowed";
if (err)
return void liberator.echoerr(err);
liberator.assert(!err, err);
if (!silent)
commandline.command = str.replace(/^\s*:\s*/, "");
@@ -1509,8 +1526,7 @@ const liberator = (function () //{{{
}
let page = this.findHelp(topic, unchunked);
if (page == null)
return void liberator.echoerr("E149: Sorry, no help for " + topic);
liberator.assert(page != null, "E149: Sorry, no help for " + topic);
liberator.open("liberator://help/" + page, { from: "help" });
if (options.get("activate").has("all", "help"))
@@ -1530,8 +1546,7 @@ const liberator = (function () //{{{
{
function sourceDirectory(dir)
{
if (!dir.isReadable())
return void liberator.echoerr("E484: Can't open file " + dir.path);
liberator.assert(dir.isReadable(), "E484: Can't open file " + dir.path);
liberator.log("Sourcing plugin directory: " + dir.path + "...", 3);
dir.readDirectory(true).forEach(function (file) {
@@ -1752,6 +1767,25 @@ const liberator = (function () //{{{
window.goQuitApplication();
},
/**
* Traps errors in the called function, possibly reporting them.
*
* @param {function} func The function to call
* @param {object} self The 'this' object for the function.
*/
trapErrors: function (func, self)
{
try
{
return func.apply(self || this, Array.slice(arguments, 2));
}
catch (e)
{
if (e instanceof FailedAssertion)
liberator.echoerr(e.message);
}
},
/**
* Reports an error to both the console and the host application's
* Error Console.

View File

@@ -105,11 +105,11 @@ Map.prototype = {
args.push(argument);
let self = this;
// FIXME: Kludge.
if (this.names[0] != ".")
mappings.repeat = function () self.action.apply(self, args);
function repeat() self.action.apply(self, args);
if (this.names[0] != ".") // FIXME: Kludge.
mappings.repeat = repeat;
return this.action.apply(this, args);
return liberator.trapErrors(repeat);
}
}; //}}}

View File

@@ -200,14 +200,13 @@ Option.prototype = {
scope = this.scope;
let aValue;
if (liberator.has("tabs") && (scope & options.OPTION_SCOPE_LOCAL))
aValue = tabs.options[this.name];
if ((scope & options.OPTION_SCOPE_GLOBAL) && (aValue == undefined))
aValue = this.globalValue;
if (this.getter)
return this.getter.call(this, aValue);
return liberator.trapErrors(this.getter, this, aValue);
return aValue;
},
@@ -228,7 +227,7 @@ Option.prototype = {
return null;
if (this.setter)
newValue = this.setter(newValue);
newValue = liberator.trapErrors(this.setter, this, newValue);
if (liberator.has("tabs") && (scope & options.OPTION_SCOPE_LOCAL))
tabs.options[this.name] = newValue;
@@ -581,12 +580,11 @@ function Options() //{{{
}
let opt = options.parseOpt(arg, modifiers);
if (!opt)
return void liberator.echoerr("Error parsing :set command: " + arg);
liberator.assert(opt, "Error parsing :set command: " + arg);
let option = opt.option;
if (option == null && !opt.all)
return void liberator.echoerr("E518: Unknown option: " + arg);
liberator.assert(option != null || opt.all,
"E518: Unknown option: " + arg);
// reset a variable to its default value
if (opt.reset)
@@ -630,8 +628,7 @@ function Options() //{{{
if (opt.option.type == "boolean")
{
if (opt.valueGiven)
return void liberator.echoerr("E474: Invalid argument: " + arg);
liberator.assert(!opt.valueGiven, "E474: Invalid argument: " + arg);
opt.values = !opt.unsetBoolean;
}
let res = opt.option.op(opt.operator || "=", opt.values, opt.scope, opt.invert);
@@ -769,14 +766,12 @@ function Options() //{{{
if (!matches[1])
{
let reference = liberator.variableReference(matches[2]);
if (!reference[0] && matches[3])
return void liberator.echoerr("E121: Undefined variable: " + matches[2]);
liberator.assert(reference[0] || !matches[3],
"E121: Undefined variable: " + matches[2]);
let expr = liberator.evalExpression(matches[4]);
if (expr === undefined)
return void liberator.echoerr("E15: Invalid expression: " + matches[4]);
else
{
liberator.assert(expr !== undefined, "E15: Invalid expression: " + matches[4]);
if (!reference[0])
{
if (reference[2] == "g")
@@ -798,13 +793,11 @@ function Options() //{{{
reference[0][reference[1]] = expr;
}
}
}
// 1 - name
else if (matches = args.match(/^\s*([\w:]+)\s*$/))
{
let reference = liberator.variableReference(matches[1]);
if (!reference[0])
return void liberator.echoerr("E121: Undefined variable: " + matches[1]);
liberator.assert(reference[0], "E121: Undefined variable: " + matches[1]);
let value = reference[0][reference[1]];
let prefix = typeof value == "number" ? "#" :

View File

@@ -117,8 +117,7 @@ function Sanitizer() //{{{
if (args.bang)
{
if (args.length > 0)
return void liberator.echoerr("E488: Trailing characters");
liberator.assert(args.length == 0, "E488: Trailing characters");
liberator.log("Sanitizing all items in 'sanitizeitems'...");
@@ -132,8 +131,7 @@ function Sanitizer() //{{{
}
else
{
if (args.length == 0)
return void liberator.echoerr("E471: Argument required");
liberator.assert(args.length > 0, "E471: Argument required");
for (let [, item] in Iterator(args.map(argToPref)))
{

View File

@@ -640,8 +640,9 @@ liberator.registerObserver("load_commands", function () {
if (scheme == "default")
highlight.clear();
else if (!io.sourceFromRuntimePath(["colors/" + scheme + ".vimp"]))
return void liberator.echoerr("E185: Cannot find color scheme " + scheme);
else
liberator.assert(!io.sourceFromRuntimePath(["colors/" + scheme + ".vimp"]),
"E185: Cannot find color scheme " + scheme);
autocommands.trigger("ColorScheme", { name: scheme });
},
{

View File

@@ -431,10 +431,8 @@ function Tabs() //{{{
// count is ignored if an arg is specified, as per Vim
if (arg)
{
if (/^\d+$/.test(arg))
liberator.assert(/^\d+$/.test(arg), "E488: Trailing characters");
index = arg - 1;
else
return void liberator.echoerr("E488: Trailing characters");
}
else
index = count - 1;
@@ -527,8 +525,8 @@ function Tabs() //{{{
let arg = args[0];
// FIXME: tabmove! N should probably produce an error
if (arg && !/^([+-]?\d+)$/.test(arg))
return void liberator.echoerr("E488: Trailing characters");
liberator.assert(!arg || /^([+-]?\d+)$/.test(arg),
"E488: Trailing characters");
// if not specified, move to after the last tab
tabs.move(getBrowser().mCurrentTab, arg || "$", args.bang);
@@ -567,8 +565,7 @@ function Tabs() //{{{
"Detach current tab to its own window",
function ()
{
if (tabs.count == 1)
return void liberator.echoerr("Can't detach the last tab");
liberator.assert(tabs.count > 1, "Can't detach the last tab");
tabs.detachTab(null);
},
@@ -600,16 +597,14 @@ function Tabs() //{{{
"Attach the current tab to another window",
function (args)
{
if (args.length > 2 || args.some(function (i) i && !/^\d+$/.test(i)))
return void liberator.echoerr("E488: Trailing characters");
liberator.assert(args.length <= 2 && !args.some(function (i) i && !/^\d+$/.test(i)),
"E488: Trailing characters");
let [winIndex, tabIndex] = args.map(parseInt);
let win = liberator.windows[winIndex - 1];
if (!win)
return void liberator.echoerr("Window " + winIndex + " does not exist");
else if (win == window)
return void liberator.echoerr("Can't reattach to the same window");
liberator.assert(win, "Window " + winIndex + " does not exist");
liberator.assert(win != window, "Can't reattach to the same window");
let browser = win.getBrowser();
let dummy = browser.addTab("about:blank");
@@ -1192,8 +1187,8 @@ function Tabs() //{{{
*/
selectAlternateTab: function ()
{
if (tabs.alternate == null || tabs.getTab() == tabs.alternate)
return void liberator.echoerr("E23: No alternate page");
liberator.assert(tabs.alternate != null && tabs.getTab() != tabs.alternate,
"E23: No alternate page");
// NOTE: this currently relies on v.tabs.index() returning the
// currently selected tab index when passed null
@@ -1202,9 +1197,7 @@ function Tabs() //{{{
// TODO: since a tab close is more like a bdelete for us we
// should probably reopen the closed tab when a 'deleted'
// alternate is selected
if (index == -1)
liberator.echoerr("E86: Buffer does not exist"); // TODO: This should read "Buffer N does not exist"
else
liberator.assert(index >= 0, "E86: Buffer does not exist"); // TODO: This should read "Buffer N does not exist"
tabs.select(index);
},