--- a/devtools/client/sourceeditor/codemirror/README
+++ b/devtools/client/sourceeditor/codemirror/README
@@ -1,16 +1,16 @@
This is the CodeMirror editor packaged for the Mozilla Project. CodeMirror
is a JavaScript component that provides a code editor in the browser. When
a mode is available for the language you are coding in, it will color your
code, and optionally help with indentation.
# Upgrade
-Currently used version is 5.32.0. To upgrade: download a new version of
+Currently used version is 5.33.0. To upgrade: download a new version of
CodeMirror from the project's page [1] and replace all JavaScript and
CSS files inside the codemirror directory [2].
Then to recreate codemirror.bundle.js:
> cd devtools/client/sourceeditor
> npm install
> webpack
--- a/devtools/client/sourceeditor/codemirror/addon/edit/closetag.js
+++ b/devtools/client/sourceeditor/codemirror/addon/edit/closetag.js
@@ -48,23 +48,24 @@
var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
"source", "track", "wbr"];
var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4",
"h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
function autoCloseGT(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), replacements = [];
+ var opt = cm.getOption("autoCloseTags");
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass;
- var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html";
+ var html = inner.mode.configuration == "html";
var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
var tagName = state.tagName;
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
var lowerTagName = tagName.toLowerCase();
// Don't process the '>' at the end of an end-tag or self-closing tag
if (!tagName ||
@@ -76,32 +77,35 @@
return CodeMirror.Pass;
var indent = indentTags && indexOf(indentTags, lowerTagName) > -1;
replacements[i] = {indent: indent,
text: ">" + (indent ? "\n\n" : "") + "</" + tagName + ">",
newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)};
}
+ var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnAutoClose);
for (var i = ranges.length - 1; i >= 0; i--) {
var info = replacements[i];
cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert");
var sel = cm.listSelections().slice(0);
sel[i] = {head: info.newPos, anchor: info.newPos};
cm.setSelections(sel);
- if (info.indent) {
+ if (!dontIndentOnAutoClose && info.indent) {
cm.indentLine(info.newPos.line, null, true);
cm.indentLine(info.newPos.line + 1, null, true);
}
}
}
function autoCloseCurrent(cm, typingSlash) {
var ranges = cm.listSelections(), replacements = [];
var head = typingSlash ? "/" : "</";
+ var opt = cm.getOption("autoCloseTags");
+ var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnSlash);
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
if (typingSlash && (tok.type == "string" || tok.string.charAt(0) != "<" ||
tok.start != pos.ch - 1))
return CodeMirror.Pass;
// Kludge to get around the fact that we are not in XML mode
@@ -122,19 +126,21 @@
return CodeMirror.Pass;
replacement = head + state.context.tagName;
}
if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
replacements[i] = replacement;
}
cm.replaceSelections(replacements);
ranges = cm.listSelections();
- for (var i = 0; i < ranges.length; i++)
- if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line)
- cm.indentLine(ranges[i].head.line);
+ if (!dontIndentOnAutoClose) {
+ for (var i = 0; i < ranges.length; i++)
+ if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line)
+ cm.indentLine(ranges[i].head.line);
+ }
}
function autoCloseSlash(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
return autoCloseCurrent(cm, true);
}
CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };
--- a/devtools/client/sourceeditor/codemirror/addon/edit/continuelist.js
+++ b/devtools/client/sourceeditor/codemirror/addon/edit/continuelist.js
@@ -34,23 +34,21 @@
if (!/>\s*$/.test(line)) cm.replaceRange("", {
line: pos.line, ch: 0
}, {
line: pos.line, ch: pos.ch + 1
});
replacements[i] = "\n";
} else {
var indent = match[1], after = match[5];
- var bullet = unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0
- ? match[2].replace("x", " ")
- : (parseInt(match[3], 10) + 1) + match[4];
-
+ var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0);
+ var bullet = numbered ? (parseInt(match[3], 10) + 1) + match[4] : match[2].replace("x", " ");
replacements[i] = "\n" + indent + bullet + after;
- incrementRemainingMarkdownListNumbers(cm, pos);
+ if (numbered) incrementRemainingMarkdownListNumbers(cm, pos);
}
}
cm.replaceSelections(replacements);
};
// Auto-updating Markdown list numbers when a new item is added to the
// middle of a list
--- a/devtools/client/sourceeditor/codemirror/addon/tern/tern.js
+++ b/devtools/client/sourceeditor/codemirror/addon/tern/tern.js
@@ -609,17 +609,18 @@
function clear() {
cm.state.ternTooltip = null;
if (tip.parentNode) fadeOut(tip)
clearActivity()
}
var mouseOnTip = false, old = false;
CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; });
CodeMirror.on(tip, "mouseout", function(e) {
- if (!CodeMirror.contains(tip, e.relatedTarget || e.toElement)) {
+ var related = e.relatedTarget || e.toElement
+ if (!related || !CodeMirror.contains(tip, related)) {
if (old) clear();
else mouseOnTip = false;
}
});
setTimeout(maybeClear, ts.options.hintDelay ? ts.options.hintDelay : 1700);
var clearActivity = onEditorActivity(cm, clear)
}
--- a/devtools/client/sourceeditor/codemirror/codemirror.bundle.js
+++ b/devtools/client/sourceeditor/codemirror/codemirror.bundle.js
@@ -7843,16 +7843,17 @@ var CodeMirror =
option("indentUnit", 2, loadMode, true)
option("indentWithTabs", false)
option("smartIndent", true)
option("tabSize", 4, function (cm) {
resetModeState(cm)
clearCaches(cm)
regChange(cm)
}, true)
+
option("lineSeparator", null, function (cm, val) {
cm.doc.lineSep = val
if (!val) { return }
var newBreaks = [], lineNo = cm.doc.first
cm.doc.iter(function (line) {
for (var pos = 0;;) {
var found = line.text.indexOf(val, pos)
if (found == -1) { break }
@@ -9883,17 +9884,17 @@ var CodeMirror =
CodeMirror.defineDocExtension = function (name, func) {
Doc.prototype[name] = func
}
CodeMirror.fromTextArea = fromTextArea
addLegacyProps(CodeMirror)
- CodeMirror.version = "5.32.0"
+ CodeMirror.version = "5.33.0"
return CodeMirror;
})));
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
@@ -11050,55 +11051,28 @@ var CodeMirror =
// Tokenizer
var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};}
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
- var jsKeywords = {
+ return {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
"debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
"await": C
};
-
- // Extend the 'normal' keywords with the TypeScript language extensions
- if (isTS) {
- var type = {type: "variable", style: "type"};
- var tsKeywords = {
- // object-like things
- "interface": kw("class"),
- "implements": C,
- "namespace": C,
-
- // scope modifiers
- "public": kw("modifier"),
- "private": kw("modifier"),
- "protected": kw("modifier"),
- "abstract": kw("modifier"),
- "readonly": kw("modifier"),
-
- // types
- "string": type, "number": type, "boolean": type, "any": type
- };
-
- for (var attr in tsKeywords) {
- jsKeywords[attr] = tsKeywords[attr];
- }
- }
-
- return jsKeywords;
}();
var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
function readRegexp(stream) {
var escaped = false, next, inSet = false;
while ((next = stream.next()) != null) {
@@ -11334,16 +11308,20 @@ var CodeMirror =
state.localVars = {name: varname, next: state.localVars};
} else {
if (inList(state.globalVars)) return;
if (parserConfig.globalVars)
state.globalVars = {name: varname, next: state.globalVars};
}
}
+ function isModifier(name) {
+ return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly"
+ }
+
// Combinators
var defaultVars = {name: "this", next: {name: "arguments"}};
function pushcontext() {
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
cx.state.localVars = defaultVars;
}
function popcontext() {
@@ -11390,64 +11368,67 @@ var CodeMirror =
if (type == ";") return cont();
if (type == "if") {
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
cx.state.cc.pop()();
return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
}
if (type == "function") return cont(functiondef);
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
+ if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), className, poplex); }
if (type == "variable") {
if (isTS && value == "type") {
cx.marked = "keyword"
return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
} else if (isTS && value == "declare") {
cx.marked = "keyword"
return cont(statement)
} else if (isTS && (value == "module" || value == "enum") && cx.stream.match(/^\s*\w/, false)) {
cx.marked = "keyword"
return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
+ } else if (isTS && value == "namespace") {
+ cx.marked = "keyword"
+ return cont(pushlex("form"), expression, block, poplex)
} else {
return cont(pushlex("stat"), maybelabel);
}
}
if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"),
block, poplex, poplex);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
statement, poplex, popcontext);
- if (type == "class") return cont(pushlex("form"), className, poplex);
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
if (type == "async") return cont(statement)
if (value == "@") return cont(expression, statement)
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
- function expression(type) {
- return expressionInner(type, false);
- }
- function expressionNoComma(type) {
- return expressionInner(type, true);
+ function expression(type, value) {
+ return expressionInner(type, value, false);
+ }
+ function expressionNoComma(type, value) {
+ return expressionInner(type, value, true);
}
function parenExpr(type) {
if (type != "(") return pass()
return cont(pushlex(")"), expression, expect(")"), poplex)
}
- function expressionInner(type, noComma) {
+ function expressionInner(type, value, noComma) {
if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody;
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
}
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop);
- if (type == "class") return cont(pushlex("form"), classExpression, poplex);
+ if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); }
if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
if (type == "quasi") return pass(quasi, maybeop);
if (type == "new") return cont(maybeTarget(noComma));
return cont();
@@ -11535,20 +11516,21 @@ var CodeMirror =
if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
cx.state.fatArrowAt = cx.stream.pos + m[0].length
return cont(afterprop);
} else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (cx.style + " property");
return cont(afterprop);
} else if (type == "jsonld-keyword") {
return cont(afterprop);
- } else if (type == "modifier") {
+ } else if (isTS && isModifier(value)) {
+ cx.marked = "keyword"
return cont(objprop)
} else if (type == "[") {
- return cont(expression, expect("]"), afterprop);
+ return cont(expression, maybetype, expect("]"), afterprop);
} else if (type == "spread") {
return cont(expressionNoComma, afterprop);
} else if (value == "*") {
cx.marked = "keyword";
return cont(objprop);
} else if (type == ":") {
return pass(afterprop)
}
@@ -11640,32 +11622,32 @@ var CodeMirror =
function typearg(type) {
if (type == "variable") return cont(typearg)
else if (type == ":") return cont(typeexpr)
}
function afterType(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
if (value == "|" || type == ".") return cont(typeexpr)
if (type == "[") return cont(expect("]"), afterType)
- if (value == "extends") return cont(typeexpr)
+ if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
}
function maybeTypeArgs(_, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
}
function typeparam() {
return pass(typeexpr, maybeTypeDefault)
}
function maybeTypeDefault(_, value) {
if (value == "=") return cont(typeexpr)
}
function vardef() {
return pass(pattern, maybetype, maybeAssign, vardefCont);
}
function pattern(type, value) {
- if (type == "modifier") return cont(pattern)
+ if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
if (type == "variable") { register(value); return cont(); }
if (type == "spread") return cont(pattern);
if (type == "[") return contCommasep(pattern, "]");
if (type == "{") return contCommasep(proppattern, "}");
}
function proppattern(type, value) {
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
register(value);
@@ -11709,17 +11691,18 @@ var CodeMirror =
function functiondef(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); return cont(functiondef);}
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext);
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef)
}
function funarg(type, value) {
if (value == "@") cont(expression, funarg)
- if (type == "spread" || type == "modifier") return cont(funarg);
+ if (type == "spread") return cont(funarg);
+ if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); }
return pass(pattern, maybetype, maybeAssign);
}
function classExpression(type, value) {
// Class expressions may have an optional name.
if (type == "variable") return className(type, value);
return classNameAfter(type, value);
}
function className(type, value) {
@@ -11727,29 +11710,29 @@ var CodeMirror =
}
function classNameAfter(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter)
if (value == "extends" || value == "implements" || (isTS && type == ","))
return cont(isTS ? typeexpr : expression, classNameAfter);
if (type == "{") return cont(pushlex("}"), classBody, poplex);
}
function classBody(type, value) {
- if (type == "modifier" || type == "async" ||
+ if (type == "async" ||
(type == "variable" &&
- (value == "static" || value == "get" || value == "set") &&
+ (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) &&
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
cx.marked = "keyword";
return cont(classBody);
}
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
return cont(isTS ? classfield : functiondef, classBody);
}
if (type == "[")
- return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)
+ return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
}
if (type == ";") return cont(classBody);
if (type == "}") return cont();
if (value == "@") return cont(expression, classBody)
}
@@ -11957,16 +11940,17 @@ var CodeMirror =
var xmlConfig = {
autoSelfClosers: {},
implicitlyClosed: {},
contextGrabbers: {},
doNotIndent: {},
allowUnquoted: false,
allowMissing: false,
+ allowMissingTagName: false,
caseFold: false
}
CodeMirror.defineMode("xml", function(editorConf, config_) {
var indentUnit = editorConf.indentUnit
var config = {}
var defaults = config_.htmlMode ? htmlConfig : xmlConfig
for (var prop in defaults) config[prop] = defaults[prop]
@@ -12131,16 +12115,19 @@ var CodeMirror =
return baseState;
}
}
function tagNameState(type, stream, state) {
if (type == "word") {
state.tagName = stream.current();
setStyle = "tag";
return attrState;
+ } else if (config.allowMissingTagName && type == "endTag") {
+ setStyle = "tag bracket";
+ return attrState(type, stream, state);
} else {
setStyle = "error";
return tagNameState;
}
}
function closeTagNameState(type, stream, state) {
if (type == "word") {
var tagName = stream.current();
@@ -12149,16 +12136,19 @@ var CodeMirror =
popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag";
return closeState;
} else {
setStyle = "tag error";
return closeStateErr;
}
+ } else if (config.allowMissingTagName && type == "endTag") {
+ setStyle = "tag bracket";
+ return closeState(type, stream, state);
} else {
setStyle = "error";
return closeStateErr;
}
}
function closeState(type, _stream, state) {
if (type != "endTag") {
@@ -12382,19 +12372,19 @@ var CodeMirror =
return ret("meta", "meta");
}
} else if (/[,+>*\/]/.test(ch)) {
return ret(null, "select-op");
} else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
- } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
- (ch == "d" && stream.match("omain(")) ||
- (ch == "r" && stream.match("egexp("))) {
+ } else if (((ch == "u" || ch == "U") && stream.match(/rl(-prefix)?\(/i)) ||
+ ((ch == "d" || ch == "D") && stream.match("omain(", true, true)) ||
+ ((ch == "r" || ch == "R") && stream.match("egexp(", true, true))) {
stream.backUp(1);
state.tokenize = tokenParenthesized;
return ret("property", "word");
} else if (/[\w\\\-]/.test(ch)) {
stream.eatWhile(/[\w\\\-]/);
return ret("property", "word");
} else {
return ret(null, null);
@@ -12467,26 +12457,26 @@ var CodeMirror =
var states = {};
states.top = function(type, stream, state) {
if (type == "{") {
return pushContext(state, stream, "block");
} else if (type == "}" && state.context.prev) {
return popContext(state);
- } else if (supportsAtComponent && /@component/.test(type)) {
+ } else if (supportsAtComponent && /@component/i.test(type)) {
return pushContext(state, stream, "atComponentBlock");
- } else if (/^@(-moz-)?document$/.test(type)) {
+ } else if (/^@(-moz-)?document$/i.test(type)) {
return pushContext(state, stream, "documentTypes");
- } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
+ } else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) {
return pushContext(state, stream, "atBlock");
- } else if (/^@(font-face|counter-style)/.test(type)) {
+ } else if (/^@(font-face|counter-style)/i.test(type)) {
state.stateArg = type;
return "restricted_atBlock_before";
- } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
+ } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) {
return "keyframes";
} else if (type && type.charAt(0) == "@") {
return pushContext(state, stream, "at");
} else if (type == "hash") {
override = "builtin";
} else if (type == "word") {
override = "tag";
} else if (type == "variable-definition") {
@@ -13098,17 +13088,17 @@ var CodeMirror =
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
} else {
return ["operator", "operator"];
}
},
"@": function(stream) {
if (stream.eat("{")) return [null, "interpolation"];
- if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
+ if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false;
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"];
return ["variable-2", "variable"];
},
"&": function() {
return ["atom", "atom"];
}
@@ -13327,17 +13317,17 @@ var CodeMirror =
function copyContext(context) {
return new Context(CodeMirror.copyState(context.mode, context.state),
context.mode,
context.depth,
context.prev && copyContext(context.prev))
}
CodeMirror.defineMode("jsx", function(config, modeConfig) {
- var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
+ var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false, allowMissingTagName: true})
var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
function flatXMLIndent(state) {
var tagName = state.tagName
state.tagName = null
var result = xmlMode.indent(state, "")
state.tagName = tagName
return result
@@ -14520,16 +14510,37 @@ var CodeMirror =
state.tokenize = null;
break;
}
escaped = stream.next() == "\\" && !escaped;
}
return "string";
}
+ function tokenNestedComment(depth) {
+ return function (stream, state) {
+ var ch
+ while (ch = stream.next()) {
+ if (ch == "*" && stream.eat("/")) {
+ if (depth == 1) {
+ state.tokenize = null
+ break
+ } else {
+ state.tokenize = tokenNestedComment(depth - 1)
+ return state.tokenize(stream, state)
+ }
+ } else if (ch == "/" && stream.eat("*")) {
+ state.tokenize = tokenNestedComment(depth + 1)
+ return state.tokenize(stream, state)
+ }
+ }
+ return "comment"
+ }
+ }
+
def("text/x-scala", {
name: "clike",
keywords: words(
/* scala */
"abstract case catch class def do else extends final finally for forSome if " +
"implicit import lazy match new null object override package private protected return " +
"sealed super this throw trait try type val var while with yield _ " +
@@ -14575,16 +14586,22 @@ var CodeMirror =
"=": function(stream, state) {
var cx = state.context
if (cx.type == "}" && cx.align && stream.eat(">")) {
state.context = new Context(cx.indented, cx.column, cx.type, cx.info, null, cx.prev)
return "operator"
} else {
return false
}
+ },
+
+ "/": function(stream, state) {
+ if (!stream.eat("*")) return false
+ state.tokenize = tokenNestedComment(1)
+ return state.tokenize(stream, state)
}
},
modeProps: {closeBrackets: {triples: '"'}}
});
function tokenKotlinString(tripleString){
return function (stream, state) {
var escaped = false, next, end = false;
@@ -14609,17 +14626,17 @@ var CodeMirror =
"package as typealias class interface this super val " +
"var fun for is in This throw return " +
"break continue object if else while do try when !in !is as? " +
/*soft keywords*/
"file import where by get set abstract enum open inner override private public internal " +
"protected catch finally out final vararg reified dynamic companion constructor init " +
"sealed field property receiver param sparam lateinit data inline noinline tailrec " +
- "external annotation crossinline const operator infix suspend"
+ "external annotation crossinline const operator infix suspend actual expect"
),
types: words(
/* package java.lang */
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
),
@@ -18206,35 +18223,42 @@ var CodeMirror =
} else {
cm.setCursor(offsetCursor(curEnd, 0, -1));
}
}
},
incrementNumberToken: function(cm, actionArgs) {
var cur = cm.getCursor();
var lineStr = cm.getLine(cur.line);
- var re = /-?\d+/g;
+ var re = /(-?)(?:(0x)([\da-f]+)|(0b|0|)(\d+))/gi;
var match;
var start;
var end;
var numberStr;
- var token;
while ((match = re.exec(lineStr)) !== null) {
- token = match[0];
start = match.index;
- end = start + token.length;
+ end = start + match[0].length;
if (cur.ch < end)break;
}
if (!actionArgs.backtrack && (end <= cur.ch))return;
- if (token) {
+ if (match) {
+ var baseStr = match[2] || match[4]
+ var digits = match[3] || match[5]
var increment = actionArgs.increase ? 1 : -1;
- var number = parseInt(token) + (increment * actionArgs.repeat);
+ var base = {'0b': 2, '0': 8, '': 10, '0x': 16}[baseStr.toLowerCase()];
+ var number = parseInt(match[1] + digits, base) + (increment * actionArgs.repeat);
+ numberStr = number.toString(base);
+ var zeroPadding = baseStr ? new Array(digits.length - numberStr.length + 1 + match[1].length).join('0') : ''
+ if (numberStr.charAt(0) === '-') {
+ numberStr = '-' + baseStr + zeroPadding + numberStr.substr(1);
+ } else {
+ numberStr = baseStr + zeroPadding + numberStr;
+ }
var from = Pos(cur.line, start);
var to = Pos(cur.line, end);
- numberStr = number.toString();
cm.replaceRange(numberStr, from, to);
} else {
return;
}
cm.setCursor(Pos(cur.line, start + numberStr.length - 1));
},
repeatLastEdit: function(cm, actionArgs, vim) {
var lastEditInputState = vim.lastEditInputState;
@@ -20970,19 +20994,25 @@ var CodeMirror =
var ranges = cm.listSelections(), newRanges = []
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], pos = range.head, opening = cm.scanForBracket(pos, -1);
if (!opening) return false;
for (;;) {
var closing = cm.scanForBracket(pos, 1);
if (!closing) return false;
if (closing.ch == mirror.charAt(mirror.indexOf(opening.ch) + 1)) {
- newRanges.push({anchor: Pos(opening.pos.line, opening.pos.ch + 1),
- head: closing.pos});
- break;
+ var startPos = Pos(opening.pos.line, opening.pos.ch + 1);
+ if (CodeMirror.cmpPos(startPos, range.from()) == 0 &&
+ CodeMirror.cmpPos(closing.pos, range.to()) == 0) {
+ opening = cm.scanForBracket(opening.pos, -1);
+ if (!opening) return false;
+ } else {
+ newRanges.push({anchor: startPos, head: closing.pos});
+ break;
+ }
}
pos = Pos(closing.pos.line, closing.pos.ch + 1);
}
}
cm.setSelections(newRanges);
return true;
}
@@ -21295,37 +21325,16 @@ var CodeMirror =
cm.replaceSelection(cm.state.sublimeKilled, null, "paste");
};
cmds.showInCenter = function(cm) {
var pos = cm.cursorCoords(null, "local");
cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2);
};
- cmds.selectLinesUpward = function(cm) {
- cm.operation(function() {
- var ranges = cm.listSelections();
- for (var i = 0; i < ranges.length; i++) {
- var range = ranges[i];
- if (range.head.line > cm.firstLine())
- cm.addSelection(Pos(range.head.line - 1, range.head.ch));
- }
- });
- };
- cmds.selectLinesDownward = function(cm) {
- cm.operation(function() {
- var ranges = cm.listSelections();
- for (var i = 0; i < ranges.length; i++) {
- var range = ranges[i];
- if (range.head.line < cm.lastLine())
- cm.addSelection(Pos(range.head.line + 1, range.head.ch));
- }
- });
- };
-
function getTarget(cm) {
var from = cm.getCursor("from"), to = cm.getCursor("to");
if (CodeMirror.cmpPos(from, to) == 0) {
var word = wordAt(cm, from);
if (!word.word) return;
from = word.from;
to = word.to;
}
@@ -21377,18 +21386,16 @@ var CodeMirror =
"Ctrl-Alt-Up": "scrollLineUp",
"Ctrl-Alt-Down": "scrollLineDown",
"Cmd-L": "selectLine",
"Shift-Cmd-L": "splitSelectionByLine",
"Esc": "singleSelectionTop",
"Cmd-Enter": "insertLineAfter",
"Shift-Cmd-Enter": "insertLineBefore",
"Cmd-D": "selectNextOccurrence",
- "Shift-Cmd-Up": "addCursorToPrevLine",
- "Shift-Cmd-Down": "addCursorToNextLine",
"Shift-Cmd-Space": "selectScope",
"Shift-Cmd-M": "selectBetweenBrackets",
"Cmd-M": "goToBracket",
"Cmd-Ctrl-Up": "swapLineUp",
"Cmd-Ctrl-Down": "swapLineDown",
"Cmd-/": "toggleCommentIndented",
"Cmd-J": "joinLines",
"Shift-Cmd-D": "duplicateLine",
@@ -21408,18 +21415,18 @@ var CodeMirror =
"Cmd-K Cmd-W": "deleteToSublimeMark",
"Cmd-K Cmd-X": "swapWithSublimeMark",
"Cmd-K Cmd-Y": "sublimeYank",
"Cmd-K Cmd-C": "showInCenter",
"Cmd-K Cmd-G": "clearBookmarks",
"Cmd-K Cmd-Backspace": "delLineLeft",
"Cmd-K Cmd-0": "unfoldAll",
"Cmd-K Cmd-J": "unfoldAll",
- "Ctrl-Shift-Up": "selectLinesUpward",
- "Ctrl-Shift-Down": "selectLinesDownward",
+ "Ctrl-Shift-Up": "addCursorToPrevLine",
+ "Ctrl-Shift-Down": "addCursorToNextLine",
"Cmd-F3": "findUnder",
"Shift-Cmd-F3": "findUnderPrevious",
"Alt-F3": "findAllUnder",
"Shift-Cmd-[": "fold",
"Shift-Cmd-]": "unfold",
"Cmd-I": "findIncremental",
"Shift-Cmd-I": "findIncrementalReverse",
"Cmd-H": "replace",
@@ -21439,18 +21446,16 @@ var CodeMirror =
"Ctrl-Up": "scrollLineUp",
"Ctrl-Down": "scrollLineDown",
"Ctrl-L": "selectLine",
"Shift-Ctrl-L": "splitSelectionByLine",
"Esc": "singleSelectionTop",
"Ctrl-Enter": "insertLineAfter",
"Shift-Ctrl-Enter": "insertLineBefore",
"Ctrl-D": "selectNextOccurrence",
- "Alt-CtrlUp": "addCursorToPrevLine",
- "Alt-CtrlDown": "addCursorToNextLine",
"Shift-Ctrl-Space": "selectScope",
"Shift-Ctrl-M": "selectBetweenBrackets",
"Ctrl-M": "goToBracket",
"Shift-Ctrl-Up": "swapLineUp",
"Shift-Ctrl-Down": "swapLineDown",
"Ctrl-/": "toggleCommentIndented",
"Ctrl-J": "joinLines",
"Shift-Ctrl-D": "duplicateLine",
@@ -21470,18 +21475,18 @@ var CodeMirror =
"Ctrl-K Ctrl-W": "deleteToSublimeMark",
"Ctrl-K Ctrl-X": "swapWithSublimeMark",
"Ctrl-K Ctrl-Y": "sublimeYank",
"Ctrl-K Ctrl-C": "showInCenter",
"Ctrl-K Ctrl-G": "clearBookmarks",
"Ctrl-K Ctrl-Backspace": "delLineLeft",
"Ctrl-K Ctrl-0": "unfoldAll",
"Ctrl-K Ctrl-J": "unfoldAll",
- "Ctrl-Alt-Up": "selectLinesUpward",
- "Ctrl-Alt-Down": "selectLinesDownward",
+ "Ctrl-Alt-Up": "addCursorToPrevLine",
+ "Ctrl-Alt-Down": "addCursorToNextLine",
"Ctrl-F3": "findUnder",
"Shift-Ctrl-F3": "findUnderPrevious",
"Alt-F3": "findAllUnder",
"Shift-Ctrl-[": "fold",
"Shift-Ctrl-]": "unfold",
"Ctrl-I": "findIncremental",
"Shift-Ctrl-I": "findIncrementalReverse",
"Ctrl-H": "replace",
--- a/devtools/client/sourceeditor/codemirror/keymap/sublime.js
+++ b/devtools/client/sourceeditor/codemirror/keymap/sublime.js
@@ -178,19 +178,25 @@
var ranges = cm.listSelections(), newRanges = []
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], pos = range.head, opening = cm.scanForBracket(pos, -1);
if (!opening) return false;
for (;;) {
var closing = cm.scanForBracket(pos, 1);
if (!closing) return false;
if (closing.ch == mirror.charAt(mirror.indexOf(opening.ch) + 1)) {
- newRanges.push({anchor: Pos(opening.pos.line, opening.pos.ch + 1),
- head: closing.pos});
- break;
+ var startPos = Pos(opening.pos.line, opening.pos.ch + 1);
+ if (CodeMirror.cmpPos(startPos, range.from()) == 0 &&
+ CodeMirror.cmpPos(closing.pos, range.to()) == 0) {
+ opening = cm.scanForBracket(opening.pos, -1);
+ if (!opening) return false;
+ } else {
+ newRanges.push({anchor: startPos, head: closing.pos});
+ break;
+ }
}
pos = Pos(closing.pos.line, closing.pos.ch + 1);
}
}
cm.setSelections(newRanges);
return true;
}
@@ -503,37 +509,16 @@
cm.replaceSelection(cm.state.sublimeKilled, null, "paste");
};
cmds.showInCenter = function(cm) {
var pos = cm.cursorCoords(null, "local");
cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2);
};
- cmds.selectLinesUpward = function(cm) {
- cm.operation(function() {
- var ranges = cm.listSelections();
- for (var i = 0; i < ranges.length; i++) {
- var range = ranges[i];
- if (range.head.line > cm.firstLine())
- cm.addSelection(Pos(range.head.line - 1, range.head.ch));
- }
- });
- };
- cmds.selectLinesDownward = function(cm) {
- cm.operation(function() {
- var ranges = cm.listSelections();
- for (var i = 0; i < ranges.length; i++) {
- var range = ranges[i];
- if (range.head.line < cm.lastLine())
- cm.addSelection(Pos(range.head.line + 1, range.head.ch));
- }
- });
- };
-
function getTarget(cm) {
var from = cm.getCursor("from"), to = cm.getCursor("to");
if (CodeMirror.cmpPos(from, to) == 0) {
var word = wordAt(cm, from);
if (!word.word) return;
from = word.from;
to = word.to;
}
@@ -585,18 +570,16 @@
"Ctrl-Alt-Up": "scrollLineUp",
"Ctrl-Alt-Down": "scrollLineDown",
"Cmd-L": "selectLine",
"Shift-Cmd-L": "splitSelectionByLine",
"Esc": "singleSelectionTop",
"Cmd-Enter": "insertLineAfter",
"Shift-Cmd-Enter": "insertLineBefore",
"Cmd-D": "selectNextOccurrence",
- "Shift-Cmd-Up": "addCursorToPrevLine",
- "Shift-Cmd-Down": "addCursorToNextLine",
"Shift-Cmd-Space": "selectScope",
"Shift-Cmd-M": "selectBetweenBrackets",
"Cmd-M": "goToBracket",
"Cmd-Ctrl-Up": "swapLineUp",
"Cmd-Ctrl-Down": "swapLineDown",
"Cmd-/": "toggleCommentIndented",
"Cmd-J": "joinLines",
"Shift-Cmd-D": "duplicateLine",
@@ -616,18 +599,18 @@
"Cmd-K Cmd-W": "deleteToSublimeMark",
"Cmd-K Cmd-X": "swapWithSublimeMark",
"Cmd-K Cmd-Y": "sublimeYank",
"Cmd-K Cmd-C": "showInCenter",
"Cmd-K Cmd-G": "clearBookmarks",
"Cmd-K Cmd-Backspace": "delLineLeft",
"Cmd-K Cmd-0": "unfoldAll",
"Cmd-K Cmd-J": "unfoldAll",
- "Ctrl-Shift-Up": "selectLinesUpward",
- "Ctrl-Shift-Down": "selectLinesDownward",
+ "Ctrl-Shift-Up": "addCursorToPrevLine",
+ "Ctrl-Shift-Down": "addCursorToNextLine",
"Cmd-F3": "findUnder",
"Shift-Cmd-F3": "findUnderPrevious",
"Alt-F3": "findAllUnder",
"Shift-Cmd-[": "fold",
"Shift-Cmd-]": "unfold",
"Cmd-I": "findIncremental",
"Shift-Cmd-I": "findIncrementalReverse",
"Cmd-H": "replace",
@@ -647,18 +630,16 @@
"Ctrl-Up": "scrollLineUp",
"Ctrl-Down": "scrollLineDown",
"Ctrl-L": "selectLine",
"Shift-Ctrl-L": "splitSelectionByLine",
"Esc": "singleSelectionTop",
"Ctrl-Enter": "insertLineAfter",
"Shift-Ctrl-Enter": "insertLineBefore",
"Ctrl-D": "selectNextOccurrence",
- "Alt-CtrlUp": "addCursorToPrevLine",
- "Alt-CtrlDown": "addCursorToNextLine",
"Shift-Ctrl-Space": "selectScope",
"Shift-Ctrl-M": "selectBetweenBrackets",
"Ctrl-M": "goToBracket",
"Shift-Ctrl-Up": "swapLineUp",
"Shift-Ctrl-Down": "swapLineDown",
"Ctrl-/": "toggleCommentIndented",
"Ctrl-J": "joinLines",
"Shift-Ctrl-D": "duplicateLine",
@@ -678,18 +659,18 @@
"Ctrl-K Ctrl-W": "deleteToSublimeMark",
"Ctrl-K Ctrl-X": "swapWithSublimeMark",
"Ctrl-K Ctrl-Y": "sublimeYank",
"Ctrl-K Ctrl-C": "showInCenter",
"Ctrl-K Ctrl-G": "clearBookmarks",
"Ctrl-K Ctrl-Backspace": "delLineLeft",
"Ctrl-K Ctrl-0": "unfoldAll",
"Ctrl-K Ctrl-J": "unfoldAll",
- "Ctrl-Alt-Up": "selectLinesUpward",
- "Ctrl-Alt-Down": "selectLinesDownward",
+ "Ctrl-Alt-Up": "addCursorToPrevLine",
+ "Ctrl-Alt-Down": "addCursorToNextLine",
"Ctrl-F3": "findUnder",
"Shift-Ctrl-F3": "findUnderPrevious",
"Alt-F3": "findAllUnder",
"Shift-Ctrl-[": "fold",
"Shift-Ctrl-]": "unfold",
"Ctrl-I": "findIncremental",
"Shift-Ctrl-I": "findIncrementalReverse",
"Ctrl-H": "replace",
--- a/devtools/client/sourceeditor/codemirror/keymap/vim.js
+++ b/devtools/client/sourceeditor/codemirror/keymap/vim.js
@@ -2632,35 +2632,42 @@
} else {
cm.setCursor(offsetCursor(curEnd, 0, -1));
}
}
},
incrementNumberToken: function(cm, actionArgs) {
var cur = cm.getCursor();
var lineStr = cm.getLine(cur.line);
- var re = /-?\d+/g;
+ var re = /(-?)(?:(0x)([\da-f]+)|(0b|0|)(\d+))/gi;
var match;
var start;
var end;
var numberStr;
- var token;
while ((match = re.exec(lineStr)) !== null) {
- token = match[0];
start = match.index;
- end = start + token.length;
+ end = start + match[0].length;
if (cur.ch < end)break;
}
if (!actionArgs.backtrack && (end <= cur.ch))return;
- if (token) {
+ if (match) {
+ var baseStr = match[2] || match[4]
+ var digits = match[3] || match[5]
var increment = actionArgs.increase ? 1 : -1;
- var number = parseInt(token) + (increment * actionArgs.repeat);
+ var base = {'0b': 2, '0': 8, '': 10, '0x': 16}[baseStr.toLowerCase()];
+ var number = parseInt(match[1] + digits, base) + (increment * actionArgs.repeat);
+ numberStr = number.toString(base);
+ var zeroPadding = baseStr ? new Array(digits.length - numberStr.length + 1 + match[1].length).join('0') : ''
+ if (numberStr.charAt(0) === '-') {
+ numberStr = '-' + baseStr + zeroPadding + numberStr.substr(1);
+ } else {
+ numberStr = baseStr + zeroPadding + numberStr;
+ }
var from = Pos(cur.line, start);
var to = Pos(cur.line, end);
- numberStr = number.toString();
cm.replaceRange(numberStr, from, to);
} else {
return;
}
cm.setCursor(Pos(cur.line, start + numberStr.length - 1));
},
repeatLastEdit: function(cm, actionArgs, vim) {
var lastEditInputState = vim.lastEditInputState;
--- a/devtools/client/sourceeditor/codemirror/lib/codemirror.css
+++ b/devtools/client/sourceeditor/codemirror/lib/codemirror.css
@@ -265,17 +265,17 @@ div.CodeMirror span.CodeMirror-nonmatchi
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
- overflow: auto;
+ padding: 0.1px; /* Force widget margins to stay inside of the container */
}
.CodeMirror-widget {}
.CodeMirror-rtl pre { direction: rtl; }
.CodeMirror-code {
outline: none;
--- a/devtools/client/sourceeditor/codemirror/lib/codemirror.js
+++ b/devtools/client/sourceeditor/codemirror/lib/codemirror.js
@@ -7601,16 +7601,17 @@ function defineOptions(CodeMirror) {
option("indentUnit", 2, loadMode, true)
option("indentWithTabs", false)
option("smartIndent", true)
option("tabSize", 4, function (cm) {
resetModeState(cm)
clearCaches(cm)
regChange(cm)
}, true)
+
option("lineSeparator", null, function (cm, val) {
cm.doc.lineSep = val
if (!val) { return }
var newBreaks = [], lineNo = cm.doc.first
cm.doc.iter(function (line) {
for (var pos = 0;;) {
var found = line.text.indexOf(val, pos)
if (found == -1) { break }
@@ -9641,13 +9642,13 @@ CodeMirror.defineExtension = function (n
CodeMirror.defineDocExtension = function (name, func) {
Doc.prototype[name] = func
}
CodeMirror.fromTextArea = fromTextArea
addLegacyProps(CodeMirror)
-CodeMirror.version = "5.32.0"
+CodeMirror.version = "5.33.0"
return CodeMirror;
})));
\ No newline at end of file
--- a/devtools/client/sourceeditor/codemirror/mode/clike/clike.js
+++ b/devtools/client/sourceeditor/codemirror/mode/clike/clike.js
@@ -484,16 +484,37 @@ CodeMirror.defineMode("clike", function(
state.tokenize = null;
break;
}
escaped = stream.next() == "\\" && !escaped;
}
return "string";
}
+ function tokenNestedComment(depth) {
+ return function (stream, state) {
+ var ch
+ while (ch = stream.next()) {
+ if (ch == "*" && stream.eat("/")) {
+ if (depth == 1) {
+ state.tokenize = null
+ break
+ } else {
+ state.tokenize = tokenNestedComment(depth - 1)
+ return state.tokenize(stream, state)
+ }
+ } else if (ch == "/" && stream.eat("*")) {
+ state.tokenize = tokenNestedComment(depth + 1)
+ return state.tokenize(stream, state)
+ }
+ }
+ return "comment"
+ }
+ }
+
def("text/x-scala", {
name: "clike",
keywords: words(
/* scala */
"abstract case catch class def do else extends final finally for forSome if " +
"implicit import lazy match new null object override package private protected return " +
"sealed super this throw trait try type val var while with yield _ " +
@@ -539,16 +560,22 @@ CodeMirror.defineMode("clike", function(
"=": function(stream, state) {
var cx = state.context
if (cx.type == "}" && cx.align && stream.eat(">")) {
state.context = new Context(cx.indented, cx.column, cx.type, cx.info, null, cx.prev)
return "operator"
} else {
return false
}
+ },
+
+ "/": function(stream, state) {
+ if (!stream.eat("*")) return false
+ state.tokenize = tokenNestedComment(1)
+ return state.tokenize(stream, state)
}
},
modeProps: {closeBrackets: {triples: '"'}}
});
function tokenKotlinString(tripleString){
return function (stream, state) {
var escaped = false, next, end = false;
@@ -573,17 +600,17 @@ CodeMirror.defineMode("clike", function(
"package as typealias class interface this super val " +
"var fun for is in This throw return " +
"break continue object if else while do try when !in !is as? " +
/*soft keywords*/
"file import where by get set abstract enum open inner override private public internal " +
"protected catch finally out final vararg reified dynamic companion constructor init " +
"sealed field property receiver param sparam lateinit data inline noinline tailrec " +
- "external annotation crossinline const operator infix suspend"
+ "external annotation crossinline const operator infix suspend actual expect"
),
types: words(
/* package java.lang */
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
),
--- a/devtools/client/sourceeditor/codemirror/mode/css/css.js
+++ b/devtools/client/sourceeditor/codemirror/mode/css/css.js
@@ -72,19 +72,19 @@ CodeMirror.defineMode("css", function(co
return ret("meta", "meta");
}
} else if (/[,+>*\/]/.test(ch)) {
return ret(null, "select-op");
} else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
- } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
- (ch == "d" && stream.match("omain(")) ||
- (ch == "r" && stream.match("egexp("))) {
+ } else if (((ch == "u" || ch == "U") && stream.match(/rl(-prefix)?\(/i)) ||
+ ((ch == "d" || ch == "D") && stream.match("omain(", true, true)) ||
+ ((ch == "r" || ch == "R") && stream.match("egexp(", true, true))) {
stream.backUp(1);
state.tokenize = tokenParenthesized;
return ret("property", "word");
} else if (/[\w\\\-]/.test(ch)) {
stream.eatWhile(/[\w\\\-]/);
return ret("property", "word");
} else {
return ret(null, null);
@@ -157,26 +157,26 @@ CodeMirror.defineMode("css", function(co
var states = {};
states.top = function(type, stream, state) {
if (type == "{") {
return pushContext(state, stream, "block");
} else if (type == "}" && state.context.prev) {
return popContext(state);
- } else if (supportsAtComponent && /@component/.test(type)) {
+ } else if (supportsAtComponent && /@component/i.test(type)) {
return pushContext(state, stream, "atComponentBlock");
- } else if (/^@(-moz-)?document$/.test(type)) {
+ } else if (/^@(-moz-)?document$/i.test(type)) {
return pushContext(state, stream, "documentTypes");
- } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
+ } else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) {
return pushContext(state, stream, "atBlock");
- } else if (/^@(font-face|counter-style)/.test(type)) {
+ } else if (/^@(font-face|counter-style)/i.test(type)) {
state.stateArg = type;
return "restricted_atBlock_before";
- } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
+ } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) {
return "keyframes";
} else if (type && type.charAt(0) == "@") {
return pushContext(state, stream, "at");
} else if (type == "hash") {
override = "builtin";
} else if (type == "word") {
override = "tag";
} else if (type == "variable-definition") {
@@ -788,17 +788,17 @@ CodeMirror.defineMode("css", function(co
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
} else {
return ["operator", "operator"];
}
},
"@": function(stream) {
if (stream.eat("{")) return [null, "interpolation"];
- if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
+ if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false;
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"];
return ["variable-2", "variable"];
},
"&": function() {
return ["atom", "atom"];
}
--- a/devtools/client/sourceeditor/codemirror/mode/javascript/javascript.js
+++ b/devtools/client/sourceeditor/codemirror/mode/javascript/javascript.js
@@ -21,55 +21,28 @@ CodeMirror.defineMode("javascript", func
// Tokenizer
var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};}
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
- var jsKeywords = {
+ return {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
"debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
"await": C
};
-
- // Extend the 'normal' keywords with the TypeScript language extensions
- if (isTS) {
- var type = {type: "variable", style: "type"};
- var tsKeywords = {
- // object-like things
- "interface": kw("class"),
- "implements": C,
- "namespace": C,
-
- // scope modifiers
- "public": kw("modifier"),
- "private": kw("modifier"),
- "protected": kw("modifier"),
- "abstract": kw("modifier"),
- "readonly": kw("modifier"),
-
- // types
- "string": type, "number": type, "boolean": type, "any": type
- };
-
- for (var attr in tsKeywords) {
- jsKeywords[attr] = tsKeywords[attr];
- }
- }
-
- return jsKeywords;
}();
var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
function readRegexp(stream) {
var escaped = false, next, inSet = false;
while ((next = stream.next()) != null) {
@@ -305,16 +278,20 @@ CodeMirror.defineMode("javascript", func
state.localVars = {name: varname, next: state.localVars};
} else {
if (inList(state.globalVars)) return;
if (parserConfig.globalVars)
state.globalVars = {name: varname, next: state.globalVars};
}
}
+ function isModifier(name) {
+ return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly"
+ }
+
// Combinators
var defaultVars = {name: "this", next: {name: "arguments"}};
function pushcontext() {
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
cx.state.localVars = defaultVars;
}
function popcontext() {
@@ -361,64 +338,67 @@ CodeMirror.defineMode("javascript", func
if (type == ";") return cont();
if (type == "if") {
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
cx.state.cc.pop()();
return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
}
if (type == "function") return cont(functiondef);
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
+ if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), className, poplex); }
if (type == "variable") {
if (isTS && value == "type") {
cx.marked = "keyword"
return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
} else if (isTS && value == "declare") {
cx.marked = "keyword"
return cont(statement)
} else if (isTS && (value == "module" || value == "enum") && cx.stream.match(/^\s*\w/, false)) {
cx.marked = "keyword"
return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
+ } else if (isTS && value == "namespace") {
+ cx.marked = "keyword"
+ return cont(pushlex("form"), expression, block, poplex)
} else {
return cont(pushlex("stat"), maybelabel);
}
}
if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"),
block, poplex, poplex);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
statement, poplex, popcontext);
- if (type == "class") return cont(pushlex("form"), className, poplex);
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
if (type == "async") return cont(statement)
if (value == "@") return cont(expression, statement)
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
- function expression(type) {
- return expressionInner(type, false);
+ function expression(type, value) {
+ return expressionInner(type, value, false);
}
- function expressionNoComma(type) {
- return expressionInner(type, true);
+ function expressionNoComma(type, value) {
+ return expressionInner(type, value, true);
}
function parenExpr(type) {
if (type != "(") return pass()
return cont(pushlex(")"), expression, expect(")"), poplex)
}
- function expressionInner(type, noComma) {
+ function expressionInner(type, value, noComma) {
if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody;
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
}
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop);
- if (type == "class") return cont(pushlex("form"), classExpression, poplex);
+ if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); }
if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
if (type == "quasi") return pass(quasi, maybeop);
if (type == "new") return cont(maybeTarget(noComma));
return cont();
@@ -506,20 +486,21 @@ CodeMirror.defineMode("javascript", func
if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
cx.state.fatArrowAt = cx.stream.pos + m[0].length
return cont(afterprop);
} else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (cx.style + " property");
return cont(afterprop);
} else if (type == "jsonld-keyword") {
return cont(afterprop);
- } else if (type == "modifier") {
+ } else if (isTS && isModifier(value)) {
+ cx.marked = "keyword"
return cont(objprop)
} else if (type == "[") {
- return cont(expression, expect("]"), afterprop);
+ return cont(expression, maybetype, expect("]"), afterprop);
} else if (type == "spread") {
return cont(expressionNoComma, afterprop);
} else if (value == "*") {
cx.marked = "keyword";
return cont(objprop);
} else if (type == ":") {
return pass(afterprop)
}
@@ -611,32 +592,32 @@ CodeMirror.defineMode("javascript", func
function typearg(type) {
if (type == "variable") return cont(typearg)
else if (type == ":") return cont(typeexpr)
}
function afterType(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
if (value == "|" || type == ".") return cont(typeexpr)
if (type == "[") return cont(expect("]"), afterType)
- if (value == "extends") return cont(typeexpr)
+ if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
}
function maybeTypeArgs(_, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
}
function typeparam() {
return pass(typeexpr, maybeTypeDefault)
}
function maybeTypeDefault(_, value) {
if (value == "=") return cont(typeexpr)
}
function vardef() {
return pass(pattern, maybetype, maybeAssign, vardefCont);
}
function pattern(type, value) {
- if (type == "modifier") return cont(pattern)
+ if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
if (type == "variable") { register(value); return cont(); }
if (type == "spread") return cont(pattern);
if (type == "[") return contCommasep(pattern, "]");
if (type == "{") return contCommasep(proppattern, "}");
}
function proppattern(type, value) {
if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
register(value);
@@ -680,17 +661,18 @@ CodeMirror.defineMode("javascript", func
function functiondef(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); return cont(functiondef);}
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext);
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef)
}
function funarg(type, value) {
if (value == "@") cont(expression, funarg)
- if (type == "spread" || type == "modifier") return cont(funarg);
+ if (type == "spread") return cont(funarg);
+ if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); }
return pass(pattern, maybetype, maybeAssign);
}
function classExpression(type, value) {
// Class expressions may have an optional name.
if (type == "variable") return className(type, value);
return classNameAfter(type, value);
}
function className(type, value) {
@@ -698,29 +680,29 @@ CodeMirror.defineMode("javascript", func
}
function classNameAfter(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter)
if (value == "extends" || value == "implements" || (isTS && type == ","))
return cont(isTS ? typeexpr : expression, classNameAfter);
if (type == "{") return cont(pushlex("}"), classBody, poplex);
}
function classBody(type, value) {
- if (type == "modifier" || type == "async" ||
+ if (type == "async" ||
(type == "variable" &&
- (value == "static" || value == "get" || value == "set") &&
+ (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) &&
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
cx.marked = "keyword";
return cont(classBody);
}
if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
return cont(isTS ? classfield : functiondef, classBody);
}
if (type == "[")
- return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)
+ return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
}
if (type == ";") return cont(classBody);
if (type == "}") return cont();
if (value == "@") return cont(expression, classBody)
}
--- a/devtools/client/sourceeditor/codemirror/mode/jsx/jsx.js
+++ b/devtools/client/sourceeditor/codemirror/mode/jsx/jsx.js
@@ -21,17 +21,17 @@
function copyContext(context) {
return new Context(CodeMirror.copyState(context.mode, context.state),
context.mode,
context.depth,
context.prev && copyContext(context.prev))
}
CodeMirror.defineMode("jsx", function(config, modeConfig) {
- var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
+ var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false, allowMissingTagName: true})
var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
function flatXMLIndent(state) {
var tagName = state.tagName
state.tagName = null
var result = xmlMode.indent(state, "")
state.tagName = tagName
return result
--- a/devtools/client/sourceeditor/codemirror/mode/xml/xml.js
+++ b/devtools/client/sourceeditor/codemirror/mode/xml/xml.js
@@ -47,16 +47,17 @@ var htmlConfig = {
var xmlConfig = {
autoSelfClosers: {},
implicitlyClosed: {},
contextGrabbers: {},
doNotIndent: {},
allowUnquoted: false,
allowMissing: false,
+ allowMissingTagName: false,
caseFold: false
}
CodeMirror.defineMode("xml", function(editorConf, config_) {
var indentUnit = editorConf.indentUnit
var config = {}
var defaults = config_.htmlMode ? htmlConfig : xmlConfig
for (var prop in defaults) config[prop] = defaults[prop]
@@ -221,16 +222,19 @@ CodeMirror.defineMode("xml", function(ed
return baseState;
}
}
function tagNameState(type, stream, state) {
if (type == "word") {
state.tagName = stream.current();
setStyle = "tag";
return attrState;
+ } else if (config.allowMissingTagName && type == "endTag") {
+ setStyle = "tag bracket";
+ return attrState(type, stream, state);
} else {
setStyle = "error";
return tagNameState;
}
}
function closeTagNameState(type, stream, state) {
if (type == "word") {
var tagName = stream.current();
@@ -239,16 +243,19 @@ CodeMirror.defineMode("xml", function(ed
popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag";
return closeState;
} else {
setStyle = "tag error";
return closeStateErr;
}
+ } else if (config.allowMissingTagName && type == "endTag") {
+ setStyle = "tag bracket";
+ return closeState(type, stream, state);
} else {
setStyle = "error";
return closeStateErr;
}
}
function closeState(type, _stream, state) {
if (type != "endTag") {
--- a/devtools/client/sourceeditor/test/codemirror/mode_test.js
+++ b/devtools/client/sourceeditor/test/codemirror/mode_test.js
@@ -62,17 +62,17 @@
test.mode = function(name, mode, tokens, modeName) {
var data = parseTokens(tokens);
return test((modeName || mode.name) + "_" + name, function() {
return compare(data.plain, data.tokens, mode);
});
};
function esc(str) {
- return str.replace('&', '&').replace('<', '<').replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
+ return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
}
function compare(text, expected, mode) {
var expectedOutput = [];
for (var i = 0; i < expected.length; ++i) {
var sty = expected[i].style;
if (sty && sty.indexOf(" ")) sty = sty.split(' ').sort().join(' ');
--- a/devtools/client/sourceeditor/test/codemirror/sublime_test.js
+++ b/devtools/client/sourceeditor/test/codemirror/sublime_test.js
@@ -147,17 +147,19 @@
stTest("selectScope", "foo(a) {\n bar[1, 2];\n}",
"selectScope", hasSel(0, 0, 2, 1),
Pos(0, 4), "selectScope", hasSel(0, 4, 0, 5),
Pos(0, 5), "selectScope", hasSel(0, 4, 0, 5),
Pos(0, 6), "selectScope", hasSel(0, 0, 2, 1),
Pos(0, 8), "selectScope", hasSel(0, 8, 2, 0),
Pos(1, 2), "selectScope", hasSel(0, 8, 2, 0),
Pos(1, 6), "selectScope", hasSel(1, 6, 1, 10),
- Pos(1, 9), "selectScope", hasSel(1, 6, 1, 10));
+ Pos(1, 9), "selectScope", hasSel(1, 6, 1, 10),
+ "selectScope", hasSel(0, 8, 2, 0),
+ "selectScope", hasSel(0, 0, 2, 1));
stTest("goToBracket", "foo(a) {\n bar[1, 2];\n}",
Pos(0, 0), "goToBracket", at(0, 0),
Pos(0, 4), "goToBracket", at(0, 5), "goToBracket", at(0, 4),
Pos(0, 8), "goToBracket", at(2, 0), "goToBracket", at(0, 8),
Pos(1, 2), "goToBracket", at(2, 0),
Pos(1, 7), "goToBracket", at(1, 10), "goToBracket", at(1, 6));
@@ -214,41 +216,16 @@
setSel(0, 1, 0, 1,
0, 2, 0, 4,
0, 5, 0, 5),
"duplicateLine",
val("abcdef\nabcdcdef\nabcdcdef"), hasSel(2, 1, 2, 1,
2, 4, 2, 6,
2, 7, 2, 7));
- stTest("selectLinesUpward", "123\n345\n789\n012",
- setSel(0, 1, 0, 1,
- 1, 1, 1, 3,
- 2, 0, 2, 0,
- 3, 0, 3, 0),
- "selectLinesUpward",
- hasSel(0, 1, 0, 1,
- 0, 3, 0, 3,
- 1, 0, 1, 0,
- 1, 1, 1, 3,
- 2, 0, 2, 0,
- 3, 0, 3, 0));
-
- stTest("selectLinesDownward", "123\n345\n789\n012",
- setSel(0, 1, 0, 1,
- 1, 1, 1, 3,
- 2, 0, 2, 0,
- 3, 0, 3, 0),
- "selectLinesDownward",
- hasSel(0, 1, 0, 1,
- 1, 1, 1, 3,
- 2, 0, 2, 0,
- 2, 3, 2, 3,
- 3, 0, 3, 0));
-
stTest("sortLines", "c\nb\na\nC\nB\nA",
"sortLines", val("A\nB\nC\na\nb\nc"),
"undo",
setSel(0, 0, 2, 0,
3, 0, 5, 0),
"sortLines", val("b\nc\na\nB\nC\nA"),
hasSel(0, 0, 2, 0,
3, 0, 5, 0),
--- a/devtools/client/sourceeditor/test/codemirror/vim_test.js
+++ b/devtools/client/sourceeditor/test/codemirror/vim_test.js
@@ -4230,9 +4230,255 @@ testVim('ex_map_key2key_from_colon', fun
}, { value: 'abc' });
// Test event handlers
testVim('beforeSelectionChange', function(cm, vim, helpers) {
cm.setCursor(0, 100);
eqCursorPos(cm.getCursor('head'), cm.getCursor('anchor'));
}, { value: 'abc' });
+testVim('increment_binary', function(cm, vim, helpers) {
+ cm.setCursor(0, 4);
+ helpers.doKeys('<C-a>');
+ eq('0b001', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0b010', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0b001', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0b000', cm.getValue());
+ cm.setCursor(0, 0);
+ helpers.doKeys('<C-a>');
+ eq('0b001', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0b010', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0b001', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0b000', cm.getValue());
+}, { value: '0b000' });
+testVim('increment_octal', function(cm, vim, helpers) {
+ cm.setCursor(0, 2);
+ helpers.doKeys('<C-a>');
+ eq('001', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('002', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('003', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('004', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('005', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('006', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('007', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('010', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('007', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('006', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('005', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('004', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('003', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('002', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('001', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('000', cm.getValue());
+ cm.setCursor(0, 0);
+ helpers.doKeys('<C-a>');
+ eq('001', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('002', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('001', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('000', cm.getValue());
+}, { value: '000' });
+
+testVim('increment_decimal', function(cm, vim, helpers) {
+ cm.setCursor(0, 2);
+ helpers.doKeys('<C-a>');
+ eq('101', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('102', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('103', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('104', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('105', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('106', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('107', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('108', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('109', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('110', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('109', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('108', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('107', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('106', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('105', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('104', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('103', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('102', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('101', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('100', cm.getValue());
+ cm.setCursor(0, 0);
+ helpers.doKeys('<C-a>');
+ eq('101', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('102', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('101', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('100', cm.getValue());
+}, { value: '100' });
+
+testVim('increment_decimal_single_zero', function(cm, vim, helpers) {
+ helpers.doKeys('<C-a>');
+ eq('1', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('2', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('3', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('4', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('5', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('6', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('7', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('8', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('9', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('10', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('9', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('8', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('7', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('6', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('5', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('4', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('3', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('2', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('1', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0', cm.getValue());
+ cm.setCursor(0, 0);
+ helpers.doKeys('<C-a>');
+ eq('1', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('2', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('1', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0', cm.getValue());
+}, { value: '0' });
+
+testVim('increment_hexadecimal', function(cm, vim, helpers) {
+ cm.setCursor(0, 2);
+ helpers.doKeys('<C-a>');
+ eq('0x1', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0x2', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0x3', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0x4', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0x5', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0x6', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0x7', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0x8', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0x9', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0xa', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0xb', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0xc', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0xd', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0xe', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0xf', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0x10', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x0f', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x0e', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x0d', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x0c', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x0b', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x0a', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x09', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x08', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x07', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x06', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x05', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x04', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x03', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x02', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x01', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x00', cm.getValue());
+ cm.setCursor(0, 0);
+ helpers.doKeys('<C-a>');
+ eq('0x01', cm.getValue());
+ helpers.doKeys('<C-a>');
+ eq('0x02', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x01', cm.getValue());
+ helpers.doKeys('<C-x>');
+ eq('0x00', cm.getValue());
+}, { value: '0x0' });