diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js index 43af7701..d2ccda20 100644 --- a/common/content/bookmarks.js +++ b/common/content/bookmarks.js @@ -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))]; diff --git a/common/content/buffer.js b/common/content/buffer.js index abdc9a0c..a1f43cf8 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -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( diff --git a/common/content/commands.js b/common/content/commands.js index fdb92c75..402e8275 100644 --- a/common/content/commands.js +++ b/common/content/commands.js @@ -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) { diff --git a/common/content/editor.js b/common/content/editor.js index 3bd5bfe1..7b752a3f 100644 --- a/common/content/editor.js +++ b/common/content/editor.js @@ -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); diff --git a/common/content/events.js b/common/content/events.js index f7ecf780..89fb1a54 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -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; diff --git a/common/content/finder.js b/common/content/finder.js index 68d386c0..36660945 100644 --- a/common/content/finder.js +++ b/common/content/finder.js @@ -417,10 +417,8 @@ function Finder() //{{{ var pattern = str; else { - if (lastSearchPattern) - pattern = lastSearchPattern; - else - return void liberator.echoerr("E35: No previous search pattern"); + liberator.assert(lastSearchPattern, "E35: No previous search pattern"); + pattern = lastSearchPattern; } this.clear(); diff --git a/common/content/io.js b/common/content/io.js index d524fab3..11a8d1e0 100644 --- a/common/content/io.js +++ b/common/content/io.js @@ -189,10 +189,8 @@ function IO() //{{{ arg = "~"; else if (arg == "-") { - if (oldcwd) - arg = oldcwd.path; - else - return void liberator.echoerr("E186: No previous directory"); + liberator.assert(oldcwd, "E186: No previous directory"); + arg = oldcwd.path; } 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 diff --git a/common/content/liberator.js b/common/content/liberator.js index 53fcbec3..3c6c63ed 100644 --- a/common/content/liberator.js +++ b/common/content/liberator.js @@ -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. diff --git a/common/content/mappings.js b/common/content/mappings.js index bdad8699..f73c32b1 100644 --- a/common/content/mappings.js +++ b/common/content/mappings.js @@ -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); } }; //}}} diff --git a/common/content/options.js b/common/content/options.js index 232c0d56..a908deae 100644 --- a/common/content/options.js +++ b/common/content/options.js @@ -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,42 +766,38 @@ 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 - { - if (!reference[0]) - { - if (reference[2] == "g") - reference[0] = liberator.globalVariables; - else - return; // for now - } + liberator.assert(expr !== undefined, "E15: Invalid expression: " + matches[4]); - if (matches[3]) - { - if (matches[3] == "+") - reference[0][reference[1]] += expr; - else if (matches[3] == "-") - reference[0][reference[1]] -= expr; - else if (matches[3] == ".") - reference[0][reference[1]] += expr.toString(); - } + if (!reference[0]) + { + if (reference[2] == "g") + reference[0] = liberator.globalVariables; else - reference[0][reference[1]] = expr; + return; // for now } + + if (matches[3]) + { + if (matches[3] == "+") + reference[0][reference[1]] += expr; + else if (matches[3] == "-") + reference[0][reference[1]] -= expr; + else if (matches[3] == ".") + reference[0][reference[1]] += expr.toString(); + } + else + 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" ? "#" : diff --git a/common/content/sanitizer.js b/common/content/sanitizer.js index 45b13458..c1e57c2e 100644 --- a/common/content/sanitizer.js +++ b/common/content/sanitizer.js @@ -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))) { diff --git a/common/content/style.js b/common/content/style.js index 73ca032e..848db6c1 100644 --- a/common/content/style.js +++ b/common/content/style.js @@ -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 }); }, { diff --git a/common/content/tabs.js b/common/content/tabs.js index f7dade7b..396e30d2 100644 --- a/common/content/tabs.js +++ b/common/content/tabs.js @@ -431,10 +431,8 @@ function Tabs() //{{{ // count is ignored if an arg is specified, as per Vim if (arg) { - if (/^\d+$/.test(arg)) - index = arg - 1; - else - return void liberator.echoerr("E488: Trailing characters"); + liberator.assert(/^\d+$/.test(arg), "E488: Trailing characters"); + index = arg - 1; } 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,10 +1197,8 @@ 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 - tabs.select(index); + liberator.assert(index >= 0, "E86: Buffer does not exist"); // TODO: This should read "Buffer N does not exist" + tabs.select(index); }, // NOTE: when restarting a session FF selects the first tab and then the