diff --git a/codemirror/addon/edit/matchbrackets.js b/codemirror/addon/edit/matchbrackets.js
index 76754ed5..4d7a2308 100644
--- a/codemirror/addon/edit/matchbrackets.js
+++ b/codemirror/addon/edit/matchbrackets.js
@@ -16,12 +16,21 @@
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
- function findMatchingBracket(cm, where, strict, config) {
+ function findMatchingBracket(cm, where, config) {
var line = cm.getLineHandle(where.line), pos = where.ch - 1;
- var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
+ var afterCursor = config && config.afterCursor
+ if (afterCursor == null)
+ afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
+
+ // A cursor is defined as between two characters, but in in vim command mode
+ // (i.e. not insert mode), the cursor is visually represented as a
+ // highlighted box on top of the 2nd character. Otherwise, we allow matches
+ // from before or after the cursor.
+ var match = (!afterCursor && pos >= 0 && matching[line.text.charAt(pos)]) ||
+ matching[line.text.charAt(++pos)];
if (!match) return null;
var dir = match.charAt(1) == ">" ? 1 : -1;
- if (strict && (dir > 0) != (pos == where.ch)) return null;
+ if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
@@ -69,7 +78,7 @@
var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
var marks = [], ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
- var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config);
+ var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
@@ -113,8 +122,17 @@
});
CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
- CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){
- return findMatchingBracket(this, pos, strict, config);
+ CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
+ // Backwards-compatibility kludge
+ if (oldConfig || typeof config == "boolean") {
+ if (!oldConfig) {
+ config = config ? {strict: true} : null
+ } else {
+ oldConfig.strict = config
+ config = oldConfig
+ }
+ }
+ return findMatchingBracket(this, pos, config)
});
CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
return scanForBracket(this, pos, dir, style, config);
diff --git a/codemirror/addon/lint/lint.js b/codemirror/addon/lint/lint.js
index e5ee7477..4e0c71fb 100644
--- a/codemirror/addon/lint/lint.js
+++ b/codemirror/addon/lint/lint.js
@@ -141,6 +141,7 @@
lintAsync(cm, getAnnotations, passOptions)
} else {
var annotations = getAnnotations(cm.getValue(), passOptions, cm);
+ if (!annotations) return;
if (annotations.then) annotations.then(function(issues) {
updateLinting(cm, issues);
});
diff --git a/codemirror/addon/search/search.js b/codemirror/addon/search/search.js
index 753b1afe..236e54cc 100644
--- a/codemirror/addon/search/search.js
+++ b/codemirror/addon/search/search.js
@@ -54,7 +54,7 @@
function getSearchCursor(cm, query, pos) {
// Heuristic: if the query string is all lowercase, do a case insensitive search.
- return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
+ return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true});
}
function persistentDialog(cm, text, deflt, onEnter, onKeyDown) {
@@ -99,7 +99,7 @@
}
var queryDialog =
- 'Search: (Use /re/ syntax for regexp search)';
+ 'Search: (Use /re/ syntax for regexp search)';
function startSearch(cm, state, query) {
state.queryText = query;
@@ -188,8 +188,8 @@
var replaceQueryDialog =
' (Use /re/ syntax for regexp search)';
- var replacementQueryDialog = 'With: ';
- var doReplaceConfirm = "Replace? ";
+ var replacementQueryDialog = 'With: ';
+ var doReplaceConfirm = 'Replace? ';
function replaceAll(cm, query, text) {
cm.operation(function() {
@@ -205,7 +205,7 @@
function replace(cm, all) {
if (cm.getOption("readOnly")) return;
var query = cm.getSelection() || getSearchState(cm).lastQuery;
- var dialogText = all ? "Replace all:" : "Replace:"
+ var dialogText = '' + (all ? 'Replace all:' : 'Replace:') + '';
dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) {
if (!query) return;
query = parseQuery(query);
diff --git a/codemirror/addon/search/searchcursor.js b/codemirror/addon/search/searchcursor.js
index b70242ee..5feedd26 100644
--- a/codemirror/addon/search/searchcursor.js
+++ b/codemirror/addon/search/searchcursor.js
@@ -3,187 +3,285 @@
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
- mod(require("../../lib/codemirror"));
+ mod(require("../../lib/codemirror"))
else if (typeof define == "function" && define.amd) // AMD
- define(["../../lib/codemirror"], mod);
+ define(["../../lib/codemirror"], mod)
else // Plain browser env
- mod(CodeMirror);
+ mod(CodeMirror)
})(function(CodeMirror) {
- "use strict";
- var Pos = CodeMirror.Pos;
+ "use strict"
+ var Pos = CodeMirror.Pos
- function SearchCursor(doc, query, pos, caseFold) {
- this.atOccurrence = false; this.doc = doc;
- if (caseFold == null && typeof query == "string") caseFold = false;
+ function regexpFlags(regexp) {
+ var flags = regexp.flags
+ return flags != null ? flags : (regexp.ignoreCase ? "i" : "")
+ + (regexp.global ? "g" : "")
+ + (regexp.multiline ? "m" : "")
+ }
- pos = pos ? doc.clipPos(pos) : Pos(0, 0);
- this.pos = {from: pos, to: pos};
+ function ensureGlobal(regexp) {
+ return regexp.global ? regexp : new RegExp(regexp.source, regexpFlags(regexp) + "g")
+ }
- // The matches method is filled in based on the type of query.
- // It takes a position and a direction, and returns an object
- // describing the next occurrence of the query, or null if no
- // more matches were found.
- if (typeof query != "string") { // Regexp match
- if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g");
- this.matches = function(reverse, pos) {
- if (reverse) {
- query.lastIndex = 0;
- var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start;
- for (;;) {
- query.lastIndex = cutOff;
- var newMatch = query.exec(line);
- if (!newMatch) break;
- match = newMatch;
- start = match.index;
- cutOff = match.index + (match[0].length || 1);
- if (cutOff == line.length) break;
- }
- var matchLen = (match && match[0].length) || 0;
- if (!matchLen) {
- if (start == 0 && line.length == 0) {match = undefined;}
- else if (start != doc.getLine(pos.line).length) {
- matchLen++;
- }
- }
- } else {
- query.lastIndex = pos.ch;
- var line = doc.getLine(pos.line), match = query.exec(line);
- var matchLen = (match && match[0].length) || 0;
- var start = match && match.index;
- if (start + matchLen != line.length && !matchLen) matchLen = 1;
- }
- if (match && matchLen)
- return {from: Pos(pos.line, start),
- to: Pos(pos.line, start + matchLen),
- match: match};
- };
- } else { // String query
- var origQuery = query;
- if (caseFold) query = query.toLowerCase();
- var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
- var target = query.split("\n");
- // Different methods for single-line and multi-line queries
- if (target.length == 1) {
- if (!query.length) {
- // Empty string would match anything and never progress, so
- // we define it to match nothing instead.
- this.matches = function() {};
- } else {
- this.matches = function(reverse, pos) {
- if (reverse) {
- var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig);
- var match = line.lastIndexOf(query);
- if (match > -1) {
- match = adjustPos(orig, line, match);
- return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
- }
- } else {
- var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig);
- var match = line.indexOf(query);
- if (match > -1) {
- match = adjustPos(orig, line, match) + pos.ch;
- return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
- }
- }
- };
- }
- } else {
- var origTarget = origQuery.split("\n");
- this.matches = function(reverse, pos) {
- var last = target.length - 1;
- if (reverse) {
- if (pos.line - (target.length - 1) < doc.firstLine()) return;
- if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return;
- var to = Pos(pos.line, origTarget[last].length);
- for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln)
- if (target[i] != fold(doc.getLine(ln))) return;
- var line = doc.getLine(ln), cut = line.length - origTarget[0].length;
- if (fold(line.slice(cut)) != target[0]) return;
- return {from: Pos(ln, cut), to: to};
- } else {
- if (pos.line + (target.length - 1) > doc.lastLine()) return;
- var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length;
- if (fold(line.slice(cut)) != target[0]) return;
- var from = Pos(pos.line, cut);
- for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)
- if (target[i] != fold(doc.getLine(ln))) return;
- if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return;
- return {from: from, to: Pos(ln, origTarget[last].length)};
- }
- };
+ function maybeMultiline(regexp) {
+ return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source)
+ }
+
+ function searchRegexpForward(doc, regexp, start) {
+ regexp = ensureGlobal(regexp)
+ for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) {
+ regexp.lastIndex = ch
+ var string = doc.getLine(line), match = regexp.exec(string)
+ if (match)
+ return {from: Pos(line, match.index),
+ to: Pos(line, match.index + match[0].length),
+ match: match}
+ }
+ }
+
+ function searchRegexpForwardMultiline(doc, regexp, start) {
+ if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start)
+
+ regexp = ensureGlobal(regexp)
+ var string, chunk = 1
+ for (var line = start.line, last = doc.lastLine(); line <= last;) {
+ // This grows the search buffer in exponentially-sized chunks
+ // between matches, so that nearby matches are fast and don't
+ // require concatenating the whole document (in case we're
+ // searching for something that has tons of matches), but at the
+ // same time, the amount of retries is limited.
+ for (var i = 0; i < chunk; i++) {
+ var curLine = doc.getLine(line++)
+ string = string == null ? curLine : string + "\n" + curLine
}
+ chunk = chunk * 2
+ regexp.lastIndex = start.ch
+ var match = regexp.exec(string)
+ if (match) {
+ var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
+ var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length
+ return {from: Pos(startLine, startCh),
+ to: Pos(startLine + inside.length - 1,
+ inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
+ match: match}
+ }
+ }
+ }
+
+ function lastMatchIn(string, regexp) {
+ var cutOff = 0, match
+ for (;;) {
+ regexp.lastIndex = cutOff
+ var newMatch = regexp.exec(string)
+ if (!newMatch) return match
+ match = newMatch
+ cutOff = match.index + (match[0].length || 1)
+ if (cutOff == string.length) return match
+ }
+ }
+
+ function searchRegexpBackward(doc, regexp, start) {
+ regexp = ensureGlobal(regexp)
+ for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) {
+ var string = doc.getLine(line)
+ if (ch > -1) string = string.slice(0, ch)
+ var match = lastMatchIn(string, regexp)
+ if (match)
+ return {from: Pos(line, match.index),
+ to: Pos(line, match.index + match[0].length),
+ match: match}
+ }
+ }
+
+ function searchRegexpBackwardMultiline(doc, regexp, start) {
+ regexp = ensureGlobal(regexp)
+ var string, chunk = 1
+ for (var line = start.line, first = doc.firstLine(); line >= first;) {
+ for (var i = 0; i < chunk; i++) {
+ var curLine = doc.getLine(line--)
+ string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string
+ }
+ chunk *= 2
+
+ var match = lastMatchIn(string, regexp)
+ if (match) {
+ var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
+ var startLine = line + before.length, startCh = before[before.length - 1].length
+ return {from: Pos(startLine, startCh),
+ to: Pos(startLine + inside.length - 1,
+ inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
+ match: match}
+ }
+ }
+ }
+
+ var doFold, noFold
+ if (String.prototype.normalize) {
+ doFold = function(str) { return str.normalize("NFD").toLowerCase() }
+ noFold = function(str) { return str.normalize("NFD") }
+ } else {
+ doFold = function(str) { return str.toLowerCase() }
+ noFold = function(str) { return str }
+ }
+
+ // Maps a position in a case-folded line back to a position in the original line
+ // (compensating for codepoints increasing in number during folding)
+ function adjustPos(orig, folded, pos, foldFunc) {
+ if (orig.length == folded.length) return pos
+ for (var pos1 = Math.min(pos, orig.length);;) {
+ var len1 = foldFunc(orig.slice(0, pos1)).length
+ if (len1 < pos) ++pos1
+ else if (len1 > pos) --pos1
+ else return pos1
+ }
+ }
+
+ function searchStringForward(doc, query, start, caseFold) {
+ // Empty string would match anything and never progress, so we
+ // define it to match nothing instead.
+ if (!query.length) return null
+ var fold = caseFold ? doFold : noFold
+ var lines = fold(query).split(/\r|\n\r?/)
+
+ search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) {
+ var orig = doc.getLine(line).slice(ch), string = fold(orig)
+ if (lines.length == 1) {
+ var found = string.indexOf(lines[0])
+ if (found == -1) continue search
+ var start = adjustPos(orig, string, found, fold) + ch
+ return {from: Pos(line, adjustPos(orig, string, found, fold) + ch),
+ to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold) + ch)}
+ } else {
+ var cutFrom = string.length - lines[0].length
+ if (string.slice(cutFrom) != lines[0]) continue search
+ for (var i = 1; i < lines.length - 1; i++)
+ if (fold(doc.getLine(line + i)) != lines[i]) continue search
+ var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1]
+ if (end.slice(0, lastLine.length) != lastLine) continue search
+ return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch),
+ to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))}
+ }
+ }
+ }
+
+ function searchStringBackward(doc, query, start, caseFold) {
+ if (!query.length) return null
+ var fold = caseFold ? doFold : noFold
+ var lines = fold(query).split(/\r|\n\r?/)
+
+ search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) {
+ var orig = doc.getLine(line)
+ if (ch > -1) orig = orig.slice(0, ch)
+ var string = fold(orig)
+ if (lines.length == 1) {
+ var found = string.lastIndexOf(lines[0])
+ if (found == -1) continue search
+ return {from: Pos(line, adjustPos(orig, string, found, fold)),
+ to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold))}
+ } else {
+ var lastLine = lines[lines.length - 1]
+ if (string.slice(0, lastLine.length) != lastLine) continue search
+ for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++)
+ if (fold(doc.getLine(start + i)) != lines[i]) continue search
+ var top = doc.getLine(line + 1 - lines.length), topString = fold(top)
+ if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search
+ return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length, fold)),
+ to: Pos(line, adjustPos(orig, string, lastLine.length, fold))}
+ }
+ }
+ }
+
+ function SearchCursor(doc, query, pos, options) {
+ this.atOccurrence = false
+ this.doc = doc
+ pos = pos ? doc.clipPos(pos) : Pos(0, 0)
+ this.pos = {from: pos, to: pos}
+
+ var caseFold
+ if (typeof options == "object") {
+ caseFold = options.caseFold
+ } else { // Backwards compat for when caseFold was the 4th argument
+ caseFold = options
+ options = null
+ }
+
+ if (typeof query == "string") {
+ if (caseFold == null) caseFold = false
+ this.matches = function(reverse, pos) {
+ return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold)
+ }
+ } else {
+ query = ensureGlobal(query)
+ if (!options || options.multiline !== false)
+ this.matches = function(reverse, pos) {
+ return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos)
+ }
+ else
+ this.matches = function(reverse, pos) {
+ return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos)
+ }
}
}
SearchCursor.prototype = {
- findNext: function() {return this.find(false);},
- findPrevious: function() {return this.find(true);},
+ findNext: function() {return this.find(false)},
+ findPrevious: function() {return this.find(true)},
find: function(reverse) {
- var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);
- function savePosAndFail(line) {
- var pos = Pos(line, 0);
- self.pos = {from: pos, to: pos};
- self.atOccurrence = false;
- return false;
+ var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
+
+ // Implements weird auto-growing behavior on null-matches for
+ // backwards-compatiblity with the vim code (unfortunately)
+ while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
+ if (reverse) {
+ if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)
+ else if (result.from.line == this.doc.firstLine()) result = null
+ else result = this.matches(reverse, this.doc.clipPos(Pos(result.from.line - 1)))
+ } else {
+ if (result.to.ch < this.doc.getLine(result.to.line).length) result.to = Pos(result.to.line, result.to.ch + 1)
+ else if (result.to.line == this.doc.lastLine()) result = null
+ else result = this.matches(reverse, Pos(result.to.line + 1, 0))
+ }
}
- for (;;) {
- if (this.pos = this.matches(reverse, pos)) {
- this.atOccurrence = true;
- return this.pos.match || true;
- }
- if (reverse) {
- if (!pos.line) return savePosAndFail(0);
- pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length);
- }
- else {
- var maxLine = this.doc.lineCount();
- if (pos.line == maxLine - 1) return savePosAndFail(maxLine);
- pos = Pos(pos.line + 1, 0);
- }
+ if (result) {
+ this.pos = result
+ this.atOccurrence = true
+ return this.pos.match || true
+ } else {
+ var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0)
+ this.pos = {from: end, to: end}
+ return this.atOccurrence = false
}
},
- from: function() {if (this.atOccurrence) return this.pos.from;},
- to: function() {if (this.atOccurrence) return this.pos.to;},
+ from: function() {if (this.atOccurrence) return this.pos.from},
+ to: function() {if (this.atOccurrence) return this.pos.to},
replace: function(newText, origin) {
- if (!this.atOccurrence) return;
- var lines = CodeMirror.splitLines(newText);
- this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin);
+ if (!this.atOccurrence) return
+ var lines = CodeMirror.splitLines(newText)
+ this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin)
this.pos.to = Pos(this.pos.from.line + lines.length - 1,
- lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));
- }
- };
-
- // Maps a position in a case-folded line back to a position in the original line
- // (compensating for codepoints increasing in number during folding)
- function adjustPos(orig, folded, pos) {
- if (orig.length == folded.length) return pos;
- for (var pos1 = Math.min(pos, orig.length);;) {
- var len1 = orig.slice(0, pos1).toLowerCase().length;
- if (len1 < pos) ++pos1;
- else if (len1 > pos) --pos1;
- else return pos1;
+ lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0))
}
}
CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
- return new SearchCursor(this.doc, query, pos, caseFold);
- });
+ return new SearchCursor(this.doc, query, pos, caseFold)
+ })
CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
- return new SearchCursor(this, query, pos, caseFold);
- });
+ return new SearchCursor(this, query, pos, caseFold)
+ })
CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
- var ranges = [];
- var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold);
+ var ranges = []
+ var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold)
while (cur.findNext()) {
- if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break;
- ranges.push({anchor: cur.from(), head: cur.to()});
+ if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break
+ ranges.push({anchor: cur.from(), head: cur.to()})
}
if (ranges.length)
- this.setSelections(ranges, 0);
- });
+ this.setSelections(ranges, 0)
+ })
});
diff --git a/codemirror/keymap/emacs.js b/codemirror/keymap/emacs.js
index 2d5fe1b8..63da52fa 100644
--- a/codemirror/keymap/emacs.js
+++ b/codemirror/keymap/emacs.js
@@ -97,7 +97,7 @@
function byExpr(cm, pos, dir) {
var wrap;
- if (cm.findMatchingBracket && (wrap = cm.findMatchingBracket(pos, true))
+ if (cm.findMatchingBracket && (wrap = cm.findMatchingBracket(pos, {strict: true}))
&& wrap.match && (wrap.forward ? 1 : -1) == dir)
return dir > 0 ? Pos(wrap.to.line, wrap.to.ch + 1) : wrap.to;
diff --git a/codemirror/keymap/vim.js b/codemirror/keymap/vim.js
index b2c404d4..d8a2d60d 100644
--- a/codemirror/keymap/vim.js
+++ b/codemirror/keymap/vim.js
@@ -259,7 +259,7 @@
CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor");
if (!next || next.attach != attachVimMap)
- leaveVimMode(cm, false);
+ leaveVimMode(cm);
}
function attachVimMap(cm, prev) {
if (this == CodeMirror.keyMap.vim)
@@ -411,11 +411,11 @@
cfg = cfg || {};
var scope = cfg.scope;
if (!option) {
- throw Error('Unknown option: ' + name);
+ return new Error('Unknown option: ' + name);
}
if (option.type == 'boolean') {
if (value && value !== true) {
- throw Error('Invalid argument: ' + name + '=' + value);
+ return new Error('Invalid argument: ' + name + '=' + value);
} else if (value !== false) {
// Boolean options are set to true if value is not defined.
value = true;
@@ -443,7 +443,7 @@
cfg = cfg || {};
var scope = cfg.scope;
if (!option) {
- throw Error('Unknown option: ' + name);
+ return new Error('Unknown option: ' + name);
}
if (option.callback) {
var local = cm && option.callback(undefined, cm);
@@ -649,9 +649,9 @@
lastCharacterSearch: {increment:0, forward:true, selectedCharacter:''},
registerController: new RegisterController({}),
// search history buffer
- searchHistoryController: new HistoryController({}),
+ searchHistoryController: new HistoryController(),
// ex Command history buffer
- exCommandHistoryController : new HistoryController({})
+ exCommandHistoryController : new HistoryController()
};
for (var optionName in options) {
var option = options[optionName];
@@ -958,7 +958,7 @@
* for a reference implementation.
*/
function defineRegister(name, register) {
- var registers = vimGlobalState.registerController.registers[name];
+ var registers = vimGlobalState.registerController.registers;
if (!name || name.length != 1) {
throw Error('Register name must be 1 character');
}
@@ -986,9 +986,6 @@
}
RegisterController.prototype = {
pushText: function(registerName, operator, text, linewise, blockwise) {
- if (linewise && text.charAt(0) == '\n') {
- text = text.slice(1) + '\n';
- }
if (linewise && text.charAt(text.length - 1) !== '\n'){
text += '\n';
}
@@ -1110,7 +1107,9 @@
}
}
if (bestMatch.keys.slice(-11) == '') {
- inputState.selectedCharacter = lastChar(keys);
+ var character = lastChar(keys);
+ if (!character) return {type: 'none'};
+ inputState.selectedCharacter = character;
}
return {type: 'full', command: bestMatch};
},
@@ -1836,16 +1835,16 @@
var ch = cursor.ch;
var lineText = cm.getLine(line);
var symbol;
- do {
- symbol = lineText.charAt(ch++);
+ for (; ch < lineText.length; ch++) {
+ symbol = lineText.charAt(ch);
if (symbol && isMatchableSymbol(symbol)) {
- var style = cm.getTokenTypeAt(Pos(line, ch));
+ var style = cm.getTokenTypeAt(Pos(line, ch + 1));
if (style !== "string" && style !== "comment") {
break;
}
}
- } while (symbol);
- if (symbol) {
+ }
+ if (ch < lineText.length) {
var matched = cm.findMatchingBracket(Pos(line, ch));
return matched.to;
} else {
@@ -2186,7 +2185,9 @@
enterMacroRecordMode: function(cm, actionArgs) {
var macroModeState = vimGlobalState.macroModeState;
var registerName = actionArgs.selectedCharacter;
- macroModeState.enterMacroRecordMode(cm, registerName);
+ if (vimGlobalState.registerController.isValidRegister(registerName)) {
+ macroModeState.enterMacroRecordMode(cm, registerName);
+ }
},
toggleOverwrite: function(cm) {
if (!cm.state.overwrite) {
@@ -2704,7 +2705,7 @@
}
}
function lastChar(keys) {
- var match = /^.*(<[\w\-]+>)$/.exec(keys);
+ var match = /^.*(<[^>]+>)$/.exec(keys);
var selectedCharacter = match ? match[1] : keys.slice(-1);
if (selectedCharacter.length > 1){
switch(selectedCharacter){
@@ -2715,6 +2716,7 @@
selectedCharacter=' ';
break;
default:
+ selectedCharacter='';
break;
}
}
@@ -2815,7 +2817,6 @@
var range = {anchor: new Pos(line, baseCh), head: new Pos(line, headCh)};
selections.push(range);
}
- primIndex = head.line == lastLine ? selections.length - 1 : 0;
cm.setSelections(selections);
selectionEnd.ch = headCh;
base.ch = baseCh;
@@ -4083,23 +4084,42 @@
parseLineSpec_: function(cm, inputStream) {
var numberMatch = inputStream.match(/^(\d+)/);
if (numberMatch) {
+ // Absolute line number plus offset (N+M or N-M) is probably a typo,
+ // not something the user actually wanted. (NB: vim does allow this.)
return parseInt(numberMatch[1], 10) - 1;
}
switch (inputStream.next()) {
case '.':
- return cm.getCursor().line;
+ return this.parseLineSpecOffset_(inputStream, cm.getCursor().line);
case '$':
- return cm.lastLine();
+ return this.parseLineSpecOffset_(inputStream, cm.lastLine());
case '\'':
var markName = inputStream.next();
var markPos = getMarkPos(cm, cm.state.vim, markName);
if (!markPos) throw new Error('Mark not set');
- return markPos.line;
+ return this.parseLineSpecOffset_(inputStream, markPos.line);
+ case '-':
+ case '+':
+ inputStream.backUp(1);
+ // Offset is relative to current line if not otherwise specified.
+ return this.parseLineSpecOffset_(inputStream, cm.getCursor().line);
default:
inputStream.backUp(1);
return undefined;
}
},
+ parseLineSpecOffset_: function(inputStream, line) {
+ var offsetMatch = inputStream.match(/^([+-])?(\d+)/);
+ if (offsetMatch) {
+ var offset = parseInt(offsetMatch[2], 10);
+ if (offsetMatch[1] == "-") {
+ line -= offset;
+ } else {
+ line += offset;
+ }
+ }
+ return line;
+ },
parseCommandArgs_: function(inputStream, params, command) {
if (inputStream.eol()) {
return;
@@ -4279,13 +4299,18 @@
// If no value is provided, then we assume this is a get.
if (!optionIsBoolean && value === undefined || forceGet) {
var oldValue = getOption(optionName, cm, setCfg);
- if (oldValue === true || oldValue === false) {
+ if (oldValue instanceof Error) {
+ showConfirm(cm, oldValue.message);
+ } else if (oldValue === true || oldValue === false) {
showConfirm(cm, ' ' + (oldValue ? '' : 'no') + optionName);
} else {
showConfirm(cm, ' ' + optionName + '=' + oldValue);
}
} else {
- setOption(optionName, value, cm, setCfg);
+ var setOptionReturn = setOption(optionName, value, cm, setCfg);
+ if (setOptionReturn instanceof Error) {
+ showConfirm(cm, setOptionReturn.message);
+ }
}
},
setlocal: function (cm, params) {
@@ -4484,6 +4509,10 @@
if (tokens.length) {
regexPart = tokens[0];
replacePart = tokens[1];
+ if (regexPart && regexPart[regexPart.length - 1] === '$') {
+ regexPart = regexPart.slice(0, regexPart.length - 1) + '\\n';
+ replacePart = replacePart ? replacePart + '\n' : '\n';
+ }
if (replacePart !== undefined) {
if (getOption('pcre')) {
replacePart = unescapeRegexReplace(replacePart);
@@ -4903,7 +4932,7 @@
* Listens for changes made in insert mode.
* Should only be active in insert mode.
*/
- function onChange(_cm, changeObj) {
+ function onChange(cm, changeObj) {
var macroModeState = vimGlobalState.macroModeState;
var lastChange = macroModeState.lastInsertModeChanges;
if (!macroModeState.isPlaying) {
@@ -4916,7 +4945,11 @@
lastChange.changes = [];
lastChange.maybeReset = false;
}
- lastChange.changes.push(text);
+ if (cm.state.overwrite && !/\n/.test(text)) {
+ lastChange.changes.push([text]);
+ } else {
+ lastChange.changes.push(text);
+ }
}
// Change objects may be chained with next.
changeObj = changeObj.next;
@@ -5098,9 +5131,13 @@
var change = changes[j];
if (change instanceof InsertModeKey) {
CodeMirror.lookupKey(change.keyName, 'vim-insert', keyHandler);
- } else {
+ } else if (typeof change == "string") {
var cur = cm.getCursor();
cm.replaceRange(change, cur, cur);
+ } else {
+ var start = cm.getCursor();
+ var end = offsetCursor(start, 0, change[0].length);
+ cm.replaceRange(change[0], start, end);
}
}
}
diff --git a/codemirror/lib/codemirror.css b/codemirror/lib/codemirror.css
index b962b383..b008351a 100644
--- a/codemirror/lib/codemirror.css
+++ b/codemirror/lib/codemirror.css
@@ -119,7 +119,7 @@
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
-.cm-s-default .cm-variable-3 {color: #085;}
+.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
diff --git a/codemirror/mode/css/css.js b/codemirror/mode/css/css.js
index 02cc93d9..056c48e6 100644
--- a/codemirror/mode/css/css.js
+++ b/codemirror/mode/css/css.js
@@ -401,7 +401,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
// Dedent relative to current context.
indent = Math.max(0, cx.indent - indentUnit);
- cx = cx.prev;
}
}
return indent;
@@ -472,7 +471,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"border-top-left-radius", "border-top-right-radius", "border-top-style",
"border-top-width", "border-width", "bottom", "box-decoration-break",
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
- "caption-side", "clear", "clip", "color", "color-profile", "column-count",
+ "caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count",
"column-fill", "column-gap", "column-rule", "column-rule-color",
"column-rule-style", "column-rule-width", "column-span", "column-width",
"columns", "content", "counter-increment", "counter-reset", "crop", "cue",
@@ -493,7 +492,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
"grid-template-rows", "hanging-punctuation", "height", "hyphens",
"icon", "image-orientation", "image-rendering", "image-resolution",
- "inline-box-align", "justify-content", "left", "letter-spacing",
+ "inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing",
"line-break", "line-height", "line-stacking", "line-stacking-ruby",
"line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin",
@@ -508,7 +507,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
"page", "page-break-after", "page-break-before", "page-break-inside",
"page-policy", "pause", "pause-after", "pause-before", "perspective",
- "perspective-origin", "pitch", "pitch-range", "play-during", "position",
+ "perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position",
"presentation-level", "punctuation-trim", "quotes", "region-break-after",
"region-break-before", "region-break-inside", "region-fragment",
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
@@ -659,13 +658,13 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
"scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
- "searchfield-results-button", "searchfield-results-decoration",
+ "searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
"simp-chinese-formal", "simp-chinese-informal", "single",
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
- "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
+ "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
"square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
"table-caption", "table-cell", "table-column", "table-column-group",
@@ -748,8 +747,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
}
},
":": function(stream) {
- if (stream.match(/\s*\{/))
- return [null, "{"];
+ if (stream.match(/\s*\{/, false))
+ return [null, null]
return false;
},
"$": function(stream) {
diff --git a/codemirror/theme/abcdef.css b/codemirror/theme/abcdef.css
index 7f9d7887..cf935309 100644
--- a/codemirror/theme/abcdef.css
+++ b/codemirror/theme/abcdef.css
@@ -14,7 +14,7 @@
.cm-s-abcdef span.cm-def { color: #fffabc; }
.cm-s-abcdef span.cm-variable { color: #abcdef; }
.cm-s-abcdef span.cm-variable-2 { color: #cacbcc; }
-.cm-s-abcdef span.cm-variable-3 { color: #def; }
+.cm-s-abcdef span.cm-variable-3, .cm-s-abcdef span.cm-type { color: #def; }
.cm-s-abcdef span.cm-property { color: #fedcba; }
.cm-s-abcdef span.cm-operator { color: #ff0; }
.cm-s-abcdef span.cm-comment { color: #7a7b7c; font-style: italic;}
diff --git a/codemirror/theme/ambiance.css b/codemirror/theme/ambiance.css
index bce34464..782fca43 100644
--- a/codemirror/theme/ambiance.css
+++ b/codemirror/theme/ambiance.css
@@ -11,7 +11,7 @@
.cm-s-ambiance .cm-def { color: #aac6e3; }
.cm-s-ambiance .cm-variable { color: #ffb795; }
.cm-s-ambiance .cm-variable-2 { color: #eed1b3; }
-.cm-s-ambiance .cm-variable-3 { color: #faded3; }
+.cm-s-ambiance .cm-variable-3, .cm-s-ambiance .cm-type { color: #faded3; }
.cm-s-ambiance .cm-property { color: #eed1b3; }
.cm-s-ambiance .cm-operator { color: #fa8d6a; }
.cm-s-ambiance .cm-comment { color: #555; font-style:italic; }
diff --git a/codemirror/theme/cobalt.css b/codemirror/theme/cobalt.css
index d88223ed..bbbda3b5 100644
--- a/codemirror/theme/cobalt.css
+++ b/codemirror/theme/cobalt.css
@@ -15,7 +15,7 @@
.cm-s-cobalt span.cm-string { color: #3ad900; }
.cm-s-cobalt span.cm-meta { color: #ff9d00; }
.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
-.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def { color: white; }
+.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def, .cm-s-cobalt .cm-type { color: white; }
.cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
.cm-s-cobalt span.cm-link { color: #845dc4; }
diff --git a/codemirror/theme/colorforth.css b/codemirror/theme/colorforth.css
index 606899f3..19095e41 100644
--- a/codemirror/theme/colorforth.css
+++ b/codemirror/theme/colorforth.css
@@ -15,7 +15,7 @@
.cm-s-colorforth span.cm-atom { color: #606060; }
.cm-s-colorforth span.cm-variable-2 { color: #EEE; }
-.cm-s-colorforth span.cm-variable-3 { color: #DDD; }
+.cm-s-colorforth span.cm-variable-3, .cm-s-colorforth span.cm-type { color: #DDD; }
.cm-s-colorforth span.cm-property {}
.cm-s-colorforth span.cm-operator {}
diff --git a/codemirror/theme/dracula.css b/codemirror/theme/dracula.css
index 53a660b5..253133ef 100644
--- a/codemirror/theme/dracula.css
+++ b/codemirror/theme/dracula.css
@@ -34,7 +34,7 @@
.cm-s-dracula span.cm-qualifier { color: #50fa7b; }
.cm-s-dracula span.cm-property { color: #66d9ef; }
.cm-s-dracula span.cm-builtin { color: #50fa7b; }
-.cm-s-dracula span.cm-variable-3 { color: #ffb86c; }
+.cm-s-dracula span.cm-variable-3, .cm-s-dracula span.cm-type { color: #ffb86c; }
.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }
.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/codemirror/theme/duotone-dark.css b/codemirror/theme/duotone-dark.css
index b09a585c..88fdc76c 100644
--- a/codemirror/theme/duotone-dark.css
+++ b/codemirror/theme/duotone-dark.css
@@ -24,7 +24,7 @@ CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bra
.cm-s-duotone-dark span.cm-operator { color: #ffad5c; }
.cm-s-duotone-dark span.cm-positive { color: #6a51e6; }
-.cm-s-duotone-dark span.cm-variable-2, .cm-s-duotone-dark span.cm-variable-3, .cm-s-duotone-dark span.cm-string-2, .cm-s-duotone-dark span.cm-url { color: #7a63ee; }
+.cm-s-duotone-dark span.cm-variable-2, .cm-s-duotone-dark span.cm-variable-3, .cm-s-duotone-dark span.cm-type, .cm-s-duotone-dark span.cm-string-2, .cm-s-duotone-dark span.cm-url { color: #7a63ee; }
.cm-s-duotone-dark span.cm-def, .cm-s-duotone-dark span.cm-tag, .cm-s-duotone-dark span.cm-builtin, .cm-s-duotone-dark span.cm-qualifier, .cm-s-duotone-dark span.cm-header, .cm-s-duotone-dark span.cm-em { color: #eeebff; }
.cm-s-duotone-dark span.cm-bracket, .cm-s-duotone-dark span.cm-comment { color: #6c6783; }
diff --git a/codemirror/theme/duotone-light.css b/codemirror/theme/duotone-light.css
index 80203d15..d99480f7 100644
--- a/codemirror/theme/duotone-light.css
+++ b/codemirror/theme/duotone-light.css
@@ -23,7 +23,7 @@ CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bra
.cm-s-duotone-light span.cm-string, .cm-s-duotone-light span.cm-operator { color: #1659df; }
.cm-s-duotone-light span.cm-positive { color: #896724; }
-.cm-s-duotone-light span.cm-variable-2, .cm-s-duotone-light span.cm-variable-3, .cm-s-duotone-light span.cm-string-2, .cm-s-duotone-light span.cm-url { color: #896724; }
+.cm-s-duotone-light span.cm-variable-2, .cm-s-duotone-light span.cm-variable-3, .cm-s-duotone-light span.cm-type, .cm-s-duotone-light span.cm-string-2, .cm-s-duotone-light span.cm-url { color: #896724; }
.cm-s-duotone-light span.cm-def, .cm-s-duotone-light span.cm-tag, .cm-s-duotone-light span.cm-builtin, .cm-s-duotone-light span.cm-qualifier, .cm-s-duotone-light span.cm-header, .cm-s-duotone-light span.cm-em { color: #2d2006; }
.cm-s-duotone-light span.cm-bracket, .cm-s-duotone-light span.cm-comment { color: #b6ad9a; }
diff --git a/codemirror/theme/eclipse.css b/codemirror/theme/eclipse.css
index 1bde460e..800d603f 100644
--- a/codemirror/theme/eclipse.css
+++ b/codemirror/theme/eclipse.css
@@ -5,7 +5,7 @@
.cm-s-eclipse span.cm-def { color: #00f; }
.cm-s-eclipse span.cm-variable { color: black; }
.cm-s-eclipse span.cm-variable-2 { color: #0000C0; }
-.cm-s-eclipse span.cm-variable-3 { color: #0000C0; }
+.cm-s-eclipse span.cm-variable-3, .cm-s-eclipse span.cm-type { color: #0000C0; }
.cm-s-eclipse span.cm-property { color: black; }
.cm-s-eclipse span.cm-operator { color: black; }
.cm-s-eclipse span.cm-comment { color: #3F7F5F; }
diff --git a/codemirror/theme/erlang-dark.css b/codemirror/theme/erlang-dark.css
index 65fe4814..8c8a4171 100644
--- a/codemirror/theme/erlang-dark.css
+++ b/codemirror/theme/erlang-dark.css
@@ -27,7 +27,7 @@
.cm-s-erlang-dark span.cm-tag { color: #9effff; }
.cm-s-erlang-dark span.cm-variable { color: #50fe50; }
.cm-s-erlang-dark span.cm-variable-2 { color: #e0e; }
-.cm-s-erlang-dark span.cm-variable-3 { color: #ccc; }
+.cm-s-erlang-dark span.cm-variable-3, .cm-s-erlang-dark span.cm-type { color: #ccc; }
.cm-s-erlang-dark span.cm-error { color: #9d1e15; }
.cm-s-erlang-dark .CodeMirror-activeline-background { background: #013461; }
diff --git a/codemirror/theme/icecoder.css b/codemirror/theme/icecoder.css
index ffebaf2f..5440fbe2 100644
--- a/codemirror/theme/icecoder.css
+++ b/codemirror/theme/icecoder.css
@@ -11,7 +11,7 @@ ICEcoder default theme by Matt Pass, used in code editor available at https://ic
.cm-s-icecoder span.cm-variable { color: #6cb5d9; } /* blue */
.cm-s-icecoder span.cm-variable-2 { color: #cc1e5c; } /* pink */
-.cm-s-icecoder span.cm-variable-3 { color: #f9602c; } /* orange */
+.cm-s-icecoder span.cm-variable-3, .cm-s-icecoder span.cm-type { color: #f9602c; } /* orange */
.cm-s-icecoder span.cm-property { color: #eee; } /* off-white 1 */
.cm-s-icecoder span.cm-operator { color: #9179bb; } /* purple */
diff --git a/codemirror/theme/lesser-dark.css b/codemirror/theme/lesser-dark.css
index 690c183d..b2ec418f 100644
--- a/codemirror/theme/lesser-dark.css
+++ b/codemirror/theme/lesser-dark.css
@@ -27,7 +27,7 @@ Ported to CodeMirror by Peter Kroon
.cm-s-lesser-dark span.cm-def { color: white; }
.cm-s-lesser-dark span.cm-variable { color:#D9BF8C; }
.cm-s-lesser-dark span.cm-variable-2 { color: #669199; }
-.cm-s-lesser-dark span.cm-variable-3 { color: white; }
+.cm-s-lesser-dark span.cm-variable-3, .cm-s-lesser-dark span.cm-type { color: white; }
.cm-s-lesser-dark span.cm-property { color: #92A75C; }
.cm-s-lesser-dark span.cm-operator { color: #92A75C; }
.cm-s-lesser-dark span.cm-comment { color: #666; }
diff --git a/codemirror/theme/liquibyte.css b/codemirror/theme/liquibyte.css
index 9db8bde7..393825e0 100644
--- a/codemirror/theme/liquibyte.css
+++ b/codemirror/theme/liquibyte.css
@@ -36,7 +36,7 @@
.cm-s-liquibyte span.cm-atom { color: #bf3030; font-weight: bold; }
.cm-s-liquibyte span.cm-variable-2 { color: #007f7f; font-weight: bold; }
-.cm-s-liquibyte span.cm-variable-3 { color: #c080ff; font-weight: bold; }
+.cm-s-liquibyte span.cm-variable-3, .cm-s-liquibyte span.cm-type { color: #c080ff; font-weight: bold; }
.cm-s-liquibyte span.cm-property { color: #999; font-weight: bold; }
.cm-s-liquibyte span.cm-operator { color: #fff; }
@@ -59,10 +59,10 @@
.CodeMirror-matchingtag { background-color: rgba(150, 255, 0, .3); }
/* Scrollbars */
/* Simple */
-.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div:hover, div.CodeMirror-simplescroll-vertical div:hover {
+.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div:hover, .cm-s-liquibyte div.CodeMirror-simplescroll-vertical div:hover {
background-color: rgba(80, 80, 80, .7);
}
-.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div, div.CodeMirror-simplescroll-vertical div {
+.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div, .cm-s-liquibyte div.CodeMirror-simplescroll-vertical div {
background-color: rgba(80, 80, 80, .3);
border: 1px solid #404040;
border-radius: 5px;
diff --git a/codemirror/theme/material.css b/codemirror/theme/material.css
index 01d86793..84962a24 100644
--- a/codemirror/theme/material.css
+++ b/codemirror/theme/material.css
@@ -27,7 +27,7 @@
.cm-s-material .cm-keyword { color: rgba(199, 146, 234, 1); }
.cm-s-material .cm-operator { color: rgba(233, 237, 237, 1); }
.cm-s-material .cm-variable-2 { color: #80CBC4; }
-.cm-s-material .cm-variable-3 { color: #82B1FF; }
+.cm-s-material .cm-variable-3, .cm-s-material .cm-type { color: #82B1FF; }
.cm-s-material .cm-builtin { color: #DECB6B; }
.cm-s-material .cm-atom { color: #F77669; }
.cm-s-material .cm-number { color: #F77669; }
@@ -41,7 +41,7 @@
.cm-s-material .cm-attribute { color: #FFCB6B; }
.cm-s-material .cm-property { color: #80CBAE; }
.cm-s-material .cm-qualifier { color: #DECB6B; }
-.cm-s-material .cm-variable-3 { color: #DECB6B; }
+.cm-s-material .cm-variable-3, .cm-s-material .cm-type { color: #DECB6B; }
.cm-s-material .cm-tag { color: rgba(255, 83, 112, 1); }
.cm-s-material .cm-error {
color: rgba(255, 255, 255, 1.0);
diff --git a/codemirror/theme/mdn-like.css b/codemirror/theme/mdn-like.css
index f325d450..622ed3ef 100644
--- a/codemirror/theme/mdn-like.css
+++ b/codemirror/theme/mdn-like.css
@@ -21,7 +21,7 @@
.cm-s-mdn-like .cm-number { color: #ca7841; }
.cm-s-mdn-like .cm-def { color: #8DA6CE; }
.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; }
-.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def { color: #07a; }
+.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def, .cm-s-mdn-like span.cm-type { color: #07a; }
.cm-s-mdn-like .cm-variable { color: #07a; }
.cm-s-mdn-like .cm-property { color: #905; }
diff --git a/codemirror/theme/monokai.css b/codemirror/theme/monokai.css
index 7c8a4c5d..b5edd13f 100644
--- a/codemirror/theme/monokai.css
+++ b/codemirror/theme/monokai.css
@@ -21,7 +21,7 @@
.cm-s-monokai span.cm-variable { color: #f8f8f2; }
.cm-s-monokai span.cm-variable-2 { color: #9effff; }
-.cm-s-monokai span.cm-variable-3 { color: #66d9ef; }
+.cm-s-monokai span.cm-variable-3, .cm-s-monokai span.cm-type { color: #66d9ef; }
.cm-s-monokai span.cm-def { color: #fd971f; }
.cm-s-monokai span.cm-bracket { color: #f8f8f2; }
.cm-s-monokai span.cm-tag { color: #f92672; }
diff --git a/codemirror/theme/night.css b/codemirror/theme/night.css
index fd4e5619..f631bf42 100644
--- a/codemirror/theme/night.css
+++ b/codemirror/theme/night.css
@@ -17,7 +17,7 @@
.cm-s-night span.cm-string { color: #37f14a; }
.cm-s-night span.cm-meta { color: #7678e2; }
.cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; }
-.cm-s-night span.cm-variable-3, .cm-s-night span.cm-def { color: white; }
+.cm-s-night span.cm-variable-3, .cm-s-night span.cm-def, .cm-s-night span.cm-type { color: white; }
.cm-s-night span.cm-bracket { color: #8da6ce; }
.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; }
.cm-s-night span.cm-link { color: #845dc4; }
diff --git a/codemirror/theme/panda-syntax.css b/codemirror/theme/panda-syntax.css
index c93b2ea0..6de58b56 100644
--- a/codemirror/theme/panda-syntax.css
+++ b/codemirror/theme/panda-syntax.css
@@ -52,7 +52,7 @@
.cm-s-panda-syntax .cm-variable-2 {
color: #ff9ac1;
}
-.cm-s-panda-syntax .cm-variable-3 {
+.cm-s-panda-syntax .cm-variable-3, .cm-s-panda-syntax .cm-type {
color: #ff9ac1;
}
diff --git a/codemirror/theme/pastel-on-dark.css b/codemirror/theme/pastel-on-dark.css
index 2603d362..60435dd1 100644
--- a/codemirror/theme/pastel-on-dark.css
+++ b/codemirror/theme/pastel-on-dark.css
@@ -34,7 +34,7 @@
.cm-s-pastel-on-dark span.cm-string { color: #66A968; }
.cm-s-pastel-on-dark span.cm-variable { color: #AEB2F8; }
.cm-s-pastel-on-dark span.cm-variable-2 { color: #BEBF55; }
-.cm-s-pastel-on-dark span.cm-variable-3 { color: #DE8E30; }
+.cm-s-pastel-on-dark span.cm-variable-3, .cm-s-pastel-on-dark span.cm-type { color: #DE8E30; }
.cm-s-pastel-on-dark span.cm-def { color: #757aD8; }
.cm-s-pastel-on-dark span.cm-bracket { color: #f8f8f2; }
.cm-s-pastel-on-dark span.cm-tag { color: #C1C144; }
diff --git a/codemirror/theme/rubyblue.css b/codemirror/theme/rubyblue.css
index 76d33e77..1f181b06 100644
--- a/codemirror/theme/rubyblue.css
+++ b/codemirror/theme/rubyblue.css
@@ -15,7 +15,7 @@
.cm-s-rubyblue span.cm-string { color: #F08047; }
.cm-s-rubyblue span.cm-meta { color: #F0F; }
.cm-s-rubyblue span.cm-variable-2, .cm-s-rubyblue span.cm-tag { color: #7BD827; }
-.cm-s-rubyblue span.cm-variable-3, .cm-s-rubyblue span.cm-def { color: white; }
+.cm-s-rubyblue span.cm-variable-3, .cm-s-rubyblue span.cm-def, .cm-s-rubyblue span.cm-type { color: white; }
.cm-s-rubyblue span.cm-bracket { color: #F0F; }
.cm-s-rubyblue span.cm-link { color: #F4C20B; }
.cm-s-rubyblue span.CodeMirror-matchingbracket { color:#F0F !important; }
diff --git a/codemirror/theme/seti.css b/codemirror/theme/seti.css
index 6632d3fc..814f76f7 100644
--- a/codemirror/theme/seti.css
+++ b/codemirror/theme/seti.css
@@ -38,7 +38,7 @@
.cm-s-seti span.cm-attribute { color: #9fca56; }
.cm-s-seti span.cm-qualifier { color: #9fca56; }
.cm-s-seti span.cm-property { color: #a074c4; }
-.cm-s-seti span.cm-variable-3 { color: #9fca56; }
+.cm-s-seti span.cm-variable-3, .cm-s-seti span.cm-type { color: #9fca56; }
.cm-s-seti span.cm-builtin { color: #9fca56; }
.cm-s-seti .CodeMirror-activeline-background { background: #101213; }
.cm-s-seti .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
diff --git a/codemirror/theme/solarized.css b/codemirror/theme/solarized.css
index 1f39c7ed..d95f6c1b 100644
--- a/codemirror/theme/solarized.css
+++ b/codemirror/theme/solarized.css
@@ -57,7 +57,7 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png
.cm-s-solarized .cm-variable { color: #839496; }
.cm-s-solarized .cm-variable-2 { color: #b58900; }
-.cm-s-solarized .cm-variable-3 { color: #6c71c4; }
+.cm-s-solarized .cm-variable-3, .cm-s-solarized .cm-type { color: #6c71c4; }
.cm-s-solarized .cm-property { color: #2aa198; }
.cm-s-solarized .cm-operator { color: #6c71c4; }
diff --git a/codemirror/theme/the-matrix.css b/codemirror/theme/the-matrix.css
index 3912a8db..c4c93c11 100644
--- a/codemirror/theme/the-matrix.css
+++ b/codemirror/theme/the-matrix.css
@@ -14,7 +14,7 @@
.cm-s-the-matrix span.cm-def { color: #99C; }
.cm-s-the-matrix span.cm-variable { color: #F6C; }
.cm-s-the-matrix span.cm-variable-2 { color: #C6F; }
-.cm-s-the-matrix span.cm-variable-3 { color: #96F; }
+.cm-s-the-matrix span.cm-variable-3, .cm-s-the-matrix span.cm-type { color: #96F; }
.cm-s-the-matrix span.cm-property { color: #62FFA0; }
.cm-s-the-matrix span.cm-operator { color: #999; }
.cm-s-the-matrix span.cm-comment { color: #CCCCCC; }
diff --git a/codemirror/theme/ttcn.css b/codemirror/theme/ttcn.css
index b3d46564..0b14ac35 100644
--- a/codemirror/theme/ttcn.css
+++ b/codemirror/theme/ttcn.css
@@ -29,7 +29,7 @@
.cm-s-ttcn .cm-tag { color: #170; }
.cm-s-ttcn .cm-variable { color: #8B2252; }
.cm-s-ttcn .cm-variable-2 { color: #05a; }
-.cm-s-ttcn .cm-variable-3 { color: #085; }
+.cm-s-ttcn .cm-variable-3, .cm-s-ttcn .cm-type { color: #085; }
.cm-s-ttcn .cm-invalidchar { color: #f00; }
diff --git a/codemirror/theme/twilight.css b/codemirror/theme/twilight.css
index d342b899..b2b1b2aa 100644
--- a/codemirror/theme/twilight.css
+++ b/codemirror/theme/twilight.css
@@ -14,7 +14,7 @@
.cm-s-twilight .cm-number { color: #ca7841; } /**/
.cm-s-twilight .cm-def { color: #8DA6CE; }
.cm-s-twilight span.cm-variable-2, .cm-s-twilight span.cm-tag { color: #607392; } /**/
-.cm-s-twilight span.cm-variable-3, .cm-s-twilight span.cm-def { color: #607392; } /**/
+.cm-s-twilight span.cm-variable-3, .cm-s-twilight span.cm-def, .cm-s-twilight span.cm-type { color: #607392; } /**/
.cm-s-twilight .cm-operator { color: #cda869; } /**/
.cm-s-twilight .cm-comment { color:#777; font-style:italic; font-weight:normal; } /**/
.cm-s-twilight .cm-string { color:#8f9d6a; font-style:italic; } /**/
diff --git a/codemirror/theme/vibrant-ink.css b/codemirror/theme/vibrant-ink.css
index ac4ec6d8..b13ecf21 100644
--- a/codemirror/theme/vibrant-ink.css
+++ b/codemirror/theme/vibrant-ink.css
@@ -16,7 +16,7 @@
.cm-s-vibrant-ink .cm-number { color: #FFEE98; }
.cm-s-vibrant-ink .cm-def { color: #8DA6CE; }
.cm-s-vibrant-ink span.cm-variable-2, .cm-s-vibrant span.cm-tag { color: #FFC66D; }
-.cm-s-vibrant-ink span.cm-variable-3, .cm-s-vibrant span.cm-def { color: #FFC66D; }
+.cm-s-vibrant-ink span.cm-variable-3, .cm-s-vibrant span.cm-def, .cm-s-vibrant span.cm-type { color: #FFC66D; }
.cm-s-vibrant-ink .cm-operator { color: #888; }
.cm-s-vibrant-ink .cm-comment { color: gray; font-weight: bold; }
.cm-s-vibrant-ink .cm-string { color: #A5C25C; }
diff --git a/codemirror/theme/xq-dark.css b/codemirror/theme/xq-dark.css
index e3bd960b..7da1a0f7 100644
--- a/codemirror/theme/xq-dark.css
+++ b/codemirror/theme/xq-dark.css
@@ -36,7 +36,7 @@ THE SOFTWARE.
.cm-s-xq-dark span.cm-def { color: #FFF; text-decoration:underline; }
.cm-s-xq-dark span.cm-variable { color: #FFF; }
.cm-s-xq-dark span.cm-variable-2 { color: #EEE; }
-.cm-s-xq-dark span.cm-variable-3 { color: #DDD; }
+.cm-s-xq-dark span.cm-variable-3, .cm-s-xq-dark span.cm-type { color: #DDD; }
.cm-s-xq-dark span.cm-property {}
.cm-s-xq-dark span.cm-operator {}
.cm-s-xq-dark span.cm-comment { color: gray; }
diff --git a/codemirror/theme/xq-light.css b/codemirror/theme/xq-light.css
index 8d2fcb66..7b182ea9 100644
--- a/codemirror/theme/xq-light.css
+++ b/codemirror/theme/xq-light.css
@@ -26,7 +26,7 @@ THE SOFTWARE.
.cm-s-xq-light span.cm-def { text-decoration:underline; }
.cm-s-xq-light span.cm-variable { color: black; }
.cm-s-xq-light span.cm-variable-2 { color:black; }
-.cm-s-xq-light span.cm-variable-3 { color: black; }
+.cm-s-xq-light span.cm-variable-3, .cm-s-xq-light span.cm-type { color: black; }
.cm-s-xq-light span.cm-property {}
.cm-s-xq-light span.cm-operator {}
.cm-s-xq-light span.cm-comment { color: #0080FF; font-style: italic; }
diff --git a/codemirror/theme/yeti.css b/codemirror/theme/yeti.css
index c70d4d21..d085f724 100644
--- a/codemirror/theme/yeti.css
+++ b/codemirror/theme/yeti.css
@@ -39,6 +39,6 @@
.cm-s-yeti span.cm-qualifier { color: #96c0d8; }
.cm-s-yeti span.cm-property { color: #a074c4; }
.cm-s-yeti span.cm-builtin { color: #a074c4; }
-.cm-s-yeti span.cm-variable-3 { color: #96c0d8; }
+.cm-s-yeti span.cm-variable-3, .cm-s-yeti span.cm-type { color: #96c0d8; }
.cm-s-yeti .CodeMirror-activeline-background { background: #E7E4E0; }
.cm-s-yeti .CodeMirror-matchingbracket { text-decoration: underline; }