diff --git a/AUTHORS b/AUTHORS
index 67a8e248c5..1e3ece23e0 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -27,6 +27,7 @@ Alex Piggott
Aliaksei Chapyzhenka
Allen Sarkisyan
Amin Shali
+amshali@google.com
Amsul
amuntean
Amy
@@ -63,6 +64,8 @@ as3boyan
AtomicPages LLC
Atul Bhouraskar
Aurelian Oancea
+Barret Rennie
+Basarat Ali Syed
Bastian Müller
belhaj
Bem Jones-Bey
@@ -86,6 +89,7 @@ Brett Zamir
Brian Grinstead
Brian Sletten
Bruce Mitchener
+Caitlin Potter
Calin Barbat
Chandra Sekhar Pydi
Charles Skelton
@@ -144,6 +148,7 @@ duralog
eborden
edsharp
ekhaled
+Elisée
Enam Mijbah Noor
Eric Allam
eustas
@@ -196,6 +201,7 @@ Ian Wehrman
Ian Wetherbee
Ice White
ICHIKAWA, Yuji
+idleberg
ilvalle
Ingo Richter
Irakli Gozalishvili
@@ -230,6 +236,7 @@ Jeremy Parmenter
Jochen Berger
Johan Ask
John Connor
+John Engler
John Lees-Miller
John Snelson
John Van Der Loo
@@ -296,12 +303,15 @@ Marek Rudnicki
Marijn Haverbeke
Mário Gonçalves
Mario Pietsch
+Mark Anderson
Mark Lentczner
Marko Bonaci
+Markus Bordihn
Martin Balek
Martín Gaitán
Martin Hasoň
Martin Hunt
+Martin Laine
Martin Zagora
Mason Malone
Mateusz Paprocki
@@ -327,6 +337,7 @@ melpon
Metatheos
Micah Dubinko
Michael
+Michael Goderbauer
Michael Grey
Michael Kaminsky
Michael Lehenbauer
@@ -386,6 +397,7 @@ Pavel Feldman
Pavel Strashkin
Paweł Bartkiewicz
peteguhl
+peter
Peter Flynn
peterkroon
Peter Kroon
@@ -420,6 +432,7 @@ Sascha Peilicke
satamas
satchmorun
sathyamoorthi
+S. Chris Colbert
SCLINIC\jdecker
Scott Aikin
Scott Goodhew
@@ -449,6 +462,7 @@ stoskov
Sungho Kim
sverweij
Taha Jahangir
+Tako Schotanus
Takuji Shimokawa
Tarmil
tel
diff --git a/addon/comment/comment.js b/addon/comment/comment.js
index 2dd114d332..3aa468089e 100644
--- a/addon/comment/comment.js
+++ b/addon/comment/comment.js
@@ -21,22 +21,28 @@
}
CodeMirror.commands.toggleComment = function(cm) {
- var minLine = Infinity, ranges = cm.listSelections(), mode = null;
+ cm.toggleComment();
+ };
+
+ CodeMirror.defineExtension("toggleComment", function(options) {
+ if (!options) options = noOptions;
+ var cm = this;
+ var minLine = Infinity, ranges = this.listSelections(), mode = null;
for (var i = ranges.length - 1; i >= 0; i--) {
var from = ranges[i].from(), to = ranges[i].to();
if (from.line >= minLine) continue;
if (to.line >= minLine) to = Pos(minLine, 0);
minLine = from.line;
if (mode == null) {
- if (cm.uncomment(from, to)) mode = "un";
- else { cm.lineComment(from, to); mode = "line"; }
+ if (cm.uncomment(from, to, options)) mode = "un";
+ else { cm.lineComment(from, to, options); mode = "line"; }
} else if (mode == "un") {
- cm.uncomment(from, to);
+ cm.uncomment(from, to, options);
} else {
- cm.lineComment(from, to);
+ cm.lineComment(from, to, options);
}
}
- };
+ });
CodeMirror.defineExtension("lineComment", function(from, to, options) {
if (!options) options = noOptions;
@@ -57,7 +63,14 @@
self.operation(function() {
if (options.indent) {
- var baseString = firstLine.slice(0, firstNonWS(firstLine));
+ var baseString = null;
+ for (var i = from.line; i < end; ++i) {
+ var line = self.getLine(i);
+ var whitespace = line.slice(0, firstNonWS(line));
+ if (baseString == null || baseString.length > whitespace.length) {
+ baseString = whitespace;
+ }
+ }
for (var i = from.line; i < end; ++i) {
var line = self.getLine(i), cut = baseString.length;
if (!blankLines && !nonWS.test(line)) continue;
diff --git a/addon/hint/show-hint.js b/addon/hint/show-hint.js
index 980da5235d..a1e56c38be 100644
--- a/addon/hint/show-hint.js
+++ b/addon/hint/show-hint.js
@@ -25,8 +25,18 @@
};
CodeMirror.defineExtension("showHint", function(options) {
- // We want a single cursor position.
- if (this.listSelections().length > 1 || this.somethingSelected()) return;
+ options = parseOptions(this, this.getCursor("start"), options);
+ var selections = this.listSelections()
+ if (selections.length > 1) return;
+ // By default, don't allow completion when something is selected.
+ // A hint function can have a `supportsSelection` property to
+ // indicate that it can handle selections.
+ if (this.somethingSelected()) {
+ if (!options.hint.supportsSelection) return;
+ // Don't try with cross-line selections
+ for (var i = 0; i < selections.length; i++)
+ if (selections[i].head.line != selections[i].anchor.line) return;
+ }
if (this.state.completionActive) this.state.completionActive.close();
var completion = this.state.completionActive = new Completion(this, options);
@@ -38,12 +48,12 @@
function Completion(cm, options) {
this.cm = cm;
- this.options = this.buildOptions(options);
+ this.options = options;
this.widget = null;
this.debounce = 0;
this.tick = 0;
- this.startPos = this.cm.getCursor();
- this.startLen = this.cm.getLine(this.startPos.line).length;
+ this.startPos = this.cm.getCursor("start");
+ this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
var self = this;
cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
@@ -124,20 +134,21 @@
CodeMirror.signal(data, "shown");
}
}
- },
-
- buildOptions: function(options) {
- var editor = this.cm.options.hintOptions;
- var out = {};
- for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
- if (editor) for (var prop in editor)
- if (editor[prop] !== undefined) out[prop] = editor[prop];
- if (options) for (var prop in options)
- if (options[prop] !== undefined) out[prop] = options[prop];
- return out;
}
};
+ function parseOptions(cm, pos, options) {
+ var editor = cm.options.hintOptions;
+ var out = {};
+ for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
+ if (editor) for (var prop in editor)
+ if (editor[prop] !== undefined) out[prop] = editor[prop];
+ if (options) for (var prop in options)
+ if (options[prop] !== undefined) out[prop] = options[prop];
+ if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
+ return out;
+ }
+
function getText(completion) {
if (typeof completion == "string") return completion;
else return completion.text;
@@ -336,18 +347,61 @@
}
};
- CodeMirror.registerHelper("hint", "auto", function(cm, options) {
- var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
+ function applicableHelpers(cm, helpers) {
+ if (!cm.somethingSelected()) return helpers
+ var result = []
+ for (var i = 0; i < helpers.length; i++)
+ if (helpers[i].supportsSelection) result.push(helpers[i])
+ return result
+ }
+
+ function resolveAutoHints(cm, pos) {
+ var helpers = cm.getHelpers(pos, "hint"), words
if (helpers.length) {
- for (var i = 0; i < helpers.length; i++) {
- var cur = helpers[i](cm, options);
- if (cur && cur.list.length) return cur;
+ var async = false, resolved
+ for (var i = 0; i < helpers.length; i++) if (helpers[i].async) async = true
+ if (async) {
+ resolved = function(cm, callback, options) {
+ var app = applicableHelpers(cm, helpers)
+ function run(i, result) {
+ if (i == app.length) return callback(null)
+ var helper = app[i]
+ if (helper.async) {
+ helper(cm, function(result) {
+ if (result) callback(result)
+ else run(i + 1)
+ }, options)
+ } else {
+ var result = helper(cm, options)
+ if (result) callback(result)
+ else run(i + 1)
+ }
+ }
+ run(0)
+ }
+ resolved.async = true
+ } else {
+ resolved = function(cm, options) {
+ var app = applicableHelpers(cm, helpers)
+ for (var i = 0; i < app.length; i++) {
+ var cur = app[i](cm, options)
+ if (cur && cur.list.length) return cur
+ }
+ }
}
+ resolved.supportsSelection = true
+ return resolved
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
- if (words) return CodeMirror.hint.fromList(cm, {words: words});
+ return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
} else if (CodeMirror.hint.anyword) {
- return CodeMirror.hint.anyword(cm, options);
+ return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
+ } else {
+ return function() {}
}
+ }
+
+ CodeMirror.registerHelper("hint", "auto", {
+ resolve: resolveAutoHints
});
CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
diff --git a/addon/merge/merge.js b/addon/merge/merge.js
index e99de0b778..830a5f027a 100644
--- a/addon/merge/merge.js
+++ b/addon/merge/merge.js
@@ -5,7 +5,7 @@
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
- mod(require("../../lib/codemirror"), require("diff_match_patch"));
+ mod(require("../../lib/codemirror")); // Note non-packaged dependency diff_match_patch
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror", "diff_match_patch"], mod);
else // Plain browser env
@@ -471,13 +471,10 @@
if (left) left.init(leftPane, origLeft, options);
if (right) right.init(rightPane, origRight, options);
- if (options.collapseIdentical) {
- updating = true;
+ if (options.collapseIdentical)
this.editor().operation(function() {
collapseIdenticalStretches(self, options.collapseIdentical);
});
- updating = false;
- }
if (options.connect == "align") {
this.aligners = [];
alignChunks(this.left || this.right, true);
@@ -640,7 +637,7 @@
mark.clear();
cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
}
- widget.addEventListener("click", clear);
+ CodeMirror.on(widget, "click", clear);
return {mark: mark, clear: clear};
}
diff --git a/addon/mode/multiplex.js b/addon/mode/multiplex.js
index fe48c7fbd5..3d8b34c452 100644
--- a/addon/mode/multiplex.js
+++ b/addon/mode/multiplex.js
@@ -51,7 +51,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
if (!other.parseDelimiters) stream.match(other.open);
state.innerActive = other;
state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
- return other.delimStyle;
+ return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open");
} else if (found != -1 && found < cutOff) {
cutOff = found;
}
@@ -70,7 +70,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
if (found == stream.pos && !curInner.parseDelimiters) {
stream.match(curInner.close);
state.innerActive = state.inner = null;
- return curInner.delimStyle;
+ return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close");
}
if (found > -1) stream.string = oldContent.slice(0, found);
var innerToken = curInner.mode.token(stream, state.inner);
@@ -80,7 +80,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
state.innerActive = state.inner = null;
if (curInner.innerStyle) {
- if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle;
+ if (innerToken) innerToken = innerToken + " " + curInner.innerStyle;
else innerToken = curInner.innerStyle;
}
diff --git a/addon/mode/multiplex_test.js b/addon/mode/multiplex_test.js
index d33943420e..24e5e670de 100644
--- a/addon/mode/multiplex_test.js
+++ b/addon/mode/multiplex_test.js
@@ -29,5 +29,5 @@
MT(
"stexInsideMarkdown",
- "[strong **Equation:**] [delim $][inner&tag \\pi][delim $]");
+ "[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]");
})();
diff --git a/addon/wrap/hardwrap.js b/addon/wrap/hardwrap.js
index fe9b4dd669..8806fbe2f2 100644
--- a/addon/wrap/hardwrap.js
+++ b/addon/wrap/hardwrap.js
@@ -32,11 +32,13 @@
function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
for (var at = column; at > 0; --at)
if (wrapOn.test(text.slice(at - 1, at + 1))) break;
- if (at == 0) at = column;
- var endOfText = at;
- if (killTrailingSpace)
- while (text.charAt(endOfText - 1) == " ") --endOfText;
- return {from: endOfText, to: at};
+ for (var first = true;; first = false) {
+ var endOfText = at;
+ if (killTrailingSpace)
+ while (text.charAt(endOfText - 1) == " ") --endOfText;
+ if (endOfText == 0 && first) at = column;
+ else return {from: endOfText, to: at};
+ }
}
function wrapRange(cm, from, to, options) {
@@ -86,7 +88,8 @@
if (changes.length) cm.operation(function() {
for (var i = 0; i < changes.length; ++i) {
var change = changes[i];
- cm.replaceRange(change.text, change.from, change.to);
+ if (change.text || CodeMirror.cmpPos(change.from, change.to))
+ cm.replaceRange(change.text, change.from, change.to);
}
});
return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null;
diff --git a/demo/hardwrap.html b/demo/hardwrap.html
index f1a870b41c..84ba0cc0c2 100644
--- a/demo/hardwrap.html
+++ b/demo/hardwrap.html
@@ -60,11 +60,14 @@
Hard-wrapping Demo
"Ctrl-Q": function(cm) { cm.wrapParagraph(cm.getCursor(), options); }
}
});
-var wait, options = {column: 60};
+var wait, options = {column: 60}, changing = false;
editor.on("change", function(cm, change) {
+ if (changing) return;
clearTimeout(wait);
wait = setTimeout(function() {
- console.log(cm.wrapParagraphsInRange(change.from, CodeMirror.changeEnd(change), options));
+ changing = true;
+ cm.wrapParagraphsInRange(change.from, CodeMirror.changeEnd(change), options);
+ changing = false;
}, 200);
});
diff --git a/demo/theme.html b/demo/theme.html
index 3c6b1c07de..300e2625e3 100644
--- a/demo/theme.html
+++ b/demo/theme.html
@@ -10,6 +10,7 @@
+
@@ -18,7 +19,9 @@
+
+
@@ -32,6 +35,7 @@
+
@@ -89,6 +93,7 @@ Theme Demo
+
@@ -96,7 +101,9 @@ Theme Demo
+
+
@@ -110,6 +117,7 @@ Theme Demo
+
diff --git a/doc/compress.html b/doc/compress.html
index 218cacc2f0..6a183ca528 100644
--- a/doc/compress.html
+++ b/doc/compress.html
@@ -36,6 +36,7 @@ Script compression helper
Version:
+ x-shader/x-fragment
(shader programs),
+ text/x-squirrel
(Squirrel) and
+ text/x-ceylon
(Ceylon)
diff --git a/mode/coffeescript/coffeescript.js b/mode/coffeescript/coffeescript.js
index 1b96f85d86..adf2184fd7 100644
--- a/mode/coffeescript/coffeescript.js
+++ b/mode/coffeescript/coffeescript.js
@@ -267,17 +267,6 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
var style = state.tokenize(stream, state);
var current = stream.current();
- // Handle "." connected identifiers
- if (false && current === ".") {
- style = state.tokenize(stream, state);
- current = stream.current();
- if (/^\.[\w$]+$/.test(current)) {
- return "variable";
- } else {
- return ERRORCLASS;
- }
- }
-
// Handle scope changes.
if (current === "return") {
state.dedent = true;
diff --git a/mode/css/css.js b/mode/css/css.js
index 7300850399..d07426473b 100644
--- a/mode/css/css.js
+++ b/mode/css/css.js
@@ -275,6 +275,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (type == "}" || type == ";") return popAndPass(type, stream, state);
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
+ if (type == "interpolation") return pushContext(state, stream, "interpolation");
+
if (type == "word") {
var word = stream.current().toLowerCase();
if (word == "only" || word == "not" || word == "and" || word == "or")
diff --git a/mode/cypher/cypher.js b/mode/cypher/cypher.js
index 79048b440c..107e4f6d21 100644
--- a/mode/cypher/cypher.js
+++ b/mode/cypher/cypher.js
@@ -60,9 +60,9 @@
};
var indentUnit = config.indentUnit;
var curPunc;
- var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "keys", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "right", "round", "rtrim", "shortestPath", "sign", "sin", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "trim", "type", "upper"]);
- var preds = wordRegexp(["all", "and", "any", "has", "in", "none", "not", "or", "single", "xor", "like", "ilike", "exists"]);
- var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "distinct", "drop", "else", "end", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "join", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
+ var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "keys", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "reverse", "right", "round", "rtrim", "shortestPath", "sign", "sin", "size", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "toString", "trim", "type", "upper"]);
+ var preds = wordRegexp(["all", "and", "any", "contains", "exists", "has", "in", "none", "not", "or", "single", "xor"]);
+ var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "detach", "distinct", "drop", "else", "end", "ends", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "join", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "starts", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
var operatorChars = /[*+\-<>=&|~%^]/;
return {
diff --git a/mode/dart/dart.js b/mode/dart/dart.js
index a49e218c3b..7d6e5abd96 100644
--- a/mode/dart/dart.js
+++ b/mode/dart/dart.js
@@ -26,10 +26,21 @@
return obj;
}
+ function pushInterpolationStack(state) {
+ (state.interpolationStack || (state.interpolationStack = [])).push(state.tokenize);
+ }
+
+ function popInterpolationStack(state) {
+ return (state.interpolationStack || (state.interpolationStack = [])).pop();
+ }
+
+ function sizeInterpolationStack(state) {
+ return state.interpolationStack ? state.interpolationStack.length : 0;
+ }
+
CodeMirror.defineMIME("application/dart", {
name: "clike",
keywords: set(keywords),
- multiLineStrings: true,
blockKeywords: set(blockKeywords),
builtin: set(builtins),
atoms: set(atoms),
@@ -37,10 +48,79 @@
"@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
+ },
+
+ // custom string handling to deal with triple-quoted strings and string interpolation
+ "'": function(stream, state) {
+ return tokenString("'", stream, state, false);
+ },
+ "\"": function(stream, state) {
+ return tokenString("\"", stream, state, false);
+ },
+ "r": function(stream, state) {
+ var peek = stream.peek();
+ if (peek == "'" || peek == "\"") {
+ return tokenString(stream.next(), stream, state, true);
+ }
+ return false;
+ },
+
+ "}": function(_stream, state) {
+ // "}" is end of interpolation, if interpolation stack is non-empty
+ if (sizeInterpolationStack(state) > 0) {
+ state.tokenize = popInterpolationStack(state);
+ return null;
+ }
+ return false;
}
}
});
+ function tokenString(quote, stream, state, raw) {
+ var tripleQuoted = false;
+ if (stream.eat(quote)) {
+ if (stream.eat(quote)) tripleQuoted = true;
+ else return "string"; //empty string
+ }
+ function tokenStringHelper(stream, state) {
+ var escaped = false;
+ while (!stream.eol()) {
+ if (!raw && !escaped && stream.peek() == "$") {
+ pushInterpolationStack(state);
+ state.tokenize = tokenInterpolation;
+ return "string";
+ }
+ var next = stream.next();
+ if (next == quote && !escaped && (!tripleQuoted || stream.match(quote + quote))) {
+ state.tokenize = null;
+ break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ return "string";
+ }
+ state.tokenize = tokenStringHelper;
+ return tokenStringHelper(stream, state);
+ }
+
+ function tokenInterpolation(stream, state) {
+ stream.eat("$");
+ if (stream.eat("{")) {
+ // let clike handle the content of ${...},
+ // we take over again when "}" appears (see hooks).
+ state.tokenize = null;
+ } else {
+ state.tokenize = tokenInterpolationIdentifier;
+ }
+ return null;
+ }
+
+ function tokenInterpolationIdentifier(stream, state) {
+ stream.eatWhile(/[\w_]/);
+ state.tokenize = popInterpolationStack(state);
+ return "variable";
+ }
+
CodeMirror.registerHelper("hintWords", "application/dart", keywords.concat(atoms).concat(builtins));
// This is needed to make loading through meta.js work.
diff --git a/mode/haxe/haxe.js b/mode/haxe/haxe.js
index 73cd6213ac..a9573dd71b 100644
--- a/mode/haxe/haxe.js
+++ b/mode/haxe/haxe.js
@@ -191,13 +191,20 @@ CodeMirror.defineMode("haxe", function(config, parserConfig) {
pass.apply(null, arguments);
return true;
}
+ function inList(name, list) {
+ for (var v = list; v; v = v.next)
+ if (v.name == name) return true;
+ return false;
+ }
function register(varname) {
var state = cx.state;
if (state.context) {
cx.marked = "def";
- for (var v = state.localVars; v; v = v.next)
- if (v.name == varname) return;
+ if (inList(varname, state.localVars)) return;
state.localVars = {name: varname, next: state.localVars};
+ } else if (state.globalVars) {
+ if (inList(varname, state.globalVars)) return;
+ state.globalVars = {name: varname, next: state.globalVars};
}
}
@@ -380,11 +387,10 @@ CodeMirror.defineMode("haxe", function(config, parserConfig) {
}
// Interface
-
return {
startState: function(basecolumn) {
var defaulttypes = ["Int", "Float", "String", "Void", "Std", "Bool", "Dynamic", "Array"];
- return {
+ var state = {
tokenize: haxeTokenBase,
reAllowed: true,
kwAllowed: true,
@@ -395,6 +401,9 @@ CodeMirror.defineMode("haxe", function(config, parserConfig) {
context: parserConfig.localVars && {vars: parserConfig.localVars},
indented: 0
};
+ if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
+ state.globalVars = parserConfig.globalVars;
+ return state;
},
token: function(stream, state) {
diff --git a/mode/htmlmixed/htmlmixed.js b/mode/htmlmixed/htmlmixed.js
index 670fd62bf1..21e74f163d 100644
--- a/mode/htmlmixed/htmlmixed.js
+++ b/mode/htmlmixed/htmlmixed.js
@@ -89,8 +89,8 @@
tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
function html(stream, state) {
- var tagName = state.htmlState.tagName;
- var tagInfo = tagName && tags[tagName.toLowerCase()];
+ var tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase();
+ var tagInfo = tagName && tags.hasOwnProperty(tagName) && tags[tagName];
var style = htmlMode.token(stream, state.htmlState), modeSpec;
diff --git a/mode/index.html b/mode/index.html
index f63e83684c..044dee7fdb 100644
--- a/mode/index.html
+++ b/mode/index.html
@@ -35,6 +35,7 @@ Language modes
Asterisk dialplan
Brainfuck
C, C++, C#
+ Ceylon
Clojure
Closure Stylesheets (GSS)
CMake
@@ -87,6 +88,7 @@ Language modes
Modelica
MUMPS
Nginx
+ NSIS
NTriples
Objective C
OCaml
diff --git a/mode/javascript/javascript.js b/mode/javascript/javascript.js
index 032c207594..b961b89011 100644
--- a/mode/javascript/javascript.js
+++ b/mode/javascript/javascript.js
@@ -30,7 +30,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var jsKeywords = {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
- "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
+ "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
"var": kw("var"), "const": kw("var"), "let": kw("var"),
"async": kw("async"), "function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
@@ -56,7 +56,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
"static": kw("static"),
// types
- "string": type, "number": type, "bool": type, "any": type
+ "string": type, "number": type, "boolean": type, "any": type
};
for (var attr in tsKeywords) {
@@ -122,7 +122,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
stream.skipToEnd();
return ret("comment", "comment");
} else if (state.lastType == "operator" || state.lastType == "keyword c" ||
- state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
+ state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
readRegexp(stream);
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
return ret("regexp", "string-2");
@@ -281,8 +281,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return false;
}
var state = cx.state;
+ cx.marked = "def";
if (state.context) {
- cx.marked = "def";
if (inList(state.localVars)) return;
state.localVars = {name: varname, next: state.localVars};
} else {
@@ -380,7 +380,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
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 == "quasi") return pass(quasi, maybeop);
+ if (type == "new") return cont(maybeTarget(noComma));
return cont();
}
function maybeexpression(type) {
@@ -431,6 +432,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
findFatArrow(cx.stream, cx.state);
return pass(type == "{" ? statement : expressionNoComma);
}
+ function maybeTarget(noComma) {
+ return function(type) {
+ if (type == ".") return cont(noComma ? targetNoComma : target);
+ else return pass(noComma ? expressionNoComma : expression);
+ };
+ }
+ function target(_, value) {
+ if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
+ }
+ function targetNoComma(_, value) {
+ if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
+ }
function maybelabel(type) {
if (type == ":") return cont(poplex, statement);
return pass(maybeoperatorComma, expect(";"), poplex);
@@ -501,6 +514,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function pattern(type, value) {
if (type == "variable") { register(value); return cont(); }
+ if (type == "spread") return cont(pattern);
if (type == "[") return contCommasep(pattern, "]");
if (type == "{") return contCommasep(proppattern, "}");
}
@@ -510,6 +524,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return cont(maybeAssign);
}
if (type == "variable") cx.marked = "property";
+ if (type == "spread") return cont(pattern);
return cont(expect(":"), pattern, maybeAssign);
}
function maybeAssign(_type, value) {
diff --git a/mode/javascript/test.js b/mode/javascript/test.js
index 452de5fd6b..252e064dcc 100644
--- a/mode/javascript/test.js
+++ b/mode/javascript/test.js
@@ -6,7 +6,7 @@
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
MT("locals",
- "[keyword function] [variable foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }");
+ "[keyword function] [def foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }");
MT("comma-and-binop",
"[keyword function](){ [keyword var] [def x] [operator =] [number 1] [operator +] [number 2], [def y]; }");
@@ -18,7 +18,7 @@
"})();");
MT("class_body",
- "[keyword class] [variable Foo] {",
+ "[keyword class] [def Foo] {",
" [property constructor]() {}",
" [property sayName]() {",
" [keyword return] [string-2 `foo${][variable foo][string-2 }oo`];",
@@ -26,7 +26,7 @@
"}");
MT("class",
- "[keyword class] [variable Point] [keyword extends] [variable SuperThing] {",
+ "[keyword class] [def Point] [keyword extends] [variable SuperThing] {",
" [property get] [property prop]() { [keyword return] [number 24]; }",
" [property constructor]([def x], [def y]) {",
" [keyword super]([string 'something']);",
@@ -35,44 +35,44 @@
"}");
MT("import",
- "[keyword function] [variable foo]() {",
+ "[keyword function] [def foo]() {",
" [keyword import] [def $] [keyword from] [string 'jquery'];",
" [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];",
"}");
MT("const",
- "[keyword function] [variable f]() {",
+ "[keyword function] [def f]() {",
" [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];",
"}");
MT("for/of",
- "[keyword for]([keyword let] [variable of] [keyword of] [variable something]) {}");
+ "[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}");
MT("generator",
- "[keyword function*] [variable repeat]([def n]) {",
+ "[keyword function*] [def repeat]([def n]) {",
" [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])",
" [keyword yield] [variable-2 i];",
"}");
MT("quotedStringAddition",
- "[keyword let] [variable f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];");
+ "[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];");
MT("quotedFatArrow",
- "[keyword let] [variable f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];");
+ "[keyword let] [def f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];");
MT("fatArrow",
"[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);",
"[variable a];", // No longer in scope
- "[keyword let] [variable f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];",
+ "[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];",
"[variable c];");
MT("spread",
- "[keyword function] [variable f]([def a], [meta ...][def b]) {",
+ "[keyword function] [def f]([def a], [meta ...][def b]) {",
" [variable something]([variable-2 a], [meta ...][variable-2 b]);",
"}");
MT("comprehension",
- "[keyword function] [variable f]() {",
+ "[keyword function] [def f]() {",
" [[([variable x] [operator +] [number 1]) [keyword for] ([keyword var] [def x] [keyword in] [variable y]) [keyword if] [variable pred]([variable-2 x]) ]];",
" ([variable u] [keyword for] ([keyword var] [def u] [keyword of] [variable generateValues]()) [keyword if] ([variable-2 u].[property color] [operator ===] [string 'blue']));",
"}");
@@ -84,7 +84,7 @@
"[variable x] [operator =] [string-2 `fofdlakj${][variable x] [operator +] [string-2 `foo`] [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");
MT("indent_statement",
- "[keyword var] [variable x] [operator =] [number 10]",
+ "[keyword var] [def x] [operator =] [number 10]",
"[variable x] [operator +=] [variable y] [operator +]",
" [atom Infinity]",
"[keyword debugger];");
@@ -105,14 +105,14 @@
"}");
MT("indent_for",
- "[keyword for] ([keyword var] [variable i] [operator =] [number 0];",
+ "[keyword for] ([keyword var] [def i] [operator =] [number 0];",
" [variable i] [operator <] [number 100];",
" [variable i][operator ++])",
" [variable doSomething]([variable i]);",
"[keyword debugger];");
MT("indent_c_style",
- "[keyword function] [variable foo]()",
+ "[keyword function] [def foo]()",
"{",
" [keyword debugger];",
"}");
@@ -140,24 +140,32 @@
"[number 2];");
MT("multilinestring",
- "[keyword var] [variable x] [operator =] [string 'foo\\]",
+ "[keyword var] [def x] [operator =] [string 'foo\\]",
"[string bar'];");
MT("scary_regexp",
"[string-2 /foo[[/]]bar/];");
MT("indent_strange_array",
- "[keyword var] [variable x] [operator =] [[",
+ "[keyword var] [def x] [operator =] [[",
" [number 1],,",
" [number 2],",
"]];",
"[number 10];");
MT("param_default",
- "[keyword function] [variable foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {",
+ "[keyword function] [def foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {",
" [keyword return] [variable-2 x];",
"}");
+ MT("new_target",
+ "[keyword function] [def F]([def target]) {",
+ " [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {",
+ " [keyword return] [keyword new]",
+ " .[keyword target];",
+ " }",
+ "}");
+
var jsonld_mode = CodeMirror.getMode(
{indentUnit: 2},
{name: "javascript", jsonld: true}
diff --git a/mode/kotlin/index.html b/mode/kotlin/index.html
deleted file mode 100644
index 859e109fb8..0000000000
--- a/mode/kotlin/index.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-CodeMirror: Kotlin mode
-
-
-
-
-
-
-
-
-
-
-Kotlin mode
-
-
-
-
-
- Mode for Kotlin (http://kotlin.jetbrains.org/)
- Developed by Hadi Hariri (https://github.com/hhariri).
- MIME type defined: text/x-kotlin
.
-
diff --git a/mode/kotlin/kotlin.js b/mode/kotlin/kotlin.js
deleted file mode 100644
index e9a6a94e64..0000000000
--- a/mode/kotlin/kotlin.js
+++ /dev/null
@@ -1,284 +0,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: http://codemirror.net/LICENSE
-
-(function(mod) {
- if (typeof exports == "object" && typeof module == "object") // CommonJS
- mod(require("../../lib/codemirror"));
- else if (typeof define == "function" && define.amd) // AMD
- define(["../../lib/codemirror"], mod);
- else // Plain browser env
- mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.defineMode("kotlin", function (config, parserConfig) {
- function words(str) {
- var obj = {}, words = str.split(" ");
- for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
- return obj;
- }
-
- var multiLineStrings = parserConfig.multiLineStrings;
-
- var keywords = words(
- "package continue return object while break class data trait interface throw super" +
- " when type this else This try val var fun for is in if do as true false null get set");
- var softKeywords = words("import" +
- " where by get set abstract enum open annotation override private public internal" +
- " protected catch out vararg inline finally final ref");
- var blockKeywords = words("catch class do else finally for if where try while enum");
- var atoms = words("null true false this");
-
- var curPunc;
-
- function tokenBase(stream, state) {
- var ch = stream.next();
- if (ch == '"' || ch == "'") {
- return startString(ch, stream, state);
- }
- // Wildcard import w/o trailing semicolon (import smth.*)
- if (ch == "." && stream.eat("*")) {
- return "word";
- }
- if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
- curPunc = ch;
- return null;
- }
- if (/\d/.test(ch)) {
- if (stream.eat(/eE/)) {
- stream.eat(/\+\-/);
- stream.eatWhile(/\d/);
- }
- return "number";
- }
- if (ch == "/") {
- if (stream.eat("*")) {
- state.tokenize.push(tokenComment);
- return tokenComment(stream, state);
- }
- if (stream.eat("/")) {
- stream.skipToEnd();
- return "comment";
- }
- if (expectExpression(state.lastToken)) {
- return startString(ch, stream, state);
- }
- }
- // Commented
- if (ch == "-" && stream.eat(">")) {
- curPunc = "->";
- return null;
- }
- if (/[\-+*&%=<>!?|\/~]/.test(ch)) {
- stream.eatWhile(/[\-+*&%=<>|~]/);
- return "operator";
- }
- stream.eatWhile(/[\w\$_]/);
-
- var cur = stream.current();
- if (atoms.propertyIsEnumerable(cur)) {
- return "atom";
- }
- if (softKeywords.propertyIsEnumerable(cur)) {
- if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
- return "softKeyword";
- }
-
- if (keywords.propertyIsEnumerable(cur)) {
- if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
- return "keyword";
- }
- return "word";
- }
-
- tokenBase.isBase = true;
-
- function startString(quote, stream, state) {
- var tripleQuoted = false;
- if (quote != "/" && stream.eat(quote)) {
- if (stream.eat(quote)) tripleQuoted = true;
- else return "string";
- }
- function t(stream, state) {
- var escaped = false, next, end = !tripleQuoted;
-
- while ((next = stream.next()) != null) {
- if (next == quote && !escaped) {
- if (!tripleQuoted) {
- break;
- }
- if (stream.match(quote + quote)) {
- end = true;
- break;
- }
- }
-
- if (quote == '"' && next == "$" && !escaped && stream.eat("{")) {
- state.tokenize.push(tokenBaseUntilBrace());
- return "string";
- }
-
- if (next == "$" && !escaped && !stream.eat(" ")) {
- state.tokenize.push(tokenBaseUntilSpace());
- return "string";
- }
- escaped = !escaped && next == "\\";
- }
- if (multiLineStrings)
- state.tokenize.push(t);
- if (end) state.tokenize.pop();
- return "string";
- }
-
- state.tokenize.push(t);
- return t(stream, state);
- }
-
- function tokenBaseUntilBrace() {
- var depth = 1;
-
- function t(stream, state) {
- if (stream.peek() == "}") {
- depth--;
- if (depth == 0) {
- state.tokenize.pop();
- return state.tokenize[state.tokenize.length - 1](stream, state);
- }
- } else if (stream.peek() == "{") {
- depth++;
- }
- return tokenBase(stream, state);
- }
-
- t.isBase = true;
- return t;
- }
-
- function tokenBaseUntilSpace() {
- function t(stream, state) {
- if (stream.eat(/[\w]/)) {
- var isWord = stream.eatWhile(/[\w]/);
- if (isWord) {
- state.tokenize.pop();
- return "word";
- }
- }
- state.tokenize.pop();
- return "string";
- }
-
- t.isBase = true;
- return t;
- }
-
- function tokenComment(stream, state) {
- var maybeEnd = false, ch;
- while (ch = stream.next()) {
- if (ch == "/" && maybeEnd) {
- state.tokenize.pop();
- break;
- }
- maybeEnd = (ch == "*");
- }
- return "comment";
- }
-
- function expectExpression(last) {
- return !last || last == "operator" || last == "->" || /[\.\[\{\(,;:]/.test(last) ||
- last == "newstatement" || last == "keyword" || last == "proplabel";
- }
-
- function Context(indented, column, type, align, prev) {
- this.indented = indented;
- this.column = column;
- this.type = type;
- this.align = align;
- this.prev = prev;
- }
-
- function pushContext(state, col, type) {
- return state.context = new Context(state.indented, col, type, null, state.context);
- }
-
- function popContext(state) {
- var t = state.context.type;
- if (t == ")" || t == "]" || t == "}")
- state.indented = state.context.indented;
- return state.context = state.context.prev;
- }
-
- // Interface
-
- return {
- startState: function (basecolumn) {
- return {
- tokenize: [tokenBase],
- context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false),
- indented: 0,
- startOfLine: true,
- lastToken: null
- };
- },
-
- token: function (stream, state) {
- var ctx = state.context;
- if (stream.sol()) {
- if (ctx.align == null) ctx.align = false;
- state.indented = stream.indentation();
- state.startOfLine = true;
- // Automatic semicolon insertion
- if (ctx.type == "statement" && !expectExpression(state.lastToken)) {
- popContext(state);
- ctx = state.context;
- }
- }
- if (stream.eatSpace()) return null;
- curPunc = null;
- var style = state.tokenize[state.tokenize.length - 1](stream, state);
- if (style == "comment") return style;
- if (ctx.align == null) ctx.align = true;
- if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
- // Handle indentation for {x -> \n ... }
- else if (curPunc == "->" && ctx.type == "statement" && ctx.prev.type == "}") {
- popContext(state);
- state.context.align = false;
- }
- else if (curPunc == "{") pushContext(state, stream.column(), "}");
- else if (curPunc == "[") pushContext(state, stream.column(), "]");
- else if (curPunc == "(") pushContext(state, stream.column(), ")");
- else if (curPunc == "}") {
- while (ctx.type == "statement") ctx = popContext(state);
- if (ctx.type == "}") ctx = popContext(state);
- while (ctx.type == "statement") ctx = popContext(state);
- }
- else if (curPunc == ctx.type) popContext(state);
- else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
- pushContext(state, stream.column(), "statement");
- state.startOfLine = false;
- state.lastToken = curPunc || style;
- return style;
- },
-
- indent: function (state, textAfter) {
- if (!state.tokenize[state.tokenize.length - 1].isBase) return 0;
- var firstChar = textAfter && textAfter.charAt(0), ctx = state.context;
- if (ctx.type == "statement" && !expectExpression(state.lastToken)) ctx = ctx.prev;
- var closing = firstChar == ctx.type;
- if (ctx.type == "statement") {
- return ctx.indented + (firstChar == "{" ? 0 : config.indentUnit);
- }
- else if (ctx.align) return ctx.column + (closing ? 0 : 1);
- else return ctx.indented + (closing ? 0 : config.indentUnit);
- },
-
- closeBrackets: {triples: "'\""},
- electricChars: "{}",
- blockCommentStart: "/*",
- blockCommentEnd: "*/",
- lineComment: "//"
- };
-});
-
-CodeMirror.defineMIME("text/x-kotlin", "kotlin");
-
-});
diff --git a/mode/markdown/markdown.js b/mode/markdown/markdown.js
index 9d40368180..2349ddf22b 100644
--- a/mode/markdown/markdown.js
+++ b/mode/markdown/markdown.js
@@ -51,24 +51,36 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (modeCfg.strikethrough === undefined)
modeCfg.strikethrough = false;
+ // Allow token types to be overridden by user-provided token types.
+ if (modeCfg.tokenTypeOverrides === undefined)
+ modeCfg.tokenTypeOverrides = {};
+
var codeDepth = 0;
- var header = 'header'
- , code = 'comment'
- , quote = 'quote'
- , list1 = 'variable-2'
- , list2 = 'variable-3'
- , list3 = 'keyword'
- , hr = 'hr'
- , image = 'tag'
- , formatting = 'formatting'
- , linkinline = 'link'
- , linkemail = 'link'
- , linktext = 'link'
- , linkhref = 'string'
- , em = 'em'
- , strong = 'strong'
- , strikethrough = 'strikethrough';
+ var tokenTypes = {
+ header: "header",
+ code: "comment",
+ quote: "quote",
+ list1: "variable-2",
+ list2: "variable-3",
+ list3: "keyword",
+ hr: "hr",
+ image: "tag",
+ formatting: "formatting",
+ linkInline: "link",
+ linkEmail: "link",
+ linkText: "link",
+ linkHref: "string",
+ em: "em",
+ strong: "strong",
+ strikethrough: "strikethrough"
+ };
+
+ for (var tokenType in tokenTypes) {
+ if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) {
+ tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType];
+ }
+ }
var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
, ulRE = /^[*\-+]\s+/
@@ -152,7 +164,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
state.indentation -= 4;
state.indentedCode = true;
- return code;
+ return tokenTypes.code;
} else {
return null;
}
@@ -178,7 +190,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return switchInline(stream, state, footnoteLink);
} else if (stream.match(hrRE, true)) {
state.hr = true;
- return hr;
+ return tokenTypes.hr;
} else if ((lineIsEmpty(state.prevLine) || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
var listType = null;
if (stream.match(ulRE, true)) {
@@ -231,7 +243,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
return state.localMode.token(stream, state.localState);
} else {
stream.skipToEnd();
- return code;
+ return tokenTypes.code;
}
}
@@ -252,22 +264,22 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
var styles = [];
if (state.formatting) {
- styles.push(formatting);
+ styles.push(tokenTypes.formatting);
if (typeof state.formatting === "string") state.formatting = [state.formatting];
for (var i = 0; i < state.formatting.length; i++) {
- styles.push(formatting + "-" + state.formatting[i]);
+ styles.push(tokenTypes.formatting + "-" + state.formatting[i]);
if (state.formatting[i] === "header") {
- styles.push(formatting + "-" + state.formatting[i] + "-" + state.header);
+ styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header);
}
// Add `formatting-quote` and `formatting-quote-#` for blockquotes
// Add `error` instead if the maximum blockquote nesting depth is passed
if (state.formatting[i] === "quote") {
if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
- styles.push(formatting + "-" + state.formatting[i] + "-" + state.quote);
+ styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote);
} else {
styles.push("error");
}
@@ -285,38 +297,36 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
}
if (state.linkHref) {
- styles.push(linkhref, "url");
+ styles.push(tokenTypes.linkHref, "url");
} else { // Only apply inline styles to non-url text
- if (state.strong) { styles.push(strong); }
- if (state.em) { styles.push(em); }
- if (state.strikethrough) { styles.push(strikethrough); }
-
- if (state.linkText) { styles.push(linktext); }
-
- if (state.code) { styles.push(code); }
+ if (state.strong) { styles.push(tokenTypes.strong); }
+ if (state.em) { styles.push(tokenTypes.em); }
+ if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
+ if (state.linkText) { styles.push(tokenTypes.linkText); }
+ if (state.code) { styles.push(tokenTypes.code); }
}
- if (state.header) { styles.push(header); styles.push(header + "-" + state.header); }
+ if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
if (state.quote) {
- styles.push(quote);
+ styles.push(tokenTypes.quote);
// Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
- styles.push(quote + "-" + state.quote);
+ styles.push(tokenTypes.quote + "-" + state.quote);
} else {
- styles.push(quote + "-" + modeCfg.maxBlockquoteDepth);
+ styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
}
}
if (state.list !== false) {
var listMod = (state.listDepth - 1) % 3;
if (!listMod) {
- styles.push(list1);
+ styles.push(tokenTypes.list1);
} else if (listMod === 1) {
- styles.push(list2);
+ styles.push(tokenTypes.list2);
} else {
- styles.push(list3);
+ styles.push(tokenTypes.list3);
}
}
@@ -372,7 +382,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
stream.next();
if (modeCfg.highlightFormatting) {
var type = getType(state);
- return type ? type + " formatting-escape" : "formatting-escape";
+ var formattingEscape = tokenTypes.formatting + "-escape";
+ return type ? type + " " + formattingEscape : formattingEscape;
}
}
@@ -386,7 +397,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
if (stream.match(new RegExp(regex), true)) {
- return linkhref;
+ return tokenTypes.linkHref;
}
}
@@ -417,7 +428,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
stream.match(/\[[^\]]*\]/);
state.inline = state.f = linkHref;
- return image;
+ return tokenTypes.image;
}
if (ch === '[' && stream.match(/.*\](\(.*\)| ?\[.*\])/, false)) {
@@ -443,7 +454,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
} else {
type = "";
}
- return type + linkinline;
+ return type + tokenTypes.linkInline;
}
if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
@@ -455,7 +466,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
} else {
type = "";
}
- return type + linkemail;
+ return type + tokenTypes.linkEmail;
}
if (ch === '<' && stream.match(/^(!--|\w)/, false)) {
@@ -564,12 +575,12 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
} else {
type = "";
}
- return type + linkinline;
+ return type + tokenTypes.linkInline;
}
stream.match(/^[^>]+/, true);
- return linkinline;
+ return tokenTypes.linkInline;
}
function linkHref(stream, state) {
@@ -630,7 +641,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
stream.match(/^[^\]]+/, true);
- return linktext;
+ return tokenTypes.linkText;
}
function footnoteUrl(stream, state) {
@@ -647,7 +658,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
}
state.f = state.inline = inlineNormal;
- return linkhref + " url";
+ return tokenTypes.linkHref + " url";
}
var savedInlineRE = [];
diff --git a/mode/markdown/test.js b/mode/markdown/test.js
index 78b6c685af..f9cc27c3b4 100644
--- a/mode/markdown/test.js
+++ b/mode/markdown/test.js
@@ -10,6 +10,35 @@
function AtxNoSpaceTest(name) { test.mode(name, modeAtxNoSpace, Array.prototype.slice.call(arguments, 1)); }
var modeFenced = CodeMirror.getMode({tabSize: 4}, {name: "markdown", fencedCodeBlocks: true});
function FencedTest(name) { test.mode(name, modeFenced, Array.prototype.slice.call(arguments, 1)); }
+ var modeOverrideClasses = CodeMirror.getMode({tabsize: 4}, {
+ name: "markdown",
+ strikethrough: true,
+ tokenTypeOverrides: {
+ "header" : "override-header",
+ "code" : "override-code",
+ "quote" : "override-quote",
+ "list1" : "override-list1",
+ "list2" : "override-list2",
+ "list3" : "override-list3",
+ "hr" : "override-hr",
+ "image" : "override-image",
+ "linkInline" : "override-link-inline",
+ "linkEmail" : "override-link-email",
+ "linkText" : "override-link-text",
+ "linkHref" : "override-link-href",
+ "em" : "override-em",
+ "strong" : "override-strong",
+ "strikethrough" : "override-strikethrough"
+ }});
+ function TokenTypeOverrideTest(name) { test.mode(name, modeOverrideClasses, Array.prototype.slice.call(arguments, 1)); }
+ var modeFormattingOverride = CodeMirror.getMode({tabsize: 4}, {
+ name: "markdown",
+ highlightFormatting: true,
+ tokenTypeOverrides: {
+ "formatting" : "override-formatting"
+ }});
+ function FormatTokenTypeOverrideTest(name) { test.mode(name, modeFormattingOverride, Array.prototype.slice.call(arguments, 1)); }
+
FT("formatting_emAsterisk",
"[em&formatting&formatting-em *][em foo][em&formatting&formatting-em *]");
@@ -774,6 +803,76 @@
"\\",
"[em *foo*]");
+ // Class override tests
+ TokenTypeOverrideTest("overrideHeader1",
+ "[override-header&override-header-1 # Foo]");
+
+ TokenTypeOverrideTest("overrideHeader2",
+ "[override-header&override-header-2 ## Foo]");
+
+ TokenTypeOverrideTest("overrideHeader3",
+ "[override-header&override-header-3 ### Foo]");
+
+ TokenTypeOverrideTest("overrideHeader4",
+ "[override-header&override-header-4 #### Foo]");
+
+ TokenTypeOverrideTest("overrideHeader5",
+ "[override-header&override-header-5 ##### Foo]");
+
+ TokenTypeOverrideTest("overrideHeader6",
+ "[override-header&override-header-6 ###### Foo]");
+
+ TokenTypeOverrideTest("overrideCode",
+ "[override-code `foo`]");
+
+ TokenTypeOverrideTest("overrideCodeBlock",
+ "[override-code ```]",
+ "[override-code foo]",
+ "[override-code ```]");
+
+ TokenTypeOverrideTest("overrideQuote",
+ "[override-quote&override-quote-1 > foo]",
+ "[override-quote&override-quote-1 > bar]");
+
+ TokenTypeOverrideTest("overrideQuoteNested",
+ "[override-quote&override-quote-1 > foo]",
+ "[override-quote&override-quote-1 >][override-quote&override-quote-2 > bar]",
+ "[override-quote&override-quote-1 >][override-quote&override-quote-2 >][override-quote&override-quote-3 > baz]");
+
+ TokenTypeOverrideTest("overrideLists",
+ "[override-list1 - foo]",
+ "",
+ " [override-list2 + bar]",
+ "",
+ " [override-list3 * baz]",
+ "",
+ " [override-list1 1. qux]",
+ "",
+ " [override-list2 - quux]");
+
+ TokenTypeOverrideTest("overrideHr",
+ "[override-hr * * *]");
+
+ TokenTypeOverrideTest("overrideImage",
+ "[override-image ![[foo]]][override-link-href&url (http://example.com/)]")
+
+ TokenTypeOverrideTest("overrideLinkText",
+ "[override-link-text [[foo]]][override-link-href&url (http://example.com)]");
+
+ TokenTypeOverrideTest("overrideLinkEmailAndInline",
+ "[override-link-email <][override-link-inline foo@example.com>]");
+
+ TokenTypeOverrideTest("overrideEm",
+ "[override-em *foo*]");
+
+ TokenTypeOverrideTest("overrideStrong",
+ "[override-strong **foo**]");
+
+ TokenTypeOverrideTest("overrideStrikethrough",
+ "[override-strikethrough ~~foo~~]");
+
+ FormatTokenTypeOverrideTest("overrideFormatting",
+ "[override-formatting-escape \\*]");
// Tests to make sure GFM-specific things aren't getting through
diff --git a/mode/meta.js b/mode/meta.js
index 3a14dfc588..7af51c1ec5 100644
--- a/mode/meta.js
+++ b/mode/meta.js
@@ -70,7 +70,7 @@
{name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]},
{name: "Jinja2", mime: "null", mode: "jinja2"},
{name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]},
- {name: "Kotlin", mime: "text/x-kotlin", mode: "kotlin", ext: ["kt"]},
+ {name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]},
{name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
{name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]},
{name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]},
@@ -83,6 +83,7 @@
{name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
{name: "MySQL", mime: "text/x-mysql", mode: "sql"},
{name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i},
+ {name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]},
{name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]},
{name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"]},
{name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
@@ -109,7 +110,7 @@
{name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
{name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
{name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]},
- {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"]},
+ {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/},
{name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]},
{name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
{name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
diff --git a/mode/nsis/index.html b/mode/nsis/index.html
new file mode 100644
index 0000000000..a1d7aaa586
--- /dev/null
+++ b/mode/nsis/index.html
@@ -0,0 +1,62 @@
+
+
+CodeMirror: NSIS mode
+
+
+
+
+
+
+
+
+
+
+
+
+NSIS mode
+
+
+
+
+
+
+MIME types defined: text/x-nsis
.
+
diff --git a/mode/nsis/nsis.js b/mode/nsis/nsis.js
new file mode 100644
index 0000000000..93dd7421e8
--- /dev/null
+++ b/mode/nsis/nsis.js
@@ -0,0 +1,63 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+// Author: Jan T. Sott (http://github.com/idleberg)
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineSimpleMode("nsis",{
+ start:[
+ // Numbers
+ {regex: /(?:[+-]?)(?:0x[\d,a-f]+)|(?:0o[0-7]+)|(?:0b[0,1]+)|(?:\d+.?\d*)/, token: "number"},
+ // Compile Time Commands
+ {regex: /(?:\!(include|addincludedir|addplugindir|appendfile|cd|delfile|echo|error|execute|packhdr|finalize|getdllversion|system|tempfile|warning|verbose|define|undef|insertmacro|makensis|searchparse|searchreplace))\b/, token: "keyword"},
+ // Conditional Compilation
+ {regex: /(?:\!(if(?:n?def)?|ifmacron?def|macro))\b/, token: "keyword", indent: true},
+ {regex: /(?:\!(else|endif|macroend))\b/, token: "keyword", dedent: true},
+ // Runtime Commands
+ {regex: /(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|IntCmp|IntCmpU|IntFmt|IntOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetPluginUnload|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegStr|WriteUninstaller|XPStyle)\b/, token: "keyword"},
+ {regex: /\b(?:Function|PageEx|Section(?:Group)?)\b/, token: "keyword", indent: true},
+ {regex: /\b(?:(Function|PageEx|Section(?:Group)?)End)\b/, token: "keyword", dedent: true},
+ // Options
+ {regex: /\b(?:ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HIDDEN|HKCC|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDD_DIR|IDD_INST|IDD_INSTFILES|IDD_LICENSE|IDD_SELCOM|IDD_UNINST|IDD_VERIFY|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|MB_YESNOCANCEL|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SW_HIDE|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWNORMAL|SYSTEM|TEMPORARY)\b/, token: "atom"},
+ {regex: /\b(?:admin|all|auto|both|bottom|bzip2|components|current|custom|directory|force|hide|highest|ifdiff|ifnewer|instfiles|lastused|leave|left|license|listonly|lzma|nevershow|none|normal|notset|right|show|silent|silentlog|textonly|top|try|un\.components|un\.custom|un\.directory|un\.instfiles|un\.license|uninstConfirm|user|Win10|Win7|Win8|WinVista|zlib)\b/, token: "builtin"},
+
+ // LogicLib
+ {regex: /\$\{(?:End(If|Unless|While)|Loop(?:Until)|Next)\}/, token: "variable-2", dedent: true},
+ {regex: /\$\{(?:Do(Until|While)|Else(?:If(?:Not)?)?|For(?:Each)?|(?:(?:And|Else|Or)?If(?:Cmd|Not|Then)?|Unless)|While)\}/, token: "variable-2", indent: true},
+
+ // Line Comment
+ {regex: /(#|;).*/, token: "comment"},
+ // Block Comment
+ {regex: /\/\*/, token: "comment", next: "comment"},
+ // Operator
+ {regex: /[-+\/*=<>!]+/, token: "operator"},
+ // Variable
+ {regex: /\$[\w]+/, token: "variable"},
+ // Constant
+ {regex: /\${[\w]+}/,token: "variable-2"},
+ // Language String
+ {regex: /\$\([\w]+\)/,token: "variable-3"}
+ ],
+ comment: [
+ {regex: /.*?\*\//, token: "comment", next: "start"},
+ {regex: /.*/, token: "comment"}
+ ],
+ meta: {
+ electricInput: /^\s*((Function|PageEx|Section|Section(Group)?)End|(\!(endif|macroend))|\$\{(End(If|Unless|While)|Loop(Until)|Next)\})$/,
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ lineComment: ["#", ";"]
+ }
+});
+
+CodeMirror.defineMIME("text/x-nsis", "nsis");
+});
diff --git a/mode/rpm/rpm.js b/mode/rpm/rpm.js
index 3bb7cd2f62..87cde591a3 100644
--- a/mode/rpm/rpm.js
+++ b/mode/rpm/rpm.js
@@ -34,10 +34,10 @@ CodeMirror.defineMIME("text/x-rpm-changes", "rpm-changes");
// Quick and dirty spec file highlighting
CodeMirror.defineMode("rpm-spec", function() {
- var arch = /^(i386|i586|i686|x86_64|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/;
+ var arch = /^(i386|i586|i686|x86_64|ppc64le|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/;
- var preamble = /^(Name|Version|Release|License|Summary|Url|Group|Source|BuildArch|BuildRequires|BuildRoot|AutoReqProv|Provides|Requires(\(\w+\))?|Obsoletes|Conflicts|Recommends|Source\d*|Patch\d*|ExclusiveArch|NoSource|Supplements):/;
- var section = /^%(debug_package|package|description|prep|build|install|files|clean|changelog|preinstall|preun|postinstall|postun|pre|post|triggerin|triggerun|pretrans|posttrans|verifyscript|check|triggerpostun|triggerprein|trigger)/;
+ var preamble = /^[a-zA-Z0-9()]+:/;
+ var section = /^%(debug_package|package|description|prep|build|install|files|clean|changelog|preinstall|preun|postinstall|postun|pretrans|posttrans|pre|post|triggerin|triggerun|verifyscript|check|triggerpostun|triggerprein|trigger)/;
var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros
var control_flow_simple = /^%(else|endif)/; // rpm control flow macros
var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros
@@ -55,8 +55,8 @@ CodeMirror.defineMode("rpm-spec", function() {
if (ch == "#") { stream.skipToEnd(); return "comment"; }
if (stream.sol()) {
- if (stream.match(preamble)) { return "preamble"; }
- if (stream.match(section)) { return "section"; }
+ if (stream.match(preamble)) { return "header"; }
+ if (stream.match(section)) { return "atom"; }
}
if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT'
@@ -73,21 +73,29 @@ CodeMirror.defineMode("rpm-spec", function() {
if (stream.eol()) { state.controlFlow = false; }
}
- if (stream.match(arch)) { return "number"; }
+ if (stream.match(arch)) {
+ if (stream.eol()) { state.controlFlow = false; }
+ return "number";
+ }
// Macros like '%make_install' or '%attr(0775,root,root)'
if (stream.match(/^%[\w]+/)) {
if (stream.match(/^\(/)) { state.macroParameters = true; }
- return "macro";
+ return "keyword";
}
if (state.macroParameters) {
if (stream.match(/^\d+/)) { return "number";}
if (stream.match(/^\)/)) {
state.macroParameters = false;
- return "macro";
+ return "keyword";
}
}
- if (stream.match(/^%\{\??[\w \-]+\}/)) { return "macro"; } // Macros like '%{defined fedora}'
+
+ // Macros like '%{defined fedora}'
+ if (stream.match(/^%\{\??[\w \-\:\!]+\}/)) {
+ if (stream.eol()) { state.controlFlow = false; }
+ return "def";
+ }
//TODO: Include bash script sub-parser (CodeMirror supports that)
stream.next();
diff --git a/package.json b/package.json
index dc064040bb..bda0357da9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "codemirror",
- "version":"5.7.0",
+ "version":"5.8.0",
"main": "lib/codemirror.js",
"description": "In-browser code editing made bearable",
"license": "MIT",
diff --git a/test/comment_test.js b/test/comment_test.js
index 8bd3959ee9..26e474493b 100644
--- a/test/comment_test.js
+++ b/test/comment_test.js
@@ -79,7 +79,7 @@ namespace = "comment_";
test("indented", "javascript", function(cm) {
cm.lineComment(Pos(1, 0), Pos(2), {indent: true});
- }, simpleProg, "function foo() {\n // return bar;\n // }");
+ }, simpleProg, "function foo() {\n// return bar;\n// }");
test("singleEmptyLine", "javascript", function(cm) {
cm.setCursor(1);
diff --git a/theme/abcdef.css b/theme/abcdef.css
index 142d813703..7f9d788704 100644
--- a/theme/abcdef.css
+++ b/theme/abcdef.css
@@ -27,6 +27,6 @@
.cm-s-abcdef span.cm-attribute { color: #DDFF00; }
.cm-s-abcdef span.cm-error { color: #FF0000; }
.cm-s-abcdef span.cm-header { color: aquamarine; font-weight: bold; }
-.cm-s-abcdef span.cm-link { color: blue; }
+.cm-s-abcdef span.cm-link { color: blueviolet; }
.cm-s-abcdef .CodeMirror-activeline-background { background: #314151; }
diff --git a/theme/base16-dark.css b/theme/base16-dark.css
index 81dac03923..026a816890 100644
--- a/theme/base16-dark.css
+++ b/theme/base16-dark.css
@@ -3,7 +3,7 @@
Name: Base16 Default Dark
Author: Chris Kempson (http://chriskempson.com)
- CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-chrome-devtools)
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
*/
diff --git a/theme/base16-light.css b/theme/base16-light.css
index e645678f8a..474e0ca9d1 100644
--- a/theme/base16-light.css
+++ b/theme/base16-light.css
@@ -3,7 +3,7 @@
Name: Base16 Default Light
Author: Chris Kempson (http://chriskempson.com)
- CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-chrome-devtools)
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
*/
diff --git a/theme/bespin.css b/theme/bespin.css
new file mode 100644
index 0000000000..60913ba938
--- /dev/null
+++ b/theme/bespin.css
@@ -0,0 +1,34 @@
+/*
+
+ Name: Bespin
+ Author: Mozilla / Jan T. Sott
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-bespin.CodeMirror {background: #28211c; color: #9d9b97;}
+.cm-s-bespin div.CodeMirror-selected {background: #36312e !important;}
+.cm-s-bespin .CodeMirror-gutters {background: #28211c; border-right: 0px;}
+.cm-s-bespin .CodeMirror-linenumber {color: #666666;}
+.cm-s-bespin .CodeMirror-cursor {border-left: 1px solid #797977 !important;}
+
+.cm-s-bespin span.cm-comment {color: #937121;}
+.cm-s-bespin span.cm-atom {color: #9b859d;}
+.cm-s-bespin span.cm-number {color: #9b859d;}
+
+.cm-s-bespin span.cm-property, .cm-s-bespin span.cm-attribute {color: #54be0d;}
+.cm-s-bespin span.cm-keyword {color: #cf6a4c;}
+.cm-s-bespin span.cm-string {color: #f9ee98;}
+
+.cm-s-bespin span.cm-variable {color: #54be0d;}
+.cm-s-bespin span.cm-variable-2 {color: #5ea6ea;}
+.cm-s-bespin span.cm-def {color: #cf7d34;}
+.cm-s-bespin span.cm-error {background: #cf6a4c; color: #797977;}
+.cm-s-bespin span.cm-bracket {color: #9d9b97;}
+.cm-s-bespin span.cm-tag {color: #cf6a4c;}
+.cm-s-bespin span.cm-link {color: #9b859d;}
+
+.cm-s-bespin .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
+.cm-s-bespin .CodeMirror-activeline-background { background: #404040; }
diff --git a/theme/hopscotch.css b/theme/hopscotch.css
new file mode 100644
index 0000000000..7d05431bdc
--- /dev/null
+++ b/theme/hopscotch.css
@@ -0,0 +1,34 @@
+/*
+
+ Name: Hopscotch
+ Author: Jan T. Sott
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-hopscotch.CodeMirror {background: #322931; color: #d5d3d5;}
+.cm-s-hopscotch div.CodeMirror-selected {background: #433b42 !important;}
+.cm-s-hopscotch .CodeMirror-gutters {background: #322931; border-right: 0px;}
+.cm-s-hopscotch .CodeMirror-linenumber {color: #797379;}
+.cm-s-hopscotch .CodeMirror-cursor {border-left: 1px solid #989498 !important;}
+
+.cm-s-hopscotch span.cm-comment {color: #b33508;}
+.cm-s-hopscotch span.cm-atom {color: #c85e7c;}
+.cm-s-hopscotch span.cm-number {color: #c85e7c;}
+
+.cm-s-hopscotch span.cm-property, .cm-s-hopscotch span.cm-attribute {color: #8fc13e;}
+.cm-s-hopscotch span.cm-keyword {color: #dd464c;}
+.cm-s-hopscotch span.cm-string {color: #fdcc59;}
+
+.cm-s-hopscotch span.cm-variable {color: #8fc13e;}
+.cm-s-hopscotch span.cm-variable-2 {color: #1290bf;}
+.cm-s-hopscotch span.cm-def {color: #fd8b19;}
+.cm-s-hopscotch span.cm-error {background: #dd464c; color: #989498;}
+.cm-s-hopscotch span.cm-bracket {color: #d5d3d5;}
+.cm-s-hopscotch span.cm-tag {color: #dd464c;}
+.cm-s-hopscotch span.cm-link {color: #c85e7c;}
+
+.cm-s-hopscotch .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
+.cm-s-hopscotch .CodeMirror-activeline-background { background: #302020; }
diff --git a/theme/isotope.css b/theme/isotope.css
new file mode 100644
index 0000000000..d0d6263cf4
--- /dev/null
+++ b/theme/isotope.css
@@ -0,0 +1,34 @@
+/*
+
+ Name: Isotope
+ Author: David Desandro / Jan T. Sott
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-isotope.CodeMirror {background: #000000; color: #e0e0e0;}
+.cm-s-isotope div.CodeMirror-selected {background: #404040 !important;}
+.cm-s-isotope .CodeMirror-gutters {background: #000000; border-right: 0px;}
+.cm-s-isotope .CodeMirror-linenumber {color: #808080;}
+.cm-s-isotope .CodeMirror-cursor {border-left: 1px solid #c0c0c0 !important;}
+
+.cm-s-isotope span.cm-comment {color: #3300ff;}
+.cm-s-isotope span.cm-atom {color: #cc00ff;}
+.cm-s-isotope span.cm-number {color: #cc00ff;}
+
+.cm-s-isotope span.cm-property, .cm-s-isotope span.cm-attribute {color: #33ff00;}
+.cm-s-isotope span.cm-keyword {color: #ff0000;}
+.cm-s-isotope span.cm-string {color: #ff0099;}
+
+.cm-s-isotope span.cm-variable {color: #33ff00;}
+.cm-s-isotope span.cm-variable-2 {color: #0066ff;}
+.cm-s-isotope span.cm-def {color: #ff9900;}
+.cm-s-isotope span.cm-error {background: #ff0000; color: #c0c0c0;}
+.cm-s-isotope span.cm-bracket {color: #e0e0e0;}
+.cm-s-isotope span.cm-tag {color: #ff0000;}
+.cm-s-isotope span.cm-link {color: #cc00ff;}
+
+.cm-s-isotope .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
+.cm-s-isotope .CodeMirror-activeline-background { background: #202020; }
diff --git a/theme/liquibyte.css b/theme/liquibyte.css
index c64c25c743..9db8bde739 100644
--- a/theme/liquibyte.css
+++ b/theme/liquibyte.css
@@ -4,17 +4,17 @@
line-height: 1.2em;
font-size: 1em;
}
-.CodeMirror-focused .cm-matchhighlight {
+.cm-s-liquibyte .CodeMirror-focused .cm-matchhighlight {
text-decoration: underline;
text-decoration-color: #0f0;
text-decoration-style: wavy;
}
-.cm-trailingspace {
+.cm-s-liquibyte .cm-trailingspace {
text-decoration: line-through;
text-decoration-color: #f00;
text-decoration-style: dotted;
}
-.cm-tab {
+.cm-s-liquibyte .cm-tab {
text-decoration: line-through;
text-decoration-color: #404040;
text-decoration-style: dotted;
@@ -54,42 +54,42 @@
.cm-s-liquibyte .CodeMirror-activeline-background { background-color: rgba(0, 255, 0, 0.15); }
/* Default styles for common addons */
-div.CodeMirror span.CodeMirror-matchingbracket { color: #0f0; font-weight: bold; }
-div.CodeMirror span.CodeMirror-nonmatchingbracket { color: #f00; font-weight: bold; }
+.cm-s-liquibyte .CodeMirror span.CodeMirror-matchingbracket { color: #0f0; font-weight: bold; }
+.cm-s-liquibyte .CodeMirror span.CodeMirror-nonmatchingbracket { color: #f00; font-weight: bold; }
.CodeMirror-matchingtag { background-color: rgba(150, 255, 0, .3); }
/* Scrollbars */
/* Simple */
-div.CodeMirror-simplescroll-horizontal div:hover, div.CodeMirror-simplescroll-vertical div:hover {
+.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div:hover, div.CodeMirror-simplescroll-vertical div:hover {
background-color: rgba(80, 80, 80, .7);
}
-div.CodeMirror-simplescroll-horizontal div, div.CodeMirror-simplescroll-vertical div {
+.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div, div.CodeMirror-simplescroll-vertical div {
background-color: rgba(80, 80, 80, .3);
border: 1px solid #404040;
border-radius: 5px;
}
-div.CodeMirror-simplescroll-vertical div {
+.cm-s-liquibyte div.CodeMirror-simplescroll-vertical div {
border-top: 1px solid #404040;
border-bottom: 1px solid #404040;
}
-div.CodeMirror-simplescroll-horizontal div {
+.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div {
border-left: 1px solid #404040;
border-right: 1px solid #404040;
}
-div.CodeMirror-simplescroll-vertical {
+.cm-s-liquibyte div.CodeMirror-simplescroll-vertical {
background-color: #262626;
}
-div.CodeMirror-simplescroll-horizontal {
+.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal {
background-color: #262626;
border-top: 1px solid #404040;
}
/* Overlay */
-div.CodeMirror-overlayscroll-horizontal div, div.CodeMirror-overlayscroll-vertical div {
+.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div, div.CodeMirror-overlayscroll-vertical div {
background-color: #404040;
border-radius: 5px;
}
-div.CodeMirror-overlayscroll-vertical div {
+.cm-s-liquibyte div.CodeMirror-overlayscroll-vertical div {
border: 1px solid #404040;
}
-div.CodeMirror-overlayscroll-horizontal div {
+.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div {
border: 1px solid #404040;
}
diff --git a/theme/railscasts.css b/theme/railscasts.css
new file mode 100644
index 0000000000..aeff0449d5
--- /dev/null
+++ b/theme/railscasts.css
@@ -0,0 +1,34 @@
+/*
+
+ Name: Railscasts
+ Author: Ryan Bates (http://railscasts.com)
+
+ CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
+ Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
+
+*/
+
+.cm-s-railscasts.CodeMirror {background: #2b2b2b; color: #f4f1ed;}
+.cm-s-railscasts div.CodeMirror-selected {background: #272935 !important;}
+.cm-s-railscasts .CodeMirror-gutters {background: #2b2b2b; border-right: 0px;}
+.cm-s-railscasts .CodeMirror-linenumber {color: #5a647e;}
+.cm-s-railscasts .CodeMirror-cursor {border-left: 1px solid #d4cfc9 !important;}
+
+.cm-s-railscasts span.cm-comment {color: #bc9458;}
+.cm-s-railscasts span.cm-atom {color: #b6b3eb;}
+.cm-s-railscasts span.cm-number {color: #b6b3eb;}
+
+.cm-s-railscasts span.cm-property, .cm-s-railscasts span.cm-attribute {color: #a5c261;}
+.cm-s-railscasts span.cm-keyword {color: #da4939;}
+.cm-s-railscasts span.cm-string {color: #ffc66d;}
+
+.cm-s-railscasts span.cm-variable {color: #a5c261;}
+.cm-s-railscasts span.cm-variable-2 {color: #6d9cbe;}
+.cm-s-railscasts span.cm-def {color: #cc7833;}
+.cm-s-railscasts span.cm-error {background: #da4939; color: #d4cfc9;}
+.cm-s-railscasts span.cm-bracket {color: #f4f1ed;}
+.cm-s-railscasts span.cm-tag {color: #da4939;}
+.cm-s-railscasts span.cm-link {color: #b6b3eb;}
+
+.cm-s-railscasts .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
+.cm-s-railscasts .CodeMirror-activeline-background { background: #303040; }