diff --git a/common/content/abbreviations.js b/common/content/abbreviations.js index cd44fd08..e3b896e8 100644 --- a/common/content/abbreviations.js +++ b/common/content/abbreviations.js @@ -72,16 +72,23 @@ const Abbreviations = Module("abbreviations", { // TODO: Make keyword definition closer to Vim's default keyword // definition (which differs across platforms). - let nonkw = "\\s\"'"; - let keyword = "[^" + nonkw + "]"; - let nonkeyword = "[" + nonkw + "]"; + let params = { // This is most definitely not Vim compatible. + keyword: /[^\s"']/, + nonkeyword: /[ "']/ + }; - let fullId = keyword + "+"; - let endId = nonkeyword + "+" + keyword; - let nonId = "\\S*" + nonkeyword; - - // Used in add and expand - this._match = fullId + "|" + endId + "|" + nonId; + this._match = util.regexp(<>) (+ )$ | // full-id + (^ | \s | ) (+ )$ | // end-id + (^ | \s ) (\S* )$ // non-id + ]]>, "", params); + this._check = util.regexp(<>+ | // full-id + + | // end-id + \S* // non-id + ) $ + ]]>, "", params); }, /** @@ -117,9 +124,9 @@ const Abbreviations = Module("abbreviations", { * @returns {Abbreviation} */ match: function (mode, text) { - let match = text.match(RegExp('(' + abbreviations._match + ')$')); + let match = this._match.exec(text); if (match) - return abbreviations.get(mode, match[0]); + return abbreviations.get(mode, match[2] || match[4] || match[6]); return null; }, @@ -222,23 +229,20 @@ const Abbreviations = Module("abbreviations", { modes.sort(); modeDescription = modeDescription ? " in " + modeDescription + " mode" : ""; - // Why? --Kris - function splitAbbrev(abbrev) abbrev.match(RegExp("^(\\s*)($|" + abbreviations._match + ")(?:\\s*$|(\\s+)(.*))")) || []; - commands.add([ch ? ch + "a[bbrev]" : "ab[breviate]"], "Abbreviate a key sequence" + modeDescription, function (args) { - let [,, lhs,, rhs] = splitAbbrev(args[0] || ""); - dactyl.assert(lhs != null, "E474: Invalid argument"); + let [lhs, rhs] = args; + dactyl.assert(!args.length || abbreviations._check.test(lhs), + "E474: Invalid argument"); - if (rhs) { + if (!rhs) + abbreviations.list(modes, lhs || ""); + else { if (args["-javascript"]) rhs = Command.bindMacro({ literalArg: rhs }, "-javascript", ["editor"]); abbreviations.add(modes, lhs, rhs); } - else { - abbreviations.list(modes, lhs || ""); - } }, { options: [ { @@ -247,14 +251,12 @@ const Abbreviations = Module("abbreviations", { } ], completer: function (context, args) { - let [, sp1, lhs, sp2, rhs] = splitAbbrev(args[0]); - if (rhs == null) + if (args.length == 1) return completion.abbreviation(context, args, modes) - context.advance((sp1 + lhs + sp2).length); - if (args["-javascript"]) + else if (args["-javascript"]) return completion.javascript(context); }, - literal: 0, + literal: 1, serialize: function () [ { command: this.name, diff --git a/common/modules/highlight.jsm b/common/modules/highlight.jsm index ec818889..6126129b 100644 --- a/common/modules/highlight.jsm +++ b/common/modules/highlight.jsm @@ -164,14 +164,14 @@ const Highlights = Module("Highlight", { this.set(k, null, true); }, - groupRegexp: RegExp(String.replace(, /\s*/g, ""), "gm"), - sheetRegexp: RegExp(String.replace(, "gm"), + sheetRegexp: util.regexp(, /\s*/g, "")), + ]]>), /** * Bulk loads new CSS rules, in the format of, diff --git a/common/modules/styles.jsm b/common/modules/styles.jsm index 3ae071ec..3c4db697 100644 --- a/common/modules/styles.jsm +++ b/common/modules/styles.jsm @@ -258,9 +258,7 @@ const Styles = Module("Styles", { }); }, - propertyPattern: (function () { - const string = /(?:"(?:[^\\"]|\\.)*(?:"|$)|'(?:[^\\']|\\.)*(?:'|$))/.source; - return RegExp(String.replace( | [^)]* ) \s* (?: \) | $) )? \s* - | \s* S \s* | [^;}]* + | \s* \s* | [^;}]* )* ) )? ) (\s* (?: ; | $) ) - ]]>, /S/g, string).replace(/\s*/g, ""), - "gi"); - })() + ]]>, "gi", + { string: /(?:"(?:[^\\"]|\\.)*(?:"|$)|'(?:[^\\']|\\.)*(?:'|$))/ }) }, { commands: function (dactyl, modules, window) { const commands = modules.commands; diff --git a/common/modules/util.jsm b/common/modules/util.jsm index f5b2e333..5c2c3747 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -846,6 +846,30 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) } }, + /** + * Creates a new RegExp object based on the value of expr stripped + * of all white space and interpolated with the values from tokens. + * If tokens, any string in the form of in expr is replaced + * with the value of the property, 'key', from tokens, if that + * property exists. If the property value is itself a RegExp, its + * source is substituted rather than its string value. + * + * Additionally, expr is stripped of all JavaScript comments. + * + * This is similar to Perl's extended regular expression format. + * + * @param {string|XML} expr The expression to compile into a RegExp. + * @param {string} flags Flags to apply to the new RegExp. + * @param {object} tokens The tokens to substitute. @optional + */ + regexp: function (expr, flags, tokens) { + if (tokens) + expr = String.replace(expr, /<(\w+)>/g, function (m, n1) set.has(tokens, n1) ? tokens[n1].source || tokens[n1] : m); + expr = String.replace(expr, /\/\/[^\n]*|\/\*[^]*?\*\//gm, "") + .replace(/\s+/g, ""); + return RegExp(expr, flags); + }, + maxErrors: 15, errors: Class.memoize(function () []), reportError: function (error) {