##// END OF EJS Templates
codemirror: update from 5.4.0 to 5.11.0, fixes #3154
marcink -
r346:1a48416d default
parent child Browse files
Show More
@@ -165,7 +165,7 b' div.CodeMirror span.CodeMirror-nonmatchi'
165 }
165 }
166
166
167 /* The fake, visible scrollbars. Used to force redraw during scrolling
167 /* The fake, visible scrollbars. Used to force redraw during scrolling
168 before actuall scrolling happens, thus preventing shaking and
168 before actual scrolling happens, thus preventing shaking and
169 flickering artifacts. */
169 flickering artifacts. */
170 .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
170 .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
171 position: absolute;
171 position: absolute;
@@ -207,6 +207,11 b' div.CodeMirror span.CodeMirror-nonmatchi'
207 z-index: 4;
207 z-index: 4;
208 height: 100%;
208 height: 100%;
209 }
209 }
210 .CodeMirror-gutter-background {
211 position: absolute;
212 top: 0; bottom: 0;
213 z-index: 4;
214 }
210 .CodeMirror-gutter-elt {
215 .CodeMirror-gutter-elt {
211 position: absolute;
216 position: absolute;
212 cursor: default;
217 cursor: default;
@@ -280,7 +285,7 b' div.CodeMirror span.CodeMirror-nonmatchi'
280 overflow: hidden;
285 overflow: hidden;
281 visibility: hidden;
286 visibility: hidden;
282 }
287 }
283 .CodeMirror-measure pre { position: static; }
288
284
289
285 .CodeMirror div.CodeMirror-cursor {
290 .CodeMirror div.CodeMirror-cursor {
286 position: absolute;
291 position: absolute;
@@ -288,11 +293,17 b' div.CodeMirror span.CodeMirror-nonmatchi'
288 width: 0;
293 width: 0;
289 }
294 }
290
295
296 .CodeMirror-measure pre { position: static; }
297
291 div.CodeMirror-cursors {
298 div.CodeMirror-cursors {
292 visibility: hidden;
299 visibility: hidden;
293 position: relative;
300 position: relative;
294 z-index: 3;
301 z-index: 3;
295 }
302 }
303 div.CodeMirror-dragcursors {
304 visibility: visible;
305 }
306
296 .CodeMirror-focused div.CodeMirror-cursors {
307 .CodeMirror-focused div.CodeMirror-cursors {
297 visibility: visible;
308 visibility: visible;
298 }
309 }
@@ -300,8 +311,8 b' div.CodeMirror-cursors {'
300 .CodeMirror-selected { background: #d9d9d9; }
311 .CodeMirror-selected { background: #d9d9d9; }
301 .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
312 .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
302 .CodeMirror-crosshair { cursor: crosshair; }
313 .CodeMirror-crosshair { cursor: crosshair; }
303 .CodeMirror ::selection { background: #d7d4f0; }
314 .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
304 .CodeMirror ::-moz-selection { background: #d7d4f0; }
315 .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
305
316
306 .cm-searching {
317 .cm-searching {
307 background: #ffa;
318 background: #ffa;
@@ -25,8 +25,12 b' CodeMirror.defineMode("clike", function('
25 multiLineStrings = parserConfig.multiLineStrings,
25 multiLineStrings = parserConfig.multiLineStrings,
26 indentStatements = parserConfig.indentStatements !== false,
26 indentStatements = parserConfig.indentStatements !== false,
27 indentSwitch = parserConfig.indentSwitch !== false,
27 indentSwitch = parserConfig.indentSwitch !== false,
28 namespaceSeparator = parserConfig.namespaceSeparator;
28 namespaceSeparator = parserConfig.namespaceSeparator,
29 var isOperatorChar = /[+\-*&%=<>!?|\/]/;
29 isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/,
30 numberStart = parserConfig.numberStart || /[\d\.]/,
31 number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
32 isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
33 endStatement = parserConfig.endStatement || /^[;:,]$/;
30
34
31 var curPunc, isDefKeyword;
35 var curPunc, isDefKeyword;
32
36
@@ -40,13 +44,14 b' CodeMirror.defineMode("clike", function('
40 state.tokenize = tokenString(ch);
44 state.tokenize = tokenString(ch);
41 return state.tokenize(stream, state);
45 return state.tokenize(stream, state);
42 }
46 }
43 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
47 if (isPunctuationChar.test(ch)) {
44 curPunc = ch;
48 curPunc = ch;
45 return null;
49 return null;
46 }
50 }
47 if (/\d/.test(ch)) {
51 if (numberStart.test(ch)) {
48 stream.eatWhile(/[\w\.]/);
52 stream.backUp(1)
49 return "number";
53 if (stream.match(number)) return "number"
54 stream.next()
50 }
55 }
51 if (ch == "/") {
56 if (ch == "/") {
52 if (stream.eat("*")) {
57 if (stream.eat("*")) {
@@ -67,17 +72,17 b' CodeMirror.defineMode("clike", function('
67 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
72 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
68
73
69 var cur = stream.current();
74 var cur = stream.current();
70 if (keywords.propertyIsEnumerable(cur)) {
75 if (contains(keywords, cur)) {
71 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
76 if (contains(blockKeywords, cur)) curPunc = "newstatement";
72 if (defKeywords.propertyIsEnumerable(cur)) isDefKeyword = true;
77 if (contains(defKeywords, cur)) isDefKeyword = true;
73 return "keyword";
78 return "keyword";
74 }
79 }
75 if (types.propertyIsEnumerable(cur)) return "variable-3";
80 if (contains(types, cur)) return "variable-3";
76 if (builtin.propertyIsEnumerable(cur)) {
81 if (contains(builtin, cur)) {
77 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
82 if (contains(blockKeywords, cur)) curPunc = "newstatement";
78 return "builtin";
83 return "builtin";
79 }
84 }
80 if (atoms.propertyIsEnumerable(cur)) return "atom";
85 if (contains(atoms, cur)) return "atom";
81 return "variable";
86 return "variable";
82 }
87 }
83
88
@@ -168,8 +173,7 b' CodeMirror.defineMode("clike", function('
168 if (style == "comment" || style == "meta") return style;
173 if (style == "comment" || style == "meta") return style;
169 if (ctx.align == null) ctx.align = true;
174 if (ctx.align == null) ctx.align = true;
170
175
171 if ((curPunc == ";" || curPunc == ":" || curPunc == ","))
176 if (endStatement.test(curPunc)) while (isStatement(state.context.type)) popContext(state);
172 while (isStatement(state.context.type)) popContext(state);
173 else if (curPunc == "{") pushContext(state, stream.column(), "}");
177 else if (curPunc == "{") pushContext(state, stream.column(), "}");
174 else if (curPunc == "[") pushContext(state, stream.column(), "]");
178 else if (curPunc == "[") pushContext(state, stream.column(), "]");
175 else if (curPunc == "(") pushContext(state, stream.column(), ")");
179 else if (curPunc == "(") pushContext(state, stream.column(), ")");
@@ -212,8 +216,16 b' CodeMirror.defineMode("clike", function('
212 if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
216 if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
213 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
217 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
214 if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev;
218 if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev;
219 if (hooks.indent) {
220 var hook = hooks.indent(state, ctx, textAfter);
221 if (typeof hook == "number") return hook
222 }
215 var closing = firstChar == ctx.type;
223 var closing = firstChar == ctx.type;
216 var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
224 var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
225 if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
226 while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
227 return ctx.indented
228 }
217 if (isStatement(ctx.type))
229 if (isStatement(ctx.type))
218 return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
230 return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
219 if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
231 if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
@@ -238,27 +250,30 b' CodeMirror.defineMode("clike", function('
238 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
250 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
239 return obj;
251 return obj;
240 }
252 }
253 function contains(words, word) {
254 if (typeof words === "function") {
255 return words(word);
256 } else {
257 return words.propertyIsEnumerable(word);
258 }
259 }
241 var cKeywords = "auto if break case register continue return default do sizeof " +
260 var cKeywords = "auto if break case register continue return default do sizeof " +
242 "static else struct switch extern typedef float union for " +
261 "static else struct switch extern typedef union for goto while enum const volatile";
243 "goto while enum const volatile";
244 var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
262 var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
245
263
246 function cppHook(stream, state) {
264 function cppHook(stream, state) {
247 if (!state.startOfLine) return false;
265 if (!state.startOfLine) return false
248 for (;;) {
266 for (var ch, next = null; ch = stream.peek();) {
249 if (stream.skipTo("\\")) {
267 if (ch == "\\" && stream.match(/^.$/)) {
250 stream.next();
268 next = cppHook
251 if (stream.eol()) {
269 break
252 state.tokenize = cppHook;
270 } else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
253 break;
271 break
254 }
255 } else {
256 stream.skipToEnd();
257 state.tokenize = null;
258 break;
259 }
272 }
273 stream.next()
260 }
274 }
261 return "meta";
275 state.tokenize = next
276 return "meta"
262 }
277 }
263
278
264 function pointerHook(_stream, state) {
279 function pointerHook(_stream, state) {
@@ -266,6 +281,11 b' CodeMirror.defineMode("clike", function('
266 return false;
281 return false;
267 }
282 }
268
283
284 function cpp14Literal(stream) {
285 stream.eatWhile(/[\w\.']/);
286 return "number";
287 }
288
269 function cpp11StringHook(stream, state) {
289 function cpp11StringHook(stream, state) {
270 stream.backUp(1);
290 stream.backUp(1);
271 // Raw strings.
291 // Raw strings.
@@ -373,6 +393,16 b' CodeMirror.defineMode("clike", function('
373 "U": cpp11StringHook,
393 "U": cpp11StringHook,
374 "L": cpp11StringHook,
394 "L": cpp11StringHook,
375 "R": cpp11StringHook,
395 "R": cpp11StringHook,
396 "0": cpp14Literal,
397 "1": cpp14Literal,
398 "2": cpp14Literal,
399 "3": cpp14Literal,
400 "4": cpp14Literal,
401 "5": cpp14Literal,
402 "6": cpp14Literal,
403 "7": cpp14Literal,
404 "8": cpp14Literal,
405 "9": cpp14Literal,
376 token: function(stream, state, style) {
406 token: function(stream, state, style) {
377 if (style == "variable" && stream.peek() == "(" &&
407 if (style == "variable" && stream.peek() == "(" &&
378 (state.prevToken == ";" || state.prevToken == null ||
408 (state.prevToken == ";" || state.prevToken == null ||
@@ -398,6 +428,7 b' CodeMirror.defineMode("clike", function('
398 defKeywords: words("class interface package enum"),
428 defKeywords: words("class interface package enum"),
399 typeFirstDefinitions: true,
429 typeFirstDefinitions: true,
400 atoms: words("true false null"),
430 atoms: words("true false null"),
431 endStatement: /^[;:]$/,
401 hooks: {
432 hooks: {
402 "@": function(stream) {
433 "@": function(stream) {
403 stream.eatWhile(/[\w\$_]/);
434 stream.eatWhile(/[\w\$_]/);
@@ -453,7 +484,7 b' CodeMirror.defineMode("clike", function('
453 keywords: words(
484 keywords: words(
454
485
455 /* scala */
486 /* scala */
456 "abstract case catch class def do else extends false final finally for forSome if " +
487 "abstract case catch class def do else extends final finally for forSome if " +
457 "implicit import lazy match new null object override package private protected return " +
488 "implicit import lazy match new null object override package private protected return " +
458 "sealed super this throw trait try type val var while with yield _ : = => <- <: " +
489 "sealed super this throw trait try type val var while with yield _ : = => <- <: " +
459 "<% >: # @ " +
490 "<% >: # @ " +
@@ -501,6 +532,59 b' CodeMirror.defineMode("clike", function('
501 modeProps: {closeBrackets: {triples: '"'}}
532 modeProps: {closeBrackets: {triples: '"'}}
502 });
533 });
503
534
535 function tokenKotlinString(tripleString){
536 return function (stream, state) {
537 var escaped = false, next, end = false;
538 while (!stream.eol()) {
539 if (!tripleString && !escaped && stream.match('"') ) {end = true; break;}
540 if (tripleString && stream.match('"""')) {end = true; break;}
541 next = stream.next();
542 if(!escaped && next == "$" && stream.match('{'))
543 stream.skipTo("}");
544 escaped = !escaped && next == "\\" && !tripleString;
545 }
546 if (end || !tripleString)
547 state.tokenize = null;
548 return "string";
549 }
550 }
551
552 def("text/x-kotlin", {
553 name: "clike",
554 keywords: words(
555 /*keywords*/
556 "package as typealias class interface this super val " +
557 "var fun for is in This throw return " +
558 "break continue object if else while do try when !in !is as? " +
559
560 /*soft keywords*/
561 "file import where by get set abstract enum open inner override private public internal " +
562 "protected catch finally out final vararg reified dynamic companion constructor init " +
563 "sealed field property receiver param sparam lateinit data inline noinline tailrec " +
564 "external annotation crossinline const operator infix"
565 ),
566 types: words(
567 /* package java.lang */
568 "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
569 "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
570 "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
571 "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
572 ),
573 intendSwitch: false,
574 indentStatements: false,
575 multiLineStrings: true,
576 blockKeywords: words("catch class do else finally for if where try while enum"),
577 defKeywords: words("class val var object package interface fun"),
578 atoms: words("true false null this"),
579 hooks: {
580 '"': function(stream, state) {
581 state.tokenize = tokenKotlinString(stream.match('""'));
582 return state.tokenize(stream, state);
583 }
584 },
585 modeProps: {closeBrackets: {triples: '"'}}
586 });
587
504 def(["x-shader/x-vertex", "x-shader/x-fragment"], {
588 def(["x-shader/x-vertex", "x-shader/x-fragment"], {
505 name: "clike",
589 name: "clike",
506 keywords: words("sampler1D sampler2D sampler3D samplerCube " +
590 keywords: words("sampler1D sampler2D sampler3D samplerCube " +
@@ -583,9 +667,106 b' CodeMirror.defineMode("clike", function('
583 stream.eatWhile(/[\w\$]/);
667 stream.eatWhile(/[\w\$]/);
584 return "keyword";
668 return "keyword";
585 },
669 },
586 "#": cppHook
670 "#": cppHook,
671 indent: function(_state, ctx, textAfter) {
672 if (ctx.type == "statement" && /^@\w/.test(textAfter)) return ctx.indented
673 }
587 },
674 },
588 modeProps: {fold: "brace"}
675 modeProps: {fold: "brace"}
589 });
676 });
590
677
678 def("text/x-squirrel", {
679 name: "clike",
680 keywords: words("base break clone continue const default delete enum extends function in class" +
681 " foreach local resume return this throw typeof yield constructor instanceof static"),
682 types: words(cTypes),
683 blockKeywords: words("case catch class else for foreach if switch try while"),
684 defKeywords: words("function local class"),
685 typeFirstDefinitions: true,
686 atoms: words("true false null"),
687 hooks: {"#": cppHook},
688 modeProps: {fold: ["brace", "include"]}
689 });
690
691 // Ceylon Strings need to deal with interpolation
692 var stringTokenizer = null;
693 function tokenCeylonString(type) {
694 return function(stream, state) {
695 var escaped = false, next, end = false;
696 while (!stream.eol()) {
697 if (!escaped && stream.match('"') &&
698 (type == "single" || stream.match('""'))) {
699 end = true;
700 break;
701 }
702 if (!escaped && stream.match('``')) {
703 stringTokenizer = tokenCeylonString(type);
704 end = true;
705 break;
706 }
707 next = stream.next();
708 escaped = type == "single" && !escaped && next == "\\";
709 }
710 if (end)
711 state.tokenize = null;
712 return "string";
713 }
714 }
715
716 def("text/x-ceylon", {
717 name: "clike",
718 keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" +
719 " exists extends finally for function given if import in interface is let module new" +
720 " nonempty object of out outer package return satisfies super switch then this throw" +
721 " try value void while"),
722 types: function(word) {
723 // In Ceylon all identifiers that start with an uppercase are types
724 var first = word.charAt(0);
725 return (first === first.toUpperCase() && first !== first.toLowerCase());
726 },
727 blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"),
728 defKeywords: words("class dynamic function interface module object package value"),
729 builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" +
730 " native optional sealed see serializable shared suppressWarnings tagged throws variable"),
731 isPunctuationChar: /[\[\]{}\(\),;\:\.`]/,
732 isOperatorChar: /[+\-*&%=<>!?|^~:\/]/,
733 numberStart: /[\d#$]/,
734 number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,
735 multiLineStrings: true,
736 typeFirstDefinitions: true,
737 atoms: words("true false null larger smaller equal empty finished"),
738 indentSwitch: false,
739 styleDefs: false,
740 hooks: {
741 "@": function(stream) {
742 stream.eatWhile(/[\w\$_]/);
743 return "meta";
744 },
745 '"': function(stream, state) {
746 state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single");
747 return state.tokenize(stream, state);
748 },
749 '`': function(stream, state) {
750 if (!stringTokenizer || !stream.match('`')) return false;
751 state.tokenize = stringTokenizer;
752 stringTokenizer = null;
753 return state.tokenize(stream, state);
754 },
755 "'": function(stream) {
756 stream.eatWhile(/[\w\$_\xa1-\uffff]/);
757 return "atom";
758 },
759 token: function(_stream, state, style) {
760 if ((style == "variable" || style == "variable-3") &&
761 state.prevToken == ".") {
762 return "variable-2";
763 }
764 }
765 },
766 modeProps: {
767 fold: ["brace", "import"],
768 closeBrackets: {triples: '"'}
769 }
770 });
771
591 });
772 });
@@ -59,7 +59,8 b' CodeMirror.defineMode("clojure", functio'
59 sign: /[+-]/,
59 sign: /[+-]/,
60 exponent: /e/i,
60 exponent: /e/i,
61 keyword_char: /[^\s\(\[\;\)\]]/,
61 keyword_char: /[^\s\(\[\;\)\]]/,
62 symbol: /[\w*+!\-\._?:<>\/\xa1-\uffff]/
62 symbol: /[\w*+!\-\._?:<>\/\xa1-\uffff]/,
63 block_indent: /^(?:def|with)[^\/]+$|\/(?:def|with)/
63 };
64 };
64
65
65 function stateStack(indent, type, prev) { // represents a state stack object
66 function stateStack(indent, type, prev) { // represents a state stack object
@@ -96,6 +97,9 b' CodeMirror.defineMode("clojure", functio'
96 if ( '.' == stream.peek() ) {
97 if ( '.' == stream.peek() ) {
97 stream.eat('.');
98 stream.eat('.');
98 stream.eatWhile(tests.digit);
99 stream.eatWhile(tests.digit);
100 } else if ('/' == stream.peek() ) {
101 stream.eat('/');
102 stream.eatWhile(tests.digit);
99 }
103 }
100
104
101 if ( stream.eat(tests.exponent) ) {
105 if ( stream.eat(tests.exponent) ) {
@@ -139,7 +143,7 b' CodeMirror.defineMode("clojure", functio'
139 }
143 }
140
144
141 // skip spaces
145 // skip spaces
142 if (stream.eatSpace()) {
146 if (state.mode != "string" && stream.eatSpace()) {
143 return null;
147 return null;
144 }
148 }
145 var returnType = null;
149 var returnType = null;
@@ -187,7 +191,7 b' CodeMirror.defineMode("clojure", functio'
187 }
191 }
188
192
189 if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
193 if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
190 /^(?:def|with)/.test(keyWord))) { // indent-word
194 tests.block_indent.test(keyWord))) { // indent-word
191 pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
195 pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
192 } else { // non-indent word
196 } else { // non-indent word
193 // we continue eating the spaces
197 // we continue eating the spaces
@@ -240,5 +244,6 b' CodeMirror.defineMode("clojure", functio'
240 });
244 });
241
245
242 CodeMirror.defineMIME("text/x-clojure", "clojure");
246 CodeMirror.defineMIME("text/x-clojure", "clojure");
247 CodeMirror.defineMIME("text/x-clojurescript", "clojure");
243
248
244 });
249 });
@@ -25,7 +25,7 b' CodeMirror.defineMode("coffeescript", fu'
25 var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
25 var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
26 var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
26 var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
27 var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
27 var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
28 var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
28 var atProp = /^@[_A-Za-z$][_A-Za-z$0-9]*/;
29
29
30 var wordOperators = wordRegexp(["and", "or", "not",
30 var wordOperators = wordRegexp(["and", "or", "not",
31 "is", "isnt", "in",
31 "is", "isnt", "in",
@@ -145,6 +145,8 b' CodeMirror.defineMode("coffeescript", fu'
145 }
145 }
146 }
146 }
147
147
148
149
148 // Handle operators and delimiters
150 // Handle operators and delimiters
149 if (stream.match(operators) || stream.match(wordOperators)) {
151 if (stream.match(operators) || stream.match(wordOperators)) {
150 return "operator";
152 return "operator";
@@ -157,6 +159,10 b' CodeMirror.defineMode("coffeescript", fu'
157 return "atom";
159 return "atom";
158 }
160 }
159
161
162 if (stream.match(atProp) || state.prop && stream.match(identifiers)) {
163 return "property";
164 }
165
160 if (stream.match(keywords)) {
166 if (stream.match(keywords)) {
161 return "keyword";
167 return "keyword";
162 }
168 }
@@ -165,10 +171,6 b' CodeMirror.defineMode("coffeescript", fu'
165 return "variable";
171 return "variable";
166 }
172 }
167
173
168 if (stream.match(properties)) {
169 return "property";
170 }
171
172 // Handle non-detected items
174 // Handle non-detected items
173 stream.next();
175 stream.next();
174 return ERRORCLASS;
176 return ERRORCLASS;
@@ -265,24 +267,11 b' CodeMirror.defineMode("coffeescript", fu'
265 var style = state.tokenize(stream, state);
267 var style = state.tokenize(stream, state);
266 var current = stream.current();
268 var current = stream.current();
267
269
268 // Handle "." connected identifiers
269 if (current === ".") {
270 style = state.tokenize(stream, state);
271 current = stream.current();
272 if (/^\.[\w$]+$/.test(current)) {
273 return "variable";
274 } else {
275 return ERRORCLASS;
276 }
277 }
278
279 // Handle scope changes.
270 // Handle scope changes.
280 if (current === "return") {
271 if (current === "return") {
281 state.dedent = true;
272 state.dedent = true;
282 }
273 }
283 if (((current === "->" || current === "=>") &&
274 if (((current === "->" || current === "=>") && stream.eol())
284 !state.lambda &&
285 !stream.peek())
286 || style === "indent") {
275 || style === "indent") {
287 indent(stream, state);
276 indent(stream, state);
288 }
277 }
@@ -324,8 +313,7 b' CodeMirror.defineMode("coffeescript", fu'
324 return {
313 return {
325 tokenize: tokenBase,
314 tokenize: tokenBase,
326 scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
315 scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
327 lastToken: null,
316 prop: false,
328 lambda: false,
329 dedent: 0
317 dedent: 0
330 };
318 };
331 },
319 },
@@ -335,12 +323,9 b' CodeMirror.defineMode("coffeescript", fu'
335 if (fillAlign && stream.sol()) fillAlign.align = false;
323 if (fillAlign && stream.sol()) fillAlign.align = false;
336
324
337 var style = tokenLexer(stream, state);
325 var style = tokenLexer(stream, state);
338 if (fillAlign && style && style != "comment") fillAlign.align = true;
326 if (style && style != "comment") {
339
327 if (fillAlign) fillAlign.align = true;
340 state.lastToken = {style:style, content: stream.current()};
328 state.prop = style == "punctuation" && stream.current() == "."
341
342 if (stream.eol() && stream.lambda) {
343 state.lambda = false;
344 }
329 }
345
330
346 return style;
331 return style;
@@ -365,5 +350,6 b' CodeMirror.defineMode("coffeescript", fu'
365 });
350 });
366
351
367 CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
352 CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
353 CodeMirror.defineMIME("text/coffeescript", "coffeescript");
368
354
369 });
355 });
@@ -12,6 +12,7 b''
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("css", function(config, parserConfig) {
14 CodeMirror.defineMode("css", function(config, parserConfig) {
15 var inline = parserConfig.inline
15 if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
16 if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
16
17
17 var indentUnit = config.indentUnit,
18 var indentUnit = config.indentUnit,
@@ -19,13 +20,15 b' CodeMirror.defineMode("css", function(co'
19 documentTypes = parserConfig.documentTypes || {},
20 documentTypes = parserConfig.documentTypes || {},
20 mediaTypes = parserConfig.mediaTypes || {},
21 mediaTypes = parserConfig.mediaTypes || {},
21 mediaFeatures = parserConfig.mediaFeatures || {},
22 mediaFeatures = parserConfig.mediaFeatures || {},
23 mediaValueKeywords = parserConfig.mediaValueKeywords || {},
22 propertyKeywords = parserConfig.propertyKeywords || {},
24 propertyKeywords = parserConfig.propertyKeywords || {},
23 nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
25 nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
24 fontProperties = parserConfig.fontProperties || {},
26 fontProperties = parserConfig.fontProperties || {},
25 counterDescriptors = parserConfig.counterDescriptors || {},
27 counterDescriptors = parserConfig.counterDescriptors || {},
26 colorKeywords = parserConfig.colorKeywords || {},
28 colorKeywords = parserConfig.colorKeywords || {},
27 valueKeywords = parserConfig.valueKeywords || {},
29 valueKeywords = parserConfig.valueKeywords || {},
28 allowNested = parserConfig.allowNested;
30 allowNested = parserConfig.allowNested,
31 supportsAtComponent = parserConfig.supportsAtComponent === true;
29
32
30 var type, override;
33 var type, override;
31 function ret(style, tp) { type = tp; return style; }
34 function ret(style, tp) { type = tp; return style; }
@@ -119,13 +122,14 b' CodeMirror.defineMode("css", function(co'
119 this.prev = prev;
122 this.prev = prev;
120 }
123 }
121
124
122 function pushContext(state, stream, type) {
125 function pushContext(state, stream, type, indent) {
123 state.context = new Context(type, stream.indentation() + indentUnit, state.context);
126 state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
124 return type;
127 return type;
125 }
128 }
126
129
127 function popContext(state) {
130 function popContext(state) {
128 state.context = state.context.prev;
131 if (state.context.prev)
132 state.context = state.context.prev;
129 return state.context.type;
133 return state.context.type;
130 }
134 }
131
135
@@ -157,9 +161,13 b' CodeMirror.defineMode("css", function(co'
157 return pushContext(state, stream, "block");
161 return pushContext(state, stream, "block");
158 } else if (type == "}" && state.context.prev) {
162 } else if (type == "}" && state.context.prev) {
159 return popContext(state);
163 return popContext(state);
160 } else if (/@(media|supports|(-moz-)?document)/.test(type)) {
164 } else if (supportsAtComponent && /@component/.test(type)) {
165 return pushContext(state, stream, "atComponentBlock");
166 } else if (/^@(-moz-)?document$/.test(type)) {
167 return pushContext(state, stream, "documentTypes");
168 } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
161 return pushContext(state, stream, "atBlock");
169 return pushContext(state, stream, "atBlock");
162 } else if (/@(font-face|counter-style)/.test(type)) {
170 } else if (/^@(font-face|counter-style)/.test(type)) {
163 state.stateArg = type;
171 state.stateArg = type;
164 return "restricted_atBlock_before";
172 return "restricted_atBlock_before";
165 } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
173 } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
@@ -219,7 +227,7 b' CodeMirror.defineMode("css", function(co'
219 if (type == "}" || type == "{") return popAndPass(type, stream, state);
227 if (type == "}" || type == "{") return popAndPass(type, stream, state);
220 if (type == "(") return pushContext(state, stream, "parens");
228 if (type == "(") return pushContext(state, stream, "parens");
221
229
222 if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
230 if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
223 override += " error";
231 override += " error";
224 } else if (type == "word") {
232 } else if (type == "word") {
225 wordAsValue(stream);
233 wordAsValue(stream);
@@ -252,33 +260,56 b' CodeMirror.defineMode("css", function(co'
252 return pass(type, stream, state);
260 return pass(type, stream, state);
253 };
261 };
254
262
263 states.documentTypes = function(type, stream, state) {
264 if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
265 override = "tag";
266 return state.context.type;
267 } else {
268 return states.atBlock(type, stream, state);
269 }
270 };
271
255 states.atBlock = function(type, stream, state) {
272 states.atBlock = function(type, stream, state) {
256 if (type == "(") return pushContext(state, stream, "atBlock_parens");
273 if (type == "(") return pushContext(state, stream, "atBlock_parens");
257 if (type == "}") return popAndPass(type, stream, state);
274 if (type == "}" || type == ";") return popAndPass(type, stream, state);
258 if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
275 if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
259
276
277 if (type == "interpolation") return pushContext(state, stream, "interpolation");
278
260 if (type == "word") {
279 if (type == "word") {
261 var word = stream.current().toLowerCase();
280 var word = stream.current().toLowerCase();
262 if (word == "only" || word == "not" || word == "and" || word == "or")
281 if (word == "only" || word == "not" || word == "and" || word == "or")
263 override = "keyword";
282 override = "keyword";
264 else if (documentTypes.hasOwnProperty(word))
265 override = "tag";
266 else if (mediaTypes.hasOwnProperty(word))
283 else if (mediaTypes.hasOwnProperty(word))
267 override = "attribute";
284 override = "attribute";
268 else if (mediaFeatures.hasOwnProperty(word))
285 else if (mediaFeatures.hasOwnProperty(word))
269 override = "property";
286 override = "property";
287 else if (mediaValueKeywords.hasOwnProperty(word))
288 override = "keyword";
270 else if (propertyKeywords.hasOwnProperty(word))
289 else if (propertyKeywords.hasOwnProperty(word))
271 override = "property";
290 override = "property";
272 else if (nonStandardPropertyKeywords.hasOwnProperty(word))
291 else if (nonStandardPropertyKeywords.hasOwnProperty(word))
273 override = "string-2";
292 override = "string-2";
274 else if (valueKeywords.hasOwnProperty(word))
293 else if (valueKeywords.hasOwnProperty(word))
275 override = "atom";
294 override = "atom";
295 else if (colorKeywords.hasOwnProperty(word))
296 override = "keyword";
276 else
297 else
277 override = "error";
298 override = "error";
278 }
299 }
279 return state.context.type;
300 return state.context.type;
280 };
301 };
281
302
303 states.atComponentBlock = function(type, stream, state) {
304 if (type == "}")
305 return popAndPass(type, stream, state);
306 if (type == "{")
307 return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
308 if (type == "word")
309 override = "error";
310 return state.context.type;
311 };
312
282 states.atBlock_parens = function(type, stream, state) {
313 states.atBlock_parens = function(type, stream, state) {
283 if (type == ")") return popContext(state);
314 if (type == ")") return popContext(state);
284 if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
315 if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
@@ -336,9 +367,9 b' CodeMirror.defineMode("css", function(co'
336 return {
367 return {
337 startState: function(base) {
368 startState: function(base) {
338 return {tokenize: null,
369 return {tokenize: null,
339 state: "top",
370 state: inline ? "block" : "top",
340 stateArg: null,
371 stateArg: null,
341 context: new Context("top", base || 0, null)};
372 context: new Context(inline ? "block" : "top", base || 0, null)};
342 },
373 },
343
374
344 token: function(stream, state) {
375 token: function(stream, state) {
@@ -357,12 +388,18 b' CodeMirror.defineMode("css", function(co'
357 var cx = state.context, ch = textAfter && textAfter.charAt(0);
388 var cx = state.context, ch = textAfter && textAfter.charAt(0);
358 var indent = cx.indent;
389 var indent = cx.indent;
359 if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
390 if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
360 if (cx.prev &&
391 if (cx.prev) {
361 (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "restricted_atBlock") ||
392 if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
362 ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
393 cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
363 ch == "{" && (cx.type == "at" || cx.type == "atBlock"))) {
394 // Resume indentation from parent context.
364 indent = cx.indent - indentUnit;
395 cx = cx.prev;
365 cx = cx.prev;
396 indent = cx.indent;
397 } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
398 ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
399 // Dedent relative to current context.
400 indent = Math.max(0, cx.indent - indentUnit);
401 cx = cx.prev;
402 }
366 }
403 }
367 return indent;
404 return indent;
368 },
405 },
@@ -399,17 +436,24 b' CodeMirror.defineMode("css", function(co'
399 "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
436 "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
400 "max-color", "color-index", "min-color-index", "max-color-index",
437 "max-color", "color-index", "min-color-index", "max-color-index",
401 "monochrome", "min-monochrome", "max-monochrome", "resolution",
438 "monochrome", "min-monochrome", "max-monochrome", "resolution",
402 "min-resolution", "max-resolution", "scan", "grid"
439 "min-resolution", "max-resolution", "scan", "grid", "orientation",
440 "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
441 "pointer", "any-pointer", "hover", "any-hover"
403 ], mediaFeatures = keySet(mediaFeatures_);
442 ], mediaFeatures = keySet(mediaFeatures_);
404
443
444 var mediaValueKeywords_ = [
445 "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
446 "interlace", "progressive"
447 ], mediaValueKeywords = keySet(mediaValueKeywords_);
448
405 var propertyKeywords_ = [
449 var propertyKeywords_ = [
406 "align-content", "align-items", "align-self", "alignment-adjust",
450 "align-content", "align-items", "align-self", "alignment-adjust",
407 "alignment-baseline", "anchor-point", "animation", "animation-delay",
451 "alignment-baseline", "anchor-point", "animation", "animation-delay",
408 "animation-direction", "animation-duration", "animation-fill-mode",
452 "animation-direction", "animation-duration", "animation-fill-mode",
409 "animation-iteration-count", "animation-name", "animation-play-state",
453 "animation-iteration-count", "animation-name", "animation-play-state",
410 "animation-timing-function", "appearance", "azimuth", "backface-visibility",
454 "animation-timing-function", "appearance", "azimuth", "backface-visibility",
411 "background", "background-attachment", "background-clip", "background-color",
455 "background", "background-attachment", "background-blend-mode", "background-clip",
412 "background-image", "background-origin", "background-position",
456 "background-color", "background-image", "background-origin", "background-position",
413 "background-repeat", "background-size", "baseline-shift", "binding",
457 "background-repeat", "background-size", "baseline-shift", "binding",
414 "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
458 "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
415 "bookmark-target", "border", "border-bottom", "border-bottom-color",
459 "bookmark-target", "border", "border-bottom", "border-bottom-color",
@@ -553,11 +597,12 b' CodeMirror.defineMode("css", function(co'
553 "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
597 "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
554 "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
598 "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
555 "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
599 "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
556 "col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
600 "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
601 "compact", "condensed", "contain", "content",
557 "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
602 "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
558 "cross", "crosshair", "currentcolor", "cursive", "cyclic", "dashed", "decimal",
603 "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
559 "decimal-leading-zero", "default", "default-button", "destination-atop",
604 "decimal-leading-zero", "default", "default-button", "destination-atop",
560 "destination-in", "destination-out", "destination-over", "devanagari",
605 "destination-in", "destination-out", "destination-over", "devanagari", "difference",
561 "disc", "discard", "disclosure-closed", "disclosure-open", "document",
606 "disc", "discard", "disclosure-closed", "disclosure-open", "document",
562 "dot-dash", "dot-dot-dash",
607 "dot-dash", "dot-dot-dash",
563 "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
608 "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
@@ -568,23 +613,23 b' CodeMirror.defineMode("css", function(co'
568 "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
613 "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
569 "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
614 "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
570 "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
615 "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
571 "ethiopic-numeric", "ew-resize", "expanded", "extends", "extra-condensed",
616 "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
572 "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "footnotes",
617 "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
573 "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
618 "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
574 "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
619 "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
575 "help", "hidden", "hide", "higher", "highlight", "highlighttext",
620 "help", "hidden", "hide", "higher", "highlight", "highlighttext",
576 "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
621 "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
577 "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
622 "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
578 "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
623 "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
579 "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
624 "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
580 "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
625 "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
581 "katakana", "katakana-iroha", "keep-all", "khmer",
626 "katakana", "katakana-iroha", "keep-all", "khmer",
582 "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
627 "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
583 "landscape", "lao", "large", "larger", "left", "level", "lighter",
628 "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
584 "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
629 "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
585 "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
630 "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
586 "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
631 "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
587 "lower-roman", "lowercase", "ltr", "malayalam", "match", "matrix", "matrix3d",
632 "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
588 "media-controls-background", "media-current-time-display",
633 "media-controls-background", "media-current-time-display",
589 "media-fullscreen-button", "media-mute-button", "media-play-button",
634 "media-fullscreen-button", "media-mute-button", "media-play-button",
590 "media-return-to-realtime-button", "media-rewind-button",
635 "media-return-to-realtime-button", "media-rewind-button",
@@ -593,7 +638,7 b' CodeMirror.defineMode("css", function(co'
593 "media-volume-slider-container", "media-volume-sliderthumb", "medium",
638 "media-volume-slider-container", "media-volume-sliderthumb", "medium",
594 "menu", "menulist", "menulist-button", "menulist-text",
639 "menu", "menulist", "menulist-button", "menulist-text",
595 "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
640 "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
596 "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
641 "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
597 "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
642 "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
598 "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
643 "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
599 "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
644 "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
@@ -606,8 +651,8 b' CodeMirror.defineMode("css", function(co'
606 "relative", "repeat", "repeating-linear-gradient",
651 "relative", "repeat", "repeating-linear-gradient",
607 "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
652 "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
608 "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
653 "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
609 "rotateZ", "round", "row-resize", "rtl", "run-in", "running",
654 "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
610 "s-resize", "sans-serif", "scale", "scale3d", "scaleX", "scaleY", "scaleZ",
655 "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
611 "scroll", "scrollbar", "se-resize", "searchfield",
656 "scroll", "scrollbar", "se-resize", "searchfield",
612 "searchfield-cancel-button", "searchfield-decoration",
657 "searchfield-cancel-button", "searchfield-decoration",
613 "searchfield-results-button", "searchfield-results-decoration",
658 "searchfield-results-button", "searchfield-results-decoration",
@@ -615,8 +660,8 b' CodeMirror.defineMode("css", function(co'
615 "simp-chinese-formal", "simp-chinese-informal", "single",
660 "simp-chinese-formal", "simp-chinese-informal", "single",
616 "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
661 "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
617 "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
662 "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
618 "small", "small-caps", "small-caption", "smaller", "solid", "somali",
663 "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
619 "source-atop", "source-in", "source-out", "source-over", "space", "spell-out", "square",
664 "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
620 "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
665 "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
621 "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
666 "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
622 "table-caption", "table-cell", "table-column", "table-column-group",
667 "table-caption", "table-cell", "table-column", "table-column-group",
@@ -633,12 +678,13 b' CodeMirror.defineMode("css", function(co'
633 "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
678 "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
634 "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
679 "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
635 "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
680 "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
636 "window", "windowframe", "windowtext", "words", "x-large", "x-small", "xor",
681 "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
637 "xx-large", "xx-small"
682 "xx-large", "xx-small"
638 ], valueKeywords = keySet(valueKeywords_);
683 ], valueKeywords = keySet(valueKeywords_);
639
684
640 var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(propertyKeywords_)
685 var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
641 .concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
686 .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
687 .concat(valueKeywords_);
642 CodeMirror.registerHelper("hintWords", "css", allWords);
688 CodeMirror.registerHelper("hintWords", "css", allWords);
643
689
644 function tokenCComment(stream, state) {
690 function tokenCComment(stream, state) {
@@ -657,6 +703,7 b' CodeMirror.defineMode("css", function(co'
657 documentTypes: documentTypes,
703 documentTypes: documentTypes,
658 mediaTypes: mediaTypes,
704 mediaTypes: mediaTypes,
659 mediaFeatures: mediaFeatures,
705 mediaFeatures: mediaFeatures,
706 mediaValueKeywords: mediaValueKeywords,
660 propertyKeywords: propertyKeywords,
707 propertyKeywords: propertyKeywords,
661 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
708 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
662 fontProperties: fontProperties,
709 fontProperties: fontProperties,
@@ -676,6 +723,7 b' CodeMirror.defineMode("css", function(co'
676 CodeMirror.defineMIME("text/x-scss", {
723 CodeMirror.defineMIME("text/x-scss", {
677 mediaTypes: mediaTypes,
724 mediaTypes: mediaTypes,
678 mediaFeatures: mediaFeatures,
725 mediaFeatures: mediaFeatures,
726 mediaValueKeywords: mediaValueKeywords,
679 propertyKeywords: propertyKeywords,
727 propertyKeywords: propertyKeywords,
680 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
728 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
681 colorKeywords: colorKeywords,
729 colorKeywords: colorKeywords,
@@ -717,6 +765,7 b' CodeMirror.defineMode("css", function(co'
717 CodeMirror.defineMIME("text/x-less", {
765 CodeMirror.defineMIME("text/x-less", {
718 mediaTypes: mediaTypes,
766 mediaTypes: mediaTypes,
719 mediaFeatures: mediaFeatures,
767 mediaFeatures: mediaFeatures,
768 mediaValueKeywords: mediaValueKeywords,
720 propertyKeywords: propertyKeywords,
769 propertyKeywords: propertyKeywords,
721 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
770 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
722 colorKeywords: colorKeywords,
771 colorKeywords: colorKeywords,
@@ -751,4 +800,26 b' CodeMirror.defineMode("css", function(co'
751 helperType: "less"
800 helperType: "less"
752 });
801 });
753
802
803 CodeMirror.defineMIME("text/x-gss", {
804 documentTypes: documentTypes,
805 mediaTypes: mediaTypes,
806 mediaFeatures: mediaFeatures,
807 propertyKeywords: propertyKeywords,
808 nonStandardPropertyKeywords: nonStandardPropertyKeywords,
809 fontProperties: fontProperties,
810 counterDescriptors: counterDescriptors,
811 colorKeywords: colorKeywords,
812 valueKeywords: valueKeywords,
813 supportsAtComponent: true,
814 tokenHooks: {
815 "/": function(stream, state) {
816 if (!stream.eat("*")) return false;
817 state.tokenize = tokenCComment;
818 return tokenCComment(stream, state);
819 }
820 },
821 name: "css",
822 helperType: "gss"
823 });
824
754 });
825 });
@@ -60,9 +60,9 b''
60 };
60 };
61 var indentUnit = config.indentUnit;
61 var indentUnit = config.indentUnit;
62 var curPunc;
62 var curPunc;
63 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"]);
63 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"]);
64 var preds = wordRegexp(["all", "and", "any", "has", "in", "none", "not", "or", "single", "xor"]);
64 var preds = wordRegexp(["all", "and", "any", "contains", "exists", "has", "in", "none", "not", "or", "single", "xor"]);
65 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", "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"]);
65 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"]);
66 var operatorChars = /[*+\-<>=&|~%^]/;
66 var operatorChars = /[*+\-<>=&|~%^]/;
67
67
68 return {
68 return {
@@ -15,7 +15,7 b''
15 "implements get native operator set typedef with enum throw rethrow " +
15 "implements get native operator set typedef with enum throw rethrow " +
16 "assert break case continue default in return new deferred async await " +
16 "assert break case continue default in return new deferred async await " +
17 "try catch finally do else for if switch while import library export " +
17 "try catch finally do else for if switch while import library export " +
18 "part of show hide is").split(" ");
18 "part of show hide is as").split(" ");
19 var blockKeywords = "try catch finally do else for if switch while".split(" ");
19 var blockKeywords = "try catch finally do else for if switch while".split(" ");
20 var atoms = "true false null".split(" ");
20 var atoms = "true false null".split(" ");
21 var builtins = "void bool num int double dynamic var String".split(" ");
21 var builtins = "void bool num int double dynamic var String".split(" ");
@@ -26,21 +26,101 b''
26 return obj;
26 return obj;
27 }
27 }
28
28
29 function pushInterpolationStack(state) {
30 (state.interpolationStack || (state.interpolationStack = [])).push(state.tokenize);
31 }
32
33 function popInterpolationStack(state) {
34 return (state.interpolationStack || (state.interpolationStack = [])).pop();
35 }
36
37 function sizeInterpolationStack(state) {
38 return state.interpolationStack ? state.interpolationStack.length : 0;
39 }
40
29 CodeMirror.defineMIME("application/dart", {
41 CodeMirror.defineMIME("application/dart", {
30 name: "clike",
42 name: "clike",
31 keywords: set(keywords),
43 keywords: set(keywords),
32 multiLineStrings: true,
33 blockKeywords: set(blockKeywords),
44 blockKeywords: set(blockKeywords),
34 builtin: set(builtins),
45 builtin: set(builtins),
35 atoms: set(atoms),
46 atoms: set(atoms),
36 hooks: {
47 hooks: {
37 "@": function(stream) {
48 "@": function(stream) {
38 stream.eatWhile(/[\w\$_]/);
49 stream.eatWhile(/[\w\$_\.]/);
39 return "meta";
50 return "meta";
51 },
52
53 // custom string handling to deal with triple-quoted strings and string interpolation
54 "'": function(stream, state) {
55 return tokenString("'", stream, state, false);
56 },
57 "\"": function(stream, state) {
58 return tokenString("\"", stream, state, false);
59 },
60 "r": function(stream, state) {
61 var peek = stream.peek();
62 if (peek == "'" || peek == "\"") {
63 return tokenString(stream.next(), stream, state, true);
64 }
65 return false;
66 },
67
68 "}": function(_stream, state) {
69 // "}" is end of interpolation, if interpolation stack is non-empty
70 if (sizeInterpolationStack(state) > 0) {
71 state.tokenize = popInterpolationStack(state);
72 return null;
73 }
74 return false;
40 }
75 }
41 }
76 }
42 });
77 });
43
78
79 function tokenString(quote, stream, state, raw) {
80 var tripleQuoted = false;
81 if (stream.eat(quote)) {
82 if (stream.eat(quote)) tripleQuoted = true;
83 else return "string"; //empty string
84 }
85 function tokenStringHelper(stream, state) {
86 var escaped = false;
87 while (!stream.eol()) {
88 if (!raw && !escaped && stream.peek() == "$") {
89 pushInterpolationStack(state);
90 state.tokenize = tokenInterpolation;
91 return "string";
92 }
93 var next = stream.next();
94 if (next == quote && !escaped && (!tripleQuoted || stream.match(quote + quote))) {
95 state.tokenize = null;
96 break;
97 }
98 escaped = !raw && !escaped && next == "\\";
99 }
100 return "string";
101 }
102 state.tokenize = tokenStringHelper;
103 return tokenStringHelper(stream, state);
104 }
105
106 function tokenInterpolation(stream, state) {
107 stream.eat("$");
108 if (stream.eat("{")) {
109 // let clike handle the content of ${...},
110 // we take over again when "}" appears (see hooks).
111 state.tokenize = null;
112 } else {
113 state.tokenize = tokenInterpolationIdentifier;
114 }
115 return null;
116 }
117
118 function tokenInterpolationIdentifier(stream, state) {
119 stream.eatWhile(/[\w_]/);
120 state.tokenize = popInterpolationStack(state);
121 return "variable";
122 }
123
44 CodeMirror.registerHelper("hintWords", "application/dart", keywords.concat(atoms).concat(builtins));
124 CodeMirror.registerHelper("hintWords", "application/dart", keywords.concat(atoms).concat(builtins));
45
125
46 // This is needed to make loading through meta.js work.
126 // This is needed to make loading through meta.js work.
@@ -14,14 +14,14 b''
14 "use strict";
14 "use strict";
15
15
16 CodeMirror.defineMode("django:inner", function() {
16 CodeMirror.defineMode("django:inner", function() {
17 var keywords = ["block", "endblock", "for", "endfor", "true", "false",
17 var keywords = ["block", "endblock", "for", "endfor", "true", "false", "filter", "endfilter",
18 "loop", "none", "self", "super", "if", "endif", "as",
18 "loop", "none", "self", "super", "if", "elif", "endif", "as", "else", "import",
19 "else", "import", "with", "endwith", "without", "context", "ifequal", "endifequal",
19 "with", "endwith", "without", "context", "ifequal", "endifequal", "ifnotequal",
20 "ifnotequal", "endifnotequal", "extends", "include", "load", "comment",
20 "endifnotequal", "extends", "include", "load", "comment", "endcomment",
21 "endcomment", "empty", "url", "static", "trans", "blocktrans", "now", "regroup",
21 "empty", "url", "static", "trans", "blocktrans", "endblocktrans", "now",
22 "lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle", "csrf_token",
22 "regroup", "lorem", "ifchanged", "endifchanged", "firstof", "debug", "cycle",
23 "autoescape", "endautoescape", "spaceless", "ssi", "templatetag",
23 "csrf_token", "autoescape", "endautoescape", "spaceless", "endspaceless",
24 "verbatim", "endverbatim", "widthratio"],
24 "ssi", "templatetag", "verbatim", "endverbatim", "widthratio"],
25 filters = ["add", "addslashes", "capfirst", "center", "cut", "date",
25 filters = ["add", "addslashes", "capfirst", "center", "cut", "date",
26 "default", "default_if_none", "dictsort",
26 "default", "default_if_none", "dictsort",
27 "dictsortreversed", "divisibleby", "escape", "escapejs",
27 "dictsortreversed", "divisibleby", "escape", "escapejs",
@@ -35,11 +35,13 b''
35 "truncatechars_html", "truncatewords", "truncatewords_html",
35 "truncatechars_html", "truncatewords", "truncatewords_html",
36 "unordered_list", "upper", "urlencode", "urlize",
36 "unordered_list", "upper", "urlencode", "urlize",
37 "urlizetrunc", "wordcount", "wordwrap", "yesno"],
37 "urlizetrunc", "wordcount", "wordwrap", "yesno"],
38 operators = ["==", "!=", "<", ">", "<=", ">=", "in", "not", "or", "and"];
38 operators = ["==", "!=", "<", ">", "<=", ">="],
39 wordOperators = ["in", "not", "or", "and"];
39
40
40 keywords = new RegExp("^\\b(" + keywords.join("|") + ")\\b");
41 keywords = new RegExp("^\\b(" + keywords.join("|") + ")\\b");
41 filters = new RegExp("^\\b(" + filters.join("|") + ")\\b");
42 filters = new RegExp("^\\b(" + filters.join("|") + ")\\b");
42 operators = new RegExp("^\\b(" + operators.join("|") + ")\\b");
43 operators = new RegExp("^\\b(" + operators.join("|") + ")\\b");
44 wordOperators = new RegExp("^\\b(" + wordOperators.join("|") + ")\\b");
43
45
44 // We have to return "null" instead of null, in order to avoid string
46 // We have to return "null" instead of null, in order to avoid string
45 // styling as the default, when using Django templates inside HTML
47 // styling as the default, when using Django templates inside HTML
@@ -59,7 +61,7 b''
59
61
60 // Ignore completely any stream series that do not match the
62 // Ignore completely any stream series that do not match the
61 // Django template opening tags.
63 // Django template opening tags.
62 while (stream.next() != null && !stream.match("{{", false) && !stream.match("{%", false)) {}
64 while (stream.next() != null && !stream.match(/\{[{%#]/, false)) {}
63 return null;
65 return null;
64 }
66 }
65
67
@@ -270,6 +272,11 b''
270 return "operator";
272 return "operator";
271 }
273 }
272
274
275 // Attempt to match a word operator
276 if (stream.match(wordOperators)) {
277 return "keyword";
278 }
279
273 // Attempt to match a keyword
280 // Attempt to match a keyword
274 var keywordMatch = stream.match(keywords);
281 var keywordMatch = stream.match(keywords);
275 if (keywordMatch) {
282 if (keywordMatch) {
@@ -310,9 +317,8 b''
310
317
311 // Mark everything as comment inside the tag and the tag itself.
318 // Mark everything as comment inside the tag and the tag itself.
312 function inComment (stream, state) {
319 function inComment (stream, state) {
313 if (stream.match("#}")) {
320 if (stream.match(/^.*?#\}/)) state.tokenize = tokenBase
314 state.tokenize = tokenBase;
321 else stream.skipToEnd()
315 }
316 return "comment";
322 return "comment";
317 }
323 }
318
324
@@ -69,7 +69,10 b''
69 token: null,
69 token: null,
70 next: "start"
70 next: "start"
71 }
71 }
72 ]
72 ],
73 meta: {
74 lineComment: "#"
75 }
73 });
76 });
74
77
75 CodeMirror.defineMIME("text/x-dockerfile", "dockerfile");
78 CodeMirror.defineMIME("text/x-dockerfile", "dockerfile");
@@ -202,4 +202,4 b''
202 });
202 });
203
203
204 CodeMirror.defineMIME("text/x-elm", "elm");
204 CodeMirror.defineMIME("text/x-elm", "elm");
205 })();
205 });
@@ -220,8 +220,6 b' CodeMirror.defineMode("erlang", function'
220 }else{
220 }else{
221 return rval(state,stream,"function");
221 return rval(state,stream,"function");
222 }
222 }
223 }else if (is_member(w,operatorAtomWords)) {
224 return rval(state,stream,"operator");
225 }else if (lookahead(stream) == ":") {
223 }else if (lookahead(stream) == ":") {
226 if (w == "erlang") {
224 if (w == "erlang") {
227 return rval(state,stream,"builtin");
225 return rval(state,stream,"builtin");
@@ -230,8 +228,6 b' CodeMirror.defineMode("erlang", function'
230 }
228 }
231 }else if (is_member(w,["true","false"])) {
229 }else if (is_member(w,["true","false"])) {
232 return rval(state,stream,"boolean");
230 return rval(state,stream,"boolean");
233 }else if (is_member(w,["true","false"])) {
234 return rval(state,stream,"boolean");
235 }else{
231 }else{
236 return rval(state,stream,"atom");
232 return rval(state,stream,"atom");
237 }
233 }
@@ -11,6 +11,8 b''
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 var urlRE = /^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i
15
14 CodeMirror.defineMode("gfm", function(config, modeConfig) {
16 CodeMirror.defineMode("gfm", function(config, modeConfig) {
15 var codeDepth = 0;
17 var codeDepth = 0;
16 function blankLine(state) {
18 function blankLine(state) {
@@ -37,7 +39,7 b' CodeMirror.defineMode("gfm", function(co'
37
39
38 // Hack to prevent formatting override inside code blocks (block and inline)
40 // Hack to prevent formatting override inside code blocks (block and inline)
39 if (state.codeBlock) {
41 if (state.codeBlock) {
40 if (stream.match(/^```/)) {
42 if (stream.match(/^```+/)) {
41 state.codeBlock = false;
43 state.codeBlock = false;
42 return null;
44 return null;
43 }
45 }
@@ -47,7 +49,7 b' CodeMirror.defineMode("gfm", function(co'
47 if (stream.sol()) {
49 if (stream.sol()) {
48 state.code = false;
50 state.code = false;
49 }
51 }
50 if (stream.sol() && stream.match(/^```/)) {
52 if (stream.sol() && stream.match(/^```+/)) {
51 stream.skipToEnd();
53 stream.skipToEnd();
52 state.codeBlock = true;
54 state.codeBlock = true;
53 return null;
55 return null;
@@ -78,25 +80,29 b' CodeMirror.defineMode("gfm", function(co'
78 }
80 }
79 if (stream.sol() || state.ateSpace) {
81 if (stream.sol() || state.ateSpace) {
80 state.ateSpace = false;
82 state.ateSpace = false;
81 if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) {
83 if (modeConfig.gitHubSpice !== false) {
82 // User/Project@SHA
84 if(stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/)) {
83 // User@SHA
85 // User/Project@SHA
84 // SHA
86 // User@SHA
85 state.combineTokens = true;
87 // SHA
86 return "link";
88 state.combineTokens = true;
87 } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) {
89 return "link";
88 // User/Project#Num
90 } else if (stream.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/)) {
89 // User#Num
91 // User/Project#Num
90 // #Num
92 // User#Num
91 state.combineTokens = true;
93 // #Num
92 return "link";
94 state.combineTokens = true;
95 return "link";
96 }
93 }
97 }
94 }
98 }
95 if (stream.match(/^((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i) &&
99 if (stream.match(urlRE) &&
96 stream.string.slice(stream.start - 2, stream.start) != "](") {
100 stream.string.slice(stream.start - 2, stream.start) != "](" &&
101 (stream.start == 0 || /\W/.test(stream.string.charAt(stream.start - 1)))) {
97 // URLs
102 // URLs
98 // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
103 // Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
99 // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine
104 // And then (issue #1160) simplified to make it not crash the Chrome Regexp engine
105 // And then limited url schemes to the CommonMark list, so foo:bar isn't matched as a URL
100 state.combineTokens = true;
106 state.combineTokens = true;
101 return "link";
107 return "link";
102 }
108 }
@@ -109,15 +115,16 b' CodeMirror.defineMode("gfm", function(co'
109 var markdownConfig = {
115 var markdownConfig = {
110 underscoresBreakWords: false,
116 underscoresBreakWords: false,
111 taskLists: true,
117 taskLists: true,
112 fencedCodeBlocks: true,
118 fencedCodeBlocks: '```',
113 strikethrough: true
119 strikethrough: true
114 };
120 };
115 for (var attr in modeConfig) {
121 for (var attr in modeConfig) {
116 markdownConfig[attr] = modeConfig[attr];
122 markdownConfig[attr] = modeConfig[attr];
117 }
123 }
118 markdownConfig.name = "markdown";
124 markdownConfig.name = "markdown";
119 CodeMirror.defineMIME("gfmBase", markdownConfig);
125 return CodeMirror.overlayMode(CodeMirror.getMode(config, markdownConfig), gfmOverlay);
120 return CodeMirror.overlayMode(CodeMirror.getMode(config, "gfmBase"), gfmOverlay);
126
121 }, "markdown");
127 }, "markdown");
122
128
129 CodeMirror.defineMIME("text/x-gfm", "gfm");
123 });
130 });
@@ -86,7 +86,7 b' CodeMirror.defineMode("go", function(con'
86 var escaped = false, next, end = false;
86 var escaped = false, next, end = false;
87 while ((next = stream.next()) != null) {
87 while ((next = stream.next()) != null) {
88 if (next == quote && !escaped) {end = true; break;}
88 if (next == quote && !escaped) {end = true; break;}
89 escaped = !escaped && next == "\\";
89 escaped = !escaped && quote != "`" && next == "\\";
90 }
90 }
91 if (end || !(escaped || quote == "`"))
91 if (end || !(escaped || quote == "`"))
92 state.tokenize = tokenBase;
92 state.tokenize = tokenBase;
@@ -85,8 +85,10 b''
85 state.tokenize = rubyInQuote(")");
85 state.tokenize = rubyInQuote(")");
86 return state.tokenize(stream, state);
86 return state.tokenize(stream, state);
87 } else if (ch == "{") {
87 } else if (ch == "{") {
88 state.tokenize = rubyInQuote("}");
88 if (!stream.match(/^\{%.*/)) {
89 return state.tokenize(stream, state);
89 state.tokenize = rubyInQuote("}");
90 return state.tokenize(stream, state);
91 }
90 }
92 }
91 }
93 }
92
94
@@ -3,15 +3,15 b''
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
6 mod(require("../../lib/codemirror"), require("../../addon/mode/simple"), require("../../addon/mode/multiplex"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
8 define(["../../lib/codemirror", "../../addon/mode/simple", "../../addon/mode/multiplex"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineSimpleMode("handlebars", {
14 CodeMirror.defineSimpleMode("handlebars-tags", {
15 start: [
15 start: [
16 { regex: /\{\{!--/, push: "dash_comment", token: "comment" },
16 { regex: /\{\{!--/, push: "dash_comment", token: "comment" },
17 { regex: /\{\{!/, push: "comment", token: "comment" },
17 { regex: /\{\{!/, push: "comment", token: "comment" },
@@ -21,8 +21,8 b''
21 { regex: /\}\}/, pop: true, token: "tag" },
21 { regex: /\}\}/, pop: true, token: "tag" },
22
22
23 // Double and single quotes
23 // Double and single quotes
24 { regex: /"(?:[^\\]|\\.)*?"/, token: "string" },
24 { regex: /"(?:[^\\"]|\\.)*"?/, token: "string" },
25 { regex: /'(?:[^\\]|\\.)*?'/, token: "string" },
25 { regex: /'(?:[^\\']|\\.)*'?/, token: "string" },
26
26
27 // Handlebars keywords
27 // Handlebars keywords
28 { regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" },
28 { regex: />|[#\/]([A-Za-z_]\w*)/, token: "keyword" },
@@ -49,5 +49,14 b''
49 ]
49 ]
50 });
50 });
51
51
52 CodeMirror.defineMode("handlebars", function(config, parserConfig) {
53 var handlebars = CodeMirror.getMode(config, "handlebars-tags");
54 if (!parserConfig || !parserConfig.base) return handlebars;
55 return CodeMirror.multiplexingMode(
56 CodeMirror.getMode(config, parserConfig.base),
57 {open: "{{", close: "}}", mode: handlebars, parseDelimiters: true}
58 );
59 });
60
52 CodeMirror.defineMIME("text/x-handlebars-template", "handlebars");
61 CodeMirror.defineMIME("text/x-handlebars-template", "handlebars");
53 });
62 });
@@ -16,23 +16,21 b' CodeMirror.defineMode("haxe", function(c'
16
16
17 // Tokenizer
17 // Tokenizer
18
18
19 var keywords = function(){
19 function kw(type) {return {type: type, style: "keyword"};}
20 function kw(type) {return {type: type, style: "keyword"};}
20 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
21 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
21 var operator = kw("operator"), atom = {type: "atom", style: "atom"}, attribute = {type:"attribute", style: "attribute"};
22 var operator = kw("operator"), atom = {type: "atom", style: "atom"}, attribute = {type:"attribute", style: "attribute"};
23 var type = kw("typedef");
22 var type = kw("typedef");
24 return {
23 var keywords = {
25 "if": A, "while": A, "else": B, "do": B, "try": B,
24 "if": A, "while": A, "else": B, "do": B, "try": B,
26 "return": C, "break": C, "continue": C, "new": C, "throw": C,
25 "return": C, "break": C, "continue": C, "new": C, "throw": C,
27 "var": kw("var"), "inline":attribute, "static": attribute, "using":kw("import"),
26 "var": kw("var"), "inline":attribute, "static": attribute, "using":kw("import"),
28 "public": attribute, "private": attribute, "cast": kw("cast"), "import": kw("import"), "macro": kw("macro"),
27 "public": attribute, "private": attribute, "cast": kw("cast"), "import": kw("import"), "macro": kw("macro"),
29 "function": kw("function"), "catch": kw("catch"), "untyped": kw("untyped"), "callback": kw("cb"),
28 "function": kw("function"), "catch": kw("catch"), "untyped": kw("untyped"), "callback": kw("cb"),
30 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
29 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
31 "in": operator, "never": kw("property_access"), "trace":kw("trace"),
30 "in": operator, "never": kw("property_access"), "trace":kw("trace"),
32 "class": type, "abstract":type, "enum":type, "interface":type, "typedef":type, "extends":type, "implements":type, "dynamic":type,
31 "class": type, "abstract":type, "enum":type, "interface":type, "typedef":type, "extends":type, "implements":type, "dynamic":type,
33 "true": atom, "false": atom, "null": atom
32 "true": atom, "false": atom, "null": atom
34 };
33 };
35 }();
36
34
37 var isOperatorChar = /[+\-*&%=<>!?|]/;
35 var isOperatorChar = /[+\-*&%=<>!?|]/;
38
36
@@ -41,14 +39,13 b' CodeMirror.defineMode("haxe", function(c'
41 return f(stream, state);
39 return f(stream, state);
42 }
40 }
43
41
44 function nextUntilUnescaped(stream, end) {
42 function toUnescaped(stream, end) {
45 var escaped = false, next;
43 var escaped = false, next;
46 while ((next = stream.next()) != null) {
44 while ((next = stream.next()) != null) {
47 if (next == end && !escaped)
45 if (next == end && !escaped)
48 return false;
46 return true;
49 escaped = !escaped && next == "\\";
47 escaped = !escaped && next == "\\";
50 }
48 }
51 return escaped;
52 }
49 }
53
50
54 // Used as scratch variables to communicate multiple values without
51 // Used as scratch variables to communicate multiple values without
@@ -61,70 +58,58 b' CodeMirror.defineMode("haxe", function(c'
61
58
62 function haxeTokenBase(stream, state) {
59 function haxeTokenBase(stream, state) {
63 var ch = stream.next();
60 var ch = stream.next();
64 if (ch == '"' || ch == "'")
61 if (ch == '"' || ch == "'") {
65 return chain(stream, state, haxeTokenString(ch));
62 return chain(stream, state, haxeTokenString(ch));
66 else if (/[\[\]{}\(\),;\:\.]/.test(ch))
63 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
67 return ret(ch);
64 return ret(ch);
68 else if (ch == "0" && stream.eat(/x/i)) {
65 } else if (ch == "0" && stream.eat(/x/i)) {
69 stream.eatWhile(/[\da-f]/i);
66 stream.eatWhile(/[\da-f]/i);
70 return ret("number", "number");
67 return ret("number", "number");
71 }
68 } else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
72 else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
69 stream.match(/^\d*(?:\.\d*(?!\.))?(?:[eE][+\-]?\d+)?/);
73 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
74 return ret("number", "number");
70 return ret("number", "number");
75 }
71 } else if (state.reAllowed && (ch == "~" && stream.eat(/\//))) {
76 else if (state.reAllowed && (ch == "~" && stream.eat(/\//))) {
72 toUnescaped(stream, "/");
77 nextUntilUnescaped(stream, "/");
78 stream.eatWhile(/[gimsu]/);
73 stream.eatWhile(/[gimsu]/);
79 return ret("regexp", "string-2");
74 return ret("regexp", "string-2");
80 }
75 } else if (ch == "/") {
81 else if (ch == "/") {
82 if (stream.eat("*")) {
76 if (stream.eat("*")) {
83 return chain(stream, state, haxeTokenComment);
77 return chain(stream, state, haxeTokenComment);
84 }
78 } else if (stream.eat("/")) {
85 else if (stream.eat("/")) {
86 stream.skipToEnd();
79 stream.skipToEnd();
87 return ret("comment", "comment");
80 return ret("comment", "comment");
88 }
81 } else {
89 else {
90 stream.eatWhile(isOperatorChar);
82 stream.eatWhile(isOperatorChar);
91 return ret("operator", null, stream.current());
83 return ret("operator", null, stream.current());
92 }
84 }
93 }
85 } else if (ch == "#") {
94 else if (ch == "#") {
95 stream.skipToEnd();
86 stream.skipToEnd();
96 return ret("conditional", "meta");
87 return ret("conditional", "meta");
97 }
88 } else if (ch == "@") {
98 else if (ch == "@") {
99 stream.eat(/:/);
89 stream.eat(/:/);
100 stream.eatWhile(/[\w_]/);
90 stream.eatWhile(/[\w_]/);
101 return ret ("metadata", "meta");
91 return ret ("metadata", "meta");
102 }
92 } else if (isOperatorChar.test(ch)) {
103 else if (isOperatorChar.test(ch)) {
104 stream.eatWhile(isOperatorChar);
93 stream.eatWhile(isOperatorChar);
105 return ret("operator", null, stream.current());
94 return ret("operator", null, stream.current());
106 }
95 } else {
107 else {
96 var word;
108 var word;
97 if(/[A-Z]/.test(ch)) {
109 if(/[A-Z]/.test(ch))
98 stream.eatWhile(/[\w_<>]/);
110 {
99 word = stream.current();
111 stream.eatWhile(/[\w_<>]/);
100 return ret("type", "variable-3", word);
112 word = stream.current();
101 } else {
113 return ret("type", "variable-3", word);
114 }
115 else
116 {
117 stream.eatWhile(/[\w_]/);
102 stream.eatWhile(/[\w_]/);
118 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
103 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
119 return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
104 return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
120 ret("variable", "variable", word);
105 ret("variable", "variable", word);
121 }
106 }
122 }
107 }
123 }
108 }
124
109
125 function haxeTokenString(quote) {
110 function haxeTokenString(quote) {
126 return function(stream, state) {
111 return function(stream, state) {
127 if (!nextUntilUnescaped(stream, quote))
112 if (toUnescaped(stream, quote))
128 state.tokenize = haxeTokenBase;
113 state.tokenize = haxeTokenBase;
129 return ret("string", "string");
114 return ret("string", "string");
130 };
115 };
@@ -176,27 +161,25 b' CodeMirror.defineMode("haxe", function(c'
176 cc.pop()();
161 cc.pop()();
177 if (cx.marked) return cx.marked;
162 if (cx.marked) return cx.marked;
178 if (type == "variable" && inScope(state, content)) return "variable-2";
163 if (type == "variable" && inScope(state, content)) return "variable-2";
179 if (type == "variable" && imported(state, content)) return "variable-3";
164 if (type == "variable" && imported(state, content)) return "variable-3";
180 return style;
165 return style;
181 }
166 }
182 }
167 }
183 }
168 }
184
169
185 function imported(state, typename)
170 function imported(state, typename) {
186 {
171 if (/[a-z]/.test(typename.charAt(0)))
187 if (/[a-z]/.test(typename.charAt(0)))
172 return false;
188 return false;
173 var len = state.importedtypes.length;
189 var len = state.importedtypes.length;
174 for (var i = 0; i<len; i++)
190 for (var i = 0; i<len; i++)
175 if(state.importedtypes[i]==typename) return true;
191 if(state.importedtypes[i]==typename) return true;
192 }
176 }
193
177
194
195 function registerimport(importname) {
178 function registerimport(importname) {
196 var state = cx.state;
179 var state = cx.state;
197 for (var t = state.importedtypes; t; t = t.next)
180 for (var t = state.importedtypes; t; t = t.next)
198 if(t.name == importname) return;
181 if(t.name == importname) return;
199 state.importedtypes = { name: importname, next: state.importedtypes };
182 state.importedtypes = { name: importname, next: state.importedtypes };
200 }
183 }
201 // Combinator utils
184 // Combinator utils
202
185
@@ -208,13 +191,20 b' CodeMirror.defineMode("haxe", function(c'
208 pass.apply(null, arguments);
191 pass.apply(null, arguments);
209 return true;
192 return true;
210 }
193 }
194 function inList(name, list) {
195 for (var v = list; v; v = v.next)
196 if (v.name == name) return true;
197 return false;
198 }
211 function register(varname) {
199 function register(varname) {
212 var state = cx.state;
200 var state = cx.state;
213 if (state.context) {
201 if (state.context) {
214 cx.marked = "def";
202 cx.marked = "def";
215 for (var v = state.localVars; v; v = v.next)
203 if (inList(varname, state.localVars)) return;
216 if (v.name == varname) return;
217 state.localVars = {name: varname, next: state.localVars};
204 state.localVars = {name: varname, next: state.localVars};
205 } else if (state.globalVars) {
206 if (inList(varname, state.globalVars)) return;
207 state.globalVars = {name: varname, next: state.globalVars};
218 }
208 }
219 }
209 }
220
210
@@ -229,6 +219,7 b' CodeMirror.defineMode("haxe", function(c'
229 cx.state.localVars = cx.state.context.vars;
219 cx.state.localVars = cx.state.context.vars;
230 cx.state.context = cx.state.context.prev;
220 cx.state.context = cx.state.context.prev;
231 }
221 }
222 popcontext.lex = true;
232 function pushlex(type, info) {
223 function pushlex(type, info) {
233 var result = function() {
224 var result = function() {
234 var state = cx.state;
225 var state = cx.state;
@@ -252,7 +243,7 b' CodeMirror.defineMode("haxe", function(c'
252 if (type == wanted) return cont();
243 if (type == wanted) return cont();
253 else if (wanted == ";") return pass();
244 else if (wanted == ";") return pass();
254 else return cont(f);
245 else return cont(f);
255 };
246 }
256 return f;
247 return f;
257 }
248 }
258
249
@@ -266,25 +257,26 b' CodeMirror.defineMode("haxe", function(c'
266 if (type == "attribute") return cont(maybeattribute);
257 if (type == "attribute") return cont(maybeattribute);
267 if (type == "function") return cont(functiondef);
258 if (type == "function") return cont(functiondef);
268 if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
259 if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
269 poplex, statement, poplex);
260 poplex, statement, poplex);
270 if (type == "variable") return cont(pushlex("stat"), maybelabel);
261 if (type == "variable") return cont(pushlex("stat"), maybelabel);
271 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
262 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
272 block, poplex, poplex);
263 block, poplex, poplex);
273 if (type == "case") return cont(expression, expect(":"));
264 if (type == "case") return cont(expression, expect(":"));
274 if (type == "default") return cont(expect(":"));
265 if (type == "default") return cont(expect(":"));
275 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
266 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
276 statement, poplex, popcontext);
267 statement, poplex, popcontext);
277 if (type == "import") return cont(importdef, expect(";"));
268 if (type == "import") return cont(importdef, expect(";"));
278 if (type == "typedef") return cont(typedef);
269 if (type == "typedef") return cont(typedef);
279 return pass(pushlex("stat"), expression, expect(";"), poplex);
270 return pass(pushlex("stat"), expression, expect(";"), poplex);
280 }
271 }
281 function expression(type) {
272 function expression(type) {
282 if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
273 if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
274 if (type == "type" ) return cont(maybeoperator);
283 if (type == "function") return cont(functiondef);
275 if (type == "function") return cont(functiondef);
284 if (type == "keyword c") return cont(maybeexpression);
276 if (type == "keyword c") return cont(maybeexpression);
285 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
277 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
286 if (type == "operator") return cont(expression);
278 if (type == "operator") return cont(expression);
287 if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
279 if (type == "[") return cont(pushlex("]"), commasep(maybeexpression, "]"), poplex, maybeoperator);
288 if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
280 if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
289 return cont();
281 return cont();
290 }
282 }
@@ -318,14 +310,14 b' CodeMirror.defineMode("haxe", function(c'
318 }
310 }
319
311
320 function importdef (type, value) {
312 function importdef (type, value) {
321 if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
313 if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
322 else if(type == "variable" || type == "property" || type == "." || value == "*") return cont(importdef);
314 else if(type == "variable" || type == "property" || type == "." || value == "*") return cont(importdef);
323 }
315 }
324
316
325 function typedef (type, value)
317 function typedef (type, value)
326 {
318 {
327 if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
319 if(type == "variable" && /[A-Z]/.test(value.charAt(0))) { registerimport(value); return cont(); }
328 else if (type == "type" && /[A-Z]/.test(value.charAt(0))) { return cont(); }
320 else if (type == "type" && /[A-Z]/.test(value.charAt(0))) { return cont(); }
329 }
321 }
330
322
331 function maybelabel(type) {
323 function maybelabel(type) {
@@ -363,16 +355,19 b' CodeMirror.defineMode("haxe", function(c'
363 if (type == ",") return cont(vardef1);
355 if (type == ",") return cont(vardef1);
364 }
356 }
365 function forspec1(type, value) {
357 function forspec1(type, value) {
366 if (type == "variable") {
358 if (type == "variable") {
367 register(value);
359 register(value);
368 }
360 return cont(forin, expression)
369 return cont(pushlex(")"), pushcontext, forin, expression, poplex, statement, popcontext);
361 } else {
362 return pass()
363 }
370 }
364 }
371 function forin(_type, value) {
365 function forin(_type, value) {
372 if (value == "in") return cont();
366 if (value == "in") return cont();
373 }
367 }
374 function functiondef(type, value) {
368 function functiondef(type, value) {
375 if (type == "variable") {register(value); return cont(functiondef);}
369 //function names starting with upper-case letters are recognised as types, so cludging them together here.
370 if (type == "variable" || type == "type") {register(value); return cont(functiondef);}
376 if (value == "new") return cont(functiondef);
371 if (value == "new") return cont(functiondef);
377 if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, typeuse, statement, popcontext);
372 if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, typeuse, statement, popcontext);
378 }
373 }
@@ -392,21 +387,23 b' CodeMirror.defineMode("haxe", function(c'
392 }
387 }
393
388
394 // Interface
389 // Interface
395
396 return {
390 return {
397 startState: function(basecolumn) {
391 startState: function(basecolumn) {
398 var defaulttypes = ["Int", "Float", "String", "Void", "Std", "Bool", "Dynamic", "Array"];
392 var defaulttypes = ["Int", "Float", "String", "Void", "Std", "Bool", "Dynamic", "Array"];
399 return {
393 var state = {
400 tokenize: haxeTokenBase,
394 tokenize: haxeTokenBase,
401 reAllowed: true,
395 reAllowed: true,
402 kwAllowed: true,
396 kwAllowed: true,
403 cc: [],
397 cc: [],
404 lexical: new HaxeLexical((basecolumn || 0) - indentUnit, 0, "block", false),
398 lexical: new HaxeLexical((basecolumn || 0) - indentUnit, 0, "block", false),
405 localVars: parserConfig.localVars,
399 localVars: parserConfig.localVars,
406 importedtypes: defaulttypes,
400 importedtypes: defaulttypes,
407 context: parserConfig.localVars && {vars: parserConfig.localVars},
401 context: parserConfig.localVars && {vars: parserConfig.localVars},
408 indented: 0
402 indented: 0
409 };
403 };
404 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
405 state.globalVars = parserConfig.globalVars;
406 return state;
410 },
407 },
411
408
412 token: function(stream, state) {
409 token: function(stream, state) {
@@ -9,113 +9,142 b''
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
14 CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
15 var htmlMode = CodeMirror.getMode(config, {name: "xml",
16 htmlMode: true,
17 multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
18 multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
19 var cssMode = CodeMirror.getMode(config, "css");
20
21 var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
22 scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
23 mode: CodeMirror.getMode(config, "javascript")});
24 if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
25 var conf = scriptTypesConf[i];
26 scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
27 }
28 scriptTypes.push({matches: /./,
29 mode: CodeMirror.getMode(config, "text/plain")});
30
13
31 function html(stream, state) {
14 var defaultTags = {
32 var tagName = state.htmlState.tagName;
15 script: [
33 if (tagName) tagName = tagName.toLowerCase();
16 ["lang", /(javascript|babel)/i, "javascript"],
34 var style = htmlMode.token(stream, state.htmlState);
17 ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, "javascript"],
35 if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
18 ["type", /./, "text/plain"],
36 // Script block: mode to change to depends on type attribute
19 [null, null, "javascript"]
37 var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
20 ],
38 scriptType = scriptType ? scriptType[1] : "";
21 style: [
39 if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
22 ["lang", /^css$/i, "css"],
40 for (var i = 0; i < scriptTypes.length; ++i) {
23 ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"],
41 var tp = scriptTypes[i];
24 ["type", /./, "text/plain"],
42 if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
25 [null, null, "css"]
43 if (tp.mode) {
26 ]
44 state.token = script;
27 };
45 state.localMode = tp.mode;
28
46 state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
47 }
48 break;
49 }
50 }
51 } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
52 state.token = css;
53 state.localMode = cssMode;
54 state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
55 }
56 return style;
57 }
58 function maybeBackup(stream, pat, style) {
29 function maybeBackup(stream, pat, style) {
59 var cur = stream.current();
30 var cur = stream.current(), close = cur.search(pat);
60 var close = cur.search(pat);
31 if (close > -1) {
61 if (close > -1) stream.backUp(cur.length - close);
32 stream.backUp(cur.length - close);
62 else if (cur.match(/<\/?$/)) {
33 } else if (cur.match(/<\/?$/)) {
63 stream.backUp(cur.length);
34 stream.backUp(cur.length);
64 if (!stream.match(pat, false)) stream.match(cur);
35 if (!stream.match(pat, false)) stream.match(cur);
65 }
36 }
66 return style;
37 return style;
67 }
38 }
68 function script(stream, state) {
39
69 if (stream.match(/^<\/\s*script\s*>/i, false)) {
40 var attrRegexpCache = {};
70 state.token = html;
41 function getAttrRegexp(attr) {
71 state.localState = state.localMode = null;
42 var regexp = attrRegexpCache[attr];
72 return null;
43 if (regexp) return regexp;
73 }
44 return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
74 return maybeBackup(stream, /<\/\s*script\s*>/,
45 }
75 state.localMode.token(stream, state.localState));
46
47 function getAttrValue(stream, attr) {
48 var pos = stream.pos, match;
49 while (pos >= 0 && stream.string.charAt(pos) !== "<") pos--;
50 if (pos < 0) return pos;
51 if (match = stream.string.slice(pos, stream.pos).match(getAttrRegexp(attr)))
52 return match[2];
53 return "";
76 }
54 }
77 function css(stream, state) {
55
78 if (stream.match(/^<\/\s*style\s*>/i, false)) {
56 function getTagRegexp(tagName, anchored) {
79 state.token = html;
57 return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i");
80 state.localState = state.localMode = null;
58 }
81 return null;
59
60 function addTags(from, to) {
61 for (var tag in from) {
62 var dest = to[tag] || (to[tag] = []);
63 var source = from[tag];
64 for (var i = source.length - 1; i >= 0; i--)
65 dest.unshift(source[i])
82 }
66 }
83 return maybeBackup(stream, /<\/\s*style\s*>/,
67 }
84 cssMode.token(stream, state.localState));
68
69 function findMatchingMode(tagInfo, stream) {
70 for (var i = 0; i < tagInfo.length; i++) {
71 var spec = tagInfo[i];
72 if (!spec[0] || spec[1].test(getAttrValue(stream, spec[0]))) return spec[2];
73 }
85 }
74 }
86
75
87 return {
76 CodeMirror.defineMode("htmlmixed", function (config, parserConfig) {
88 startState: function() {
77 var htmlMode = CodeMirror.getMode(config, {
89 var state = htmlMode.startState();
78 name: "xml",
90 return {token: html, localMode: null, localState: null, htmlState: state};
79 htmlMode: true,
91 },
80 multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
81 multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag
82 });
92
83
93 copyState: function(state) {
84 var tags = {};
94 if (state.localState)
85 var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes;
95 var local = CodeMirror.copyState(state.localMode, state.localState);
86 addTags(defaultTags, tags);
96 return {token: state.token, localMode: state.localMode, localState: local,
87 if (configTags) addTags(configTags, tags);
97 htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
88 if (configScript) for (var i = configScript.length - 1; i >= 0; i--)
98 },
89 tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
99
90
100 token: function(stream, state) {
91 function html(stream, state) {
101 return state.token(stream, state);
92 var tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase();
102 },
93 var tagInfo = tagName && tags.hasOwnProperty(tagName) && tags[tagName];
94
95 var style = htmlMode.token(stream, state.htmlState), modeSpec;
103
96
104 indent: function(state, textAfter) {
97 if (tagInfo && /\btag\b/.test(style) && stream.current() === ">" &&
105 if (!state.localMode || /^\s*<\//.test(textAfter))
98 (modeSpec = findMatchingMode(tagInfo, stream))) {
106 return htmlMode.indent(state.htmlState, textAfter);
99 var mode = CodeMirror.getMode(config, modeSpec);
107 else if (state.localMode.indent)
100 var endTagA = getTagRegexp(tagName, true), endTag = getTagRegexp(tagName, false);
108 return state.localMode.indent(state.localState, textAfter);
101 state.token = function (stream, state) {
109 else
102 if (stream.match(endTagA, false)) {
110 return CodeMirror.Pass;
103 state.token = html;
111 },
104 state.localState = state.localMode = null;
105 return null;
106 }
107 return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
108 };
109 state.localMode = mode;
110 state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, ""));
111 }
112 return style;
113 };
114
115 return {
116 startState: function () {
117 var state = htmlMode.startState();
118 return {token: html, localMode: null, localState: null, htmlState: state};
119 },
112
120
113 innerMode: function(state) {
121 copyState: function (state) {
114 return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
122 var local;
115 }
123 if (state.localState) {
116 };
124 local = CodeMirror.copyState(state.localMode, state.localState);
117 }, "xml", "javascript", "css");
125 }
126 return {token: state.token, localMode: state.localMode, localState: local,
127 htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
128 },
129
130 token: function (stream, state) {
131 return state.token(stream, state);
132 },
118
133
119 CodeMirror.defineMIME("text/html", "htmlmixed");
134 indent: function (state, textAfter) {
135 if (!state.localMode || /^\s*<\//.test(textAfter))
136 return htmlMode.indent(state.htmlState, textAfter);
137 else if (state.localMode.indent)
138 return state.localMode.indent(state.localState, textAfter);
139 else
140 return CodeMirror.Pass;
141 },
120
142
143 innerMode: function (state) {
144 return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
145 }
146 };
147 }, "xml", "javascript", "css");
148
149 CodeMirror.defineMIME("text/html", "htmlmixed");
121 });
150 });
@@ -74,7 +74,7 b" CodeMirror.defineMode('jade', function ("
74 res.javaScriptArguments = this.javaScriptArguments;
74 res.javaScriptArguments = this.javaScriptArguments;
75 res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth;
75 res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth;
76 res.isInterpolating = this.isInterpolating;
76 res.isInterpolating = this.isInterpolating;
77 res.interpolationNesting = this.intpolationNesting;
77 res.interpolationNesting = this.interpolationNesting;
78
78
79 res.jsState = CodeMirror.copyState(jsMode, this.jsState);
79 res.jsState = CodeMirror.copyState(jsMode, this.jsState);
80
80
@@ -167,7 +167,7 b" CodeMirror.defineMode('jade', function ("
167 if (state.interpolationNesting < 0) {
167 if (state.interpolationNesting < 0) {
168 stream.next();
168 stream.next();
169 state.isInterpolating = false;
169 state.isInterpolating = false;
170 return 'puncutation';
170 return 'punctuation';
171 }
171 }
172 } else if (stream.peek() === '{') {
172 } else if (stream.peek() === '{') {
173 state.interpolationNesting++;
173 state.interpolationNesting++;
@@ -583,7 +583,7 b" CodeMirror.defineMode('jade', function ("
583 copyState: copyState,
583 copyState: copyState,
584 token: nextToken
584 token: nextToken
585 };
585 };
586 });
586 }, 'javascript', 'css', 'htmlmixed');
587
587
588 CodeMirror.defineMIME('text/x-jade', 'jade');
588 CodeMirror.defineMIME('text/x-jade', 'jade');
589
589
@@ -13,6 +13,11 b''
13 })(function(CodeMirror) {
13 })(function(CodeMirror) {
14 "use strict";
14 "use strict";
15
15
16 function expressionAllowed(stream, state, backUp) {
17 return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
18 (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
19 }
20
16 CodeMirror.defineMode("javascript", function(config, parserConfig) {
21 CodeMirror.defineMode("javascript", function(config, parserConfig) {
17 var indentUnit = config.indentUnit;
22 var indentUnit = config.indentUnit;
18 var statementIndent = parserConfig.statementIndent;
23 var statementIndent = parserConfig.statementIndent;
@@ -30,13 +35,13 b' CodeMirror.defineMode("javascript", func'
30
35
31 var jsKeywords = {
36 var jsKeywords = {
32 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
37 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
33 "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
38 "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
34 "var": kw("var"), "const": kw("var"), "let": kw("var"),
39 "var": kw("var"), "const": kw("var"), "let": kw("var"),
35 "function": kw("function"), "catch": kw("catch"),
40 "function": kw("function"), "catch": kw("catch"),
36 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
41 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
37 "in": operator, "typeof": operator, "instanceof": operator,
42 "in": operator, "typeof": operator, "instanceof": operator,
38 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
43 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
39 "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
44 "this": kw("this"), "class": kw("class"), "super": kw("atom"),
40 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
45 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
41 };
46 };
42
47
@@ -45,18 +50,23 b' CodeMirror.defineMode("javascript", func'
45 var type = {type: "variable", style: "variable-3"};
50 var type = {type: "variable", style: "variable-3"};
46 var tsKeywords = {
51 var tsKeywords = {
47 // object-like things
52 // object-like things
48 "interface": kw("interface"),
53 "interface": kw("class"),
49 "extends": kw("extends"),
54 "implements": C,
50 "constructor": kw("constructor"),
55 "namespace": C,
56 "module": kw("module"),
57 "enum": kw("module"),
51
58
52 // scope modifiers
59 // scope modifiers
53 "public": kw("public"),
60 "public": kw("modifier"),
54 "private": kw("private"),
61 "private": kw("modifier"),
55 "protected": kw("protected"),
62 "protected": kw("modifier"),
56 "static": kw("static"),
63 "abstract": kw("modifier"),
64
65 // operators
66 "as": operator,
57
67
58 // types
68 // types
59 "string": type, "number": type, "bool": type, "any": type
69 "string": type, "number": type, "boolean": type, "any": type
60 };
70 };
61
71
62 for (var attr in tsKeywords) {
72 for (var attr in tsKeywords) {
@@ -105,6 +115,12 b' CodeMirror.defineMode("javascript", func'
105 } else if (ch == "0" && stream.eat(/x/i)) {
115 } else if (ch == "0" && stream.eat(/x/i)) {
106 stream.eatWhile(/[\da-f]/i);
116 stream.eatWhile(/[\da-f]/i);
107 return ret("number", "number");
117 return ret("number", "number");
118 } else if (ch == "0" && stream.eat(/o/i)) {
119 stream.eatWhile(/[0-7]/i);
120 return ret("number", "number");
121 } else if (ch == "0" && stream.eat(/b/i)) {
122 stream.eatWhile(/[01]/i);
123 return ret("number", "number");
108 } else if (/\d/.test(ch)) {
124 } else if (/\d/.test(ch)) {
109 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
125 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
110 return ret("number", "number");
126 return ret("number", "number");
@@ -115,8 +131,7 b' CodeMirror.defineMode("javascript", func'
115 } else if (stream.eat("/")) {
131 } else if (stream.eat("/")) {
116 stream.skipToEnd();
132 stream.skipToEnd();
117 return ret("comment", "comment");
133 return ret("comment", "comment");
118 } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
134 } else if (expressionAllowed(stream, state, 1)) {
119 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
120 readRegexp(stream);
135 readRegexp(stream);
121 stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
136 stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
122 return ret("regexp", "string-2");
137 return ret("regexp", "string-2");
@@ -275,8 +290,8 b' CodeMirror.defineMode("javascript", func'
275 return false;
290 return false;
276 }
291 }
277 var state = cx.state;
292 var state = cx.state;
293 cx.marked = "def";
278 if (state.context) {
294 if (state.context) {
279 cx.marked = "def";
280 if (inList(state.localVars)) return;
295 if (inList(state.localVars)) return;
281 state.localVars = {name: varname, next: state.localVars};
296 state.localVars = {name: varname, next: state.localVars};
282 } else {
297 } else {
@@ -347,10 +362,10 b' CodeMirror.defineMode("javascript", func'
347 if (type == "default") return cont(expect(":"));
362 if (type == "default") return cont(expect(":"));
348 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
363 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
349 statement, poplex, popcontext);
364 statement, poplex, popcontext);
350 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
351 if (type == "class") return cont(pushlex("form"), className, poplex);
365 if (type == "class") return cont(pushlex("form"), className, poplex);
352 if (type == "export") return cont(pushlex("form"), afterExport, poplex);
366 if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
353 if (type == "import") return cont(pushlex("form"), afterImport, poplex);
367 if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
368 if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex)
354 return pass(pushlex("stat"), expression, expect(";"), poplex);
369 return pass(pushlex("stat"), expression, expect(";"), poplex);
355 }
370 }
356 function expression(type) {
371 function expression(type) {
@@ -374,7 +389,8 b' CodeMirror.defineMode("javascript", func'
374 if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
389 if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
375 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
390 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
376 if (type == "{") return contCommasep(objprop, "}", null, maybeop);
391 if (type == "{") return contCommasep(objprop, "}", null, maybeop);
377 if (type == "quasi") { return pass(quasi, maybeop); }
392 if (type == "quasi") return pass(quasi, maybeop);
393 if (type == "new") return cont(maybeTarget(noComma));
378 return cont();
394 return cont();
379 }
395 }
380 function maybeexpression(type) {
396 function maybeexpression(type) {
@@ -425,6 +441,18 b' CodeMirror.defineMode("javascript", func'
425 findFatArrow(cx.stream, cx.state);
441 findFatArrow(cx.stream, cx.state);
426 return pass(type == "{" ? statement : expressionNoComma);
442 return pass(type == "{" ? statement : expressionNoComma);
427 }
443 }
444 function maybeTarget(noComma) {
445 return function(type) {
446 if (type == ".") return cont(noComma ? targetNoComma : target);
447 else return pass(noComma ? expressionNoComma : expression);
448 };
449 }
450 function target(_, value) {
451 if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
452 }
453 function targetNoComma(_, value) {
454 if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
455 }
428 function maybelabel(type) {
456 function maybelabel(type) {
429 if (type == ":") return cont(poplex, statement);
457 if (type == ":") return cont(poplex, statement);
430 return pass(maybeoperatorComma, expect(";"), poplex);
458 return pass(maybeoperatorComma, expect(";"), poplex);
@@ -442,8 +470,12 b' CodeMirror.defineMode("javascript", func'
442 return cont(afterprop);
470 return cont(afterprop);
443 } else if (type == "jsonld-keyword") {
471 } else if (type == "jsonld-keyword") {
444 return cont(afterprop);
472 return cont(afterprop);
473 } else if (type == "modifier") {
474 return cont(objprop)
445 } else if (type == "[") {
475 } else if (type == "[") {
446 return cont(expression, expect("]"), afterprop);
476 return cont(expression, expect("]"), afterprop);
477 } else if (type == "spread") {
478 return cont(expression);
447 }
479 }
448 }
480 }
449 function getterSetter(type) {
481 function getterSetter(type) {
@@ -492,7 +524,9 b' CodeMirror.defineMode("javascript", func'
492 return pass(pattern, maybetype, maybeAssign, vardefCont);
524 return pass(pattern, maybetype, maybeAssign, vardefCont);
493 }
525 }
494 function pattern(type, value) {
526 function pattern(type, value) {
527 if (type == "modifier") return cont(pattern)
495 if (type == "variable") { register(value); return cont(); }
528 if (type == "variable") { register(value); return cont(); }
529 if (type == "spread") return cont(pattern);
496 if (type == "[") return contCommasep(pattern, "]");
530 if (type == "[") return contCommasep(pattern, "]");
497 if (type == "{") return contCommasep(proppattern, "}");
531 if (type == "{") return contCommasep(proppattern, "}");
498 }
532 }
@@ -502,6 +536,8 b' CodeMirror.defineMode("javascript", func'
502 return cont(maybeAssign);
536 return cont(maybeAssign);
503 }
537 }
504 if (type == "variable") cx.marked = "property";
538 if (type == "variable") cx.marked = "property";
539 if (type == "spread") return cont(pattern);
540 if (type == "}") return pass();
505 return cont(expect(":"), pattern, maybeAssign);
541 return cont(expect(":"), pattern, maybeAssign);
506 }
542 }
507 function maybeAssign(_type, value) {
543 function maybeAssign(_type, value) {
@@ -572,10 +608,6 b' CodeMirror.defineMode("javascript", func'
572 cx.marked = "property";
608 cx.marked = "property";
573 return cont();
609 return cont();
574 }
610 }
575 function afterModule(type, value) {
576 if (type == "string") return cont(statement);
577 if (type == "variable") { register(value); return cont(maybeFrom); }
578 }
579 function afterExport(_type, value) {
611 function afterExport(_type, value) {
580 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
612 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
581 if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
613 if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
@@ -628,7 +660,7 b' CodeMirror.defineMode("javascript", func'
628 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
660 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
629 localVars: parserConfig.localVars,
661 localVars: parserConfig.localVars,
630 context: parserConfig.localVars && {vars: parserConfig.localVars},
662 context: parserConfig.localVars && {vars: parserConfig.localVars},
631 indented: 0
663 indented: basecolumn || 0
632 };
664 };
633 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
665 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
634 state.globalVars = parserConfig.globalVars;
666 state.globalVars = parserConfig.globalVars;
@@ -684,7 +716,13 b' CodeMirror.defineMode("javascript", func'
684
716
685 helperType: jsonMode ? "json" : "javascript",
717 helperType: jsonMode ? "json" : "javascript",
686 jsonldMode: jsonldMode,
718 jsonldMode: jsonldMode,
687 jsonMode: jsonMode
719 jsonMode: jsonMode,
720
721 expressionAllowed: expressionAllowed,
722 skipExpression: function(state) {
723 var top = state.cc[state.cc.length - 1]
724 if (top == expression || top == expressionNoComma) state.cc.pop()
725 }
688 };
726 };
689 });
727 });
690
728
@@ -18,35 +18,34 b' CodeMirror.defineMode("julia", function('
18 return new RegExp("^((" + words.join(")|(") + "))\\b");
18 return new RegExp("^((" + words.join(")|(") + "))\\b");
19 }
19 }
20
20
21 var operators = parserConf.operators || /^\.?[|&^\\%*+\-<>!=\/]=?|\?|~|:|\$|\.[<>]|<<=?|>>>?=?|\.[<>=]=|->?|\/\/|\bin\b/;
21 var operators = parserConf.operators || /^\.?[|&^\\%*+\-<>!=\/]=?|\?|~|:|\$|\.[<>]|<<=?|>>>?=?|\.[<>=]=|->?|\/\/|\bin\b(?!\()|[\u2208\u2209](?!\()/;
22 var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
22 var delimiters = parserConf.delimiters || /^[;,()[\]{}]/;
23 var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*!*/;
23 var identifiers = parserConf.identifiers || /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*!*/;
24 var blockOpeners = ["begin", "function", "type", "immutable", "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", "finally", "catch", "do"];
24 var blockOpeners = ["begin", "function", "type", "immutable", "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", "finally", "catch", "do"];
25 var blockClosers = ["end", "else", "elseif", "catch", "finally"];
25 var blockClosers = ["end", "else", "elseif", "catch", "finally"];
26 var keywordList = ['if', 'else', 'elseif', 'while', 'for', 'begin', 'let', 'end', 'do', 'try', 'catch', 'finally', 'return', 'break', 'continue', 'global', 'local', 'const', 'export', 'import', 'importall', 'using', 'function', 'macro', 'module', 'baremodule', 'type', 'immutable', 'quote', 'typealias', 'abstract', 'bitstype', 'ccall'];
26 var keywordList = ['if', 'else', 'elseif', 'while', 'for', 'begin', 'let', 'end', 'do', 'try', 'catch', 'finally', 'return', 'break', 'continue', 'global', 'local', 'const', 'export', 'import', 'importall', 'using', 'function', 'macro', 'module', 'baremodule', 'type', 'immutable', 'quote', 'typealias', 'abstract', 'bitstype'];
27 var builtinList = ['true', 'false', 'enumerate', 'open', 'close', 'nothing', 'NaN', 'Inf', 'print', 'println', 'Int', 'Int8', 'Uint8', 'Int16', 'Uint16', 'Int32', 'Uint32', 'Int64', 'Uint64', 'Int128', 'Uint128', 'Bool', 'Char', 'Float16', 'Float32', 'Float64', 'Array', 'Vector', 'Matrix', 'String', 'UTF8String', 'ASCIIString', 'error', 'warn', 'info', '@printf'];
27 var builtinList = ['true', 'false', 'nothing', 'NaN', 'Inf'];
28
28
29 //var stringPrefixes = new RegExp("^[br]?('|\")")
29 //var stringPrefixes = new RegExp("^[br]?('|\")")
30 var stringPrefixes = /^(`|'|"{3}|([br]?"))/;
30 var stringPrefixes = /^(`|'|"{3}|([brv]?"))/;
31 var keywords = wordRegexp(keywordList);
31 var keywords = wordRegexp(keywordList);
32 var builtins = wordRegexp(builtinList);
32 var builtins = wordRegexp(builtinList);
33 var openers = wordRegexp(blockOpeners);
33 var openers = wordRegexp(blockOpeners);
34 var closers = wordRegexp(blockClosers);
34 var closers = wordRegexp(blockClosers);
35 var macro = /^@[_A-Za-z][_A-Za-z0-9]*/;
35 var macro = /^@[_A-Za-z][_A-Za-z0-9]*/;
36 var symbol = /^:[_A-Za-z][_A-Za-z0-9]*/;
36 var symbol = /^:[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*!*/;
37 var typeAnnotation = /^::[^.,;"{()=$\s]+({[^}]*}+)*/;
37
38
38 function in_array(state) {
39 function inArray(state) {
39 var ch = cur_scope(state);
40 var ch = currentScope(state);
40 if(ch=="[" || ch=="{") {
41 if (ch == '[') {
41 return true;
42 return true;
42 }
43 }
43 else {
44 return false;
44 return false;
45 }
46 }
45 }
47
46
48 function cur_scope(state) {
47 function currentScope(state) {
49 if(state.scopes.length==0) {
48 if (state.scopes.length == 0) {
50 return null;
49 return null;
51 }
50 }
52 return state.scopes[state.scopes.length - 1];
51 return state.scopes[state.scopes.length - 1];
@@ -54,20 +53,34 b' CodeMirror.defineMode("julia", function('
54
53
55 // tokenizers
54 // tokenizers
56 function tokenBase(stream, state) {
55 function tokenBase(stream, state) {
56 //Handle multiline comments
57 if (stream.match(/^#=\s*/)) {
58 state.scopes.push('#=');
59 }
60 if (currentScope(state) == '#=' && stream.match(/^=#/)) {
61 state.scopes.pop();
62 return 'comment';
63 }
64 if (state.scopes.indexOf('#=') >= 0) {
65 if (!stream.match(/.*?(?=(#=|=#))/)) {
66 stream.skipToEnd();
67 }
68 return 'comment';
69 }
70
57 // Handle scope changes
71 // Handle scope changes
58 var leaving_expr = state.leaving_expr;
72 var leavingExpr = state.leavingExpr;
59 if(stream.sol()) {
73 if (stream.sol()) {
60 leaving_expr = false;
74 leavingExpr = false;
61 }
75 }
62 state.leaving_expr = false;
76 state.leavingExpr = false;
63 if(leaving_expr) {
77 if (leavingExpr) {
64 if(stream.match(/^'+/)) {
78 if (stream.match(/^'+/)) {
65 return 'operator';
79 return 'operator';
66 }
80 }
67
68 }
81 }
69
82
70 if(stream.match(/^\.{2,3}/)) {
83 if (stream.match(/^\.{2,3}/)) {
71 return 'operator';
84 return 'operator';
72 }
85 }
73
86
@@ -76,56 +89,51 b' CodeMirror.defineMode("julia", function('
76 }
89 }
77
90
78 var ch = stream.peek();
91 var ch = stream.peek();
79 // Handle Comments
92
93 // Handle single line comments
80 if (ch === '#') {
94 if (ch === '#') {
81 stream.skipToEnd();
95 stream.skipToEnd();
82 return 'comment';
96 return 'comment';
83 }
84 if(ch==='[') {
85 state.scopes.push("[");
86 }
97 }
87
98
88 if(ch==='{') {
99 if (ch === '[') {
89 state.scopes.push("{");
100 state.scopes.push('[');
90 }
101 }
91
102
92 var scope=cur_scope(state);
103 var scope = currentScope(state);
93
104
94 if(scope==='[' && ch===']') {
105 if (scope == '[' && ch === ']') {
95 state.scopes.pop();
106 state.scopes.pop();
96 state.leaving_expr=true;
107 state.leavingExpr = true;
97 }
108 }
98
109
99 if(scope==='{' && ch==='}') {
110 if (scope == '(' && ch === ')') {
100 state.scopes.pop();
111 state.scopes.pop();
101 state.leaving_expr=true;
112 state.leavingExpr = true;
102 }
103
104 if(ch===')') {
105 state.leaving_expr = true;
106 }
113 }
107
114
108 var match;
115 var match;
109 if(!in_array(state) && (match=stream.match(openers, false))) {
116 if (!inArray(state) && (match=stream.match(openers, false))) {
110 state.scopes.push(match);
117 state.scopes.push(match);
111 }
118 }
112
119
113 if(!in_array(state) && stream.match(closers, false)) {
120 if (!inArray(state) && stream.match(closers, false)) {
114 state.scopes.pop();
121 state.scopes.pop();
115 }
122 }
116
123
117 if(in_array(state)) {
124 if (inArray(state)) {
118 if(stream.match(/^end/)) {
125 if (state.lastToken == 'end' && stream.match(/^:/)) {
126 return 'operator';
127 }
128 if (stream.match(/^end/)) {
119 return 'number';
129 return 'number';
120 }
130 }
121
122 }
131 }
123
132
124 if(stream.match(/^=>/)) {
133 if (stream.match(/^=>/)) {
125 return 'operator';
134 return 'operator';
126 }
135 }
127
136
128
129 // Handle Number Literals
137 // Handle Number Literals
130 if (stream.match(/^[0-9\.]/, false)) {
138 if (stream.match(/^[0-9\.]/, false)) {
131 var imMatcher = RegExp(/^im\b/);
139 var imMatcher = RegExp(/^im\b/);
@@ -134,10 +142,11 b' CodeMirror.defineMode("julia", function('
134 if (stream.match(/^\d*\.(?!\.)\d+([ef][\+\-]?\d+)?/i)) { floatLiteral = true; }
142 if (stream.match(/^\d*\.(?!\.)\d+([ef][\+\-]?\d+)?/i)) { floatLiteral = true; }
135 if (stream.match(/^\d+\.(?!\.)\d*/)) { floatLiteral = true; }
143 if (stream.match(/^\d+\.(?!\.)\d*/)) { floatLiteral = true; }
136 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
144 if (stream.match(/^\.\d+/)) { floatLiteral = true; }
145 if (stream.match(/^0x\.[0-9a-f]+p[\+\-]?\d+/i)) { floatLiteral = true; }
137 if (floatLiteral) {
146 if (floatLiteral) {
138 // Float literals may be "imaginary"
147 // Float literals may be "imaginary"
139 stream.match(imMatcher);
148 stream.match(imMatcher);
140 state.leaving_expr = true;
149 state.leavingExpr = true;
141 return 'number';
150 return 'number';
142 }
151 }
143 // Integers
152 // Integers
@@ -157,18 +166,27 b' CodeMirror.defineMode("julia", function('
157 if (intLiteral) {
166 if (intLiteral) {
158 // Integer literals may be "long"
167 // Integer literals may be "long"
159 stream.match(imMatcher);
168 stream.match(imMatcher);
160 state.leaving_expr = true;
169 state.leavingExpr = true;
161 return 'number';
170 return 'number';
162 }
171 }
163 }
172 }
164
173
165 if(stream.match(/^(::)|(<:)/)) {
174 if (stream.match(/^<:/)) {
166 return 'operator';
175 return 'operator';
167 }
176 }
168
177
178 if (stream.match(typeAnnotation)) {
179 return 'builtin';
180 }
181
169 // Handle symbols
182 // Handle symbols
170 if(!leaving_expr && stream.match(symbol)) {
183 if (!leavingExpr && stream.match(symbol) || stream.match(/:\./)) {
171 return 'string';
184 return 'builtin';
185 }
186
187 // Handle parametric types
188 if (stream.match(/^{[^}]*}(?=\()/)) {
189 return 'builtin';
172 }
190 }
173
191
174 // Handle operators and Delimiters
192 // Handle operators and Delimiters
@@ -176,7 +194,6 b' CodeMirror.defineMode("julia", function('
176 return 'operator';
194 return 'operator';
177 }
195 }
178
196
179
180 // Handle Strings
197 // Handle Strings
181 if (stream.match(stringPrefixes)) {
198 if (stream.match(stringPrefixes)) {
182 state.tokenize = tokenStringFactory(stream.current());
199 state.tokenize = tokenStringFactory(stream.current());
@@ -187,7 +204,6 b' CodeMirror.defineMode("julia", function('
187 return 'meta';
204 return 'meta';
188 }
205 }
189
206
190
191 if (stream.match(delimiters)) {
207 if (stream.match(delimiters)) {
192 return null;
208 return null;
193 }
209 }
@@ -200,21 +216,74 b' CodeMirror.defineMode("julia", function('
200 return 'builtin';
216 return 'builtin';
201 }
217 }
202
218
219 var isDefinition = state.isDefinition ||
220 state.lastToken == 'function' ||
221 state.lastToken == 'macro' ||
222 state.lastToken == 'type' ||
223 state.lastToken == 'immutable';
203
224
204 if (stream.match(identifiers)) {
225 if (stream.match(identifiers)) {
205 state.leaving_expr=true;
226 if (isDefinition) {
227 if (stream.peek() === '.') {
228 state.isDefinition = true;
229 return 'variable';
230 }
231 state.isDefinition = false;
232 return 'def';
233 }
234 if (stream.match(/^({[^}]*})*\(/, false)) {
235 return callOrDef(stream, state);
236 }
237 state.leavingExpr = true;
206 return 'variable';
238 return 'variable';
207 }
239 }
240
208 // Handle non-detected items
241 // Handle non-detected items
209 stream.next();
242 stream.next();
210 return ERRORCLASS;
243 return ERRORCLASS;
211 }
244 }
212
245
246 function callOrDef(stream, state) {
247 var match = stream.match(/^(\(\s*)/);
248 if (match) {
249 if (state.firstParenPos < 0)
250 state.firstParenPos = state.scopes.length;
251 state.scopes.push('(');
252 state.charsAdvanced += match[1].length;
253 }
254 if (currentScope(state) == '(' && stream.match(/^\)/)) {
255 state.scopes.pop();
256 state.charsAdvanced += 1;
257 if (state.scopes.length <= state.firstParenPos) {
258 var isDefinition = stream.match(/^\s*?=(?!=)/, false);
259 stream.backUp(state.charsAdvanced);
260 state.firstParenPos = -1;
261 state.charsAdvanced = 0;
262 if (isDefinition)
263 return 'def';
264 return 'builtin';
265 }
266 }
267 // Unfortunately javascript does not support multiline strings, so we have
268 // to undo anything done upto here if a function call or definition splits
269 // over two or more lines.
270 if (stream.match(/^$/g, false)) {
271 stream.backUp(state.charsAdvanced);
272 while (state.scopes.length > state.firstParenPos + 1)
273 state.scopes.pop();
274 state.firstParenPos = -1;
275 state.charsAdvanced = 0;
276 return 'builtin';
277 }
278 state.charsAdvanced += stream.match(/^([^()]*)/)[1].length;
279 return callOrDef(stream, state);
280 }
281
213 function tokenStringFactory(delimiter) {
282 function tokenStringFactory(delimiter) {
214 while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
283 while ('bruv'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
215 delimiter = delimiter.substr(1);
284 delimiter = delimiter.substr(1);
216 }
285 }
217 var singleline = delimiter.length == 1;
286 var singleline = delimiter == "'";
218 var OUTCLASS = 'string';
287 var OUTCLASS = 'string';
219
288
220 function tokenString(stream, state) {
289 function tokenString(stream, state) {
@@ -245,45 +314,41 b' CodeMirror.defineMode("julia", function('
245 return tokenString;
314 return tokenString;
246 }
315 }
247
316
248 function tokenLexer(stream, state) {
249 var style = state.tokenize(stream, state);
250 var current = stream.current();
251
252 // Handle '.' connected identifiers
253 if (current === '.') {
254 style = stream.match(identifiers, false) ? null : ERRORCLASS;
255 if (style === null && state.lastStyle === 'meta') {
256 // Apply 'meta' style to '.' connected identifiers when
257 // appropriate.
258 style = 'meta';
259 }
260 return style;
261 }
262
263 return style;
264 }
265
266 var external = {
317 var external = {
267 startState: function() {
318 startState: function() {
268 return {
319 return {
269 tokenize: tokenBase,
320 tokenize: tokenBase,
270 scopes: [],
321 scopes: [],
271 leaving_expr: false
322 lastToken: null,
323 leavingExpr: false,
324 isDefinition: false,
325 charsAdvanced: 0,
326 firstParenPos: -1
272 };
327 };
273 },
328 },
274
329
275 token: function(stream, state) {
330 token: function(stream, state) {
276 var style = tokenLexer(stream, state);
331 var style = state.tokenize(stream, state);
277 state.lastStyle = style;
332 var current = stream.current();
333
334 if (current && style) {
335 state.lastToken = current;
336 }
337
338 // Handle '.' connected identifiers
339 if (current === '.') {
340 style = stream.match(identifiers, false) || stream.match(macro, false) ||
341 stream.match(/\(/, false) ? 'operator' : ERRORCLASS;
342 }
278 return style;
343 return style;
279 },
344 },
280
345
281 indent: function(state, textAfter) {
346 indent: function(state, textAfter) {
282 var delta = 0;
347 var delta = 0;
283 if(textAfter=="end" || textAfter=="]" || textAfter=="}" || textAfter=="else" || textAfter=="elseif" || textAfter=="catch" || textAfter=="finally") {
348 if (textAfter == "end" || textAfter == "]" || textAfter == "}" || textAfter == "else" || textAfter == "elseif" || textAfter == "catch" || textAfter == "finally") {
284 delta = -1;
349 delta = -1;
285 }
350 }
286 return (state.scopes.length + delta) * 4;
351 return (state.scopes.length + delta) * _conf.indentUnit;
287 },
352 },
288
353
289 lineComment: "#",
354 lineComment: "#",
@@ -39,8 +39,10 b' CodeMirror.defineMode("markdown", functi'
39 if (modeCfg.underscoresBreakWords === undefined)
39 if (modeCfg.underscoresBreakWords === undefined)
40 modeCfg.underscoresBreakWords = true;
40 modeCfg.underscoresBreakWords = true;
41
41
42 // Turn on fenced code blocks? ("```" to start/end)
42 // Use `fencedCodeBlocks` to configure fenced code blocks. false to
43 if (modeCfg.fencedCodeBlocks === undefined) modeCfg.fencedCodeBlocks = false;
43 // disable, string to specify a precise regexp that the fence should
44 // match, and true to allow three or more backticks or tildes (as
45 // per CommonMark).
44
46
45 // Turn on task lists? ("- [ ] " and "- [x] ")
47 // Turn on task lists? ("- [ ] " and "- [x] ")
46 if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
48 if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
@@ -49,32 +51,46 b' CodeMirror.defineMode("markdown", functi'
49 if (modeCfg.strikethrough === undefined)
51 if (modeCfg.strikethrough === undefined)
50 modeCfg.strikethrough = false;
52 modeCfg.strikethrough = false;
51
53
54 // Allow token types to be overridden by user-provided token types.
55 if (modeCfg.tokenTypeOverrides === undefined)
56 modeCfg.tokenTypeOverrides = {};
57
52 var codeDepth = 0;
58 var codeDepth = 0;
53
59
54 var header = 'header'
60 var tokenTypes = {
55 , code = 'comment'
61 header: "header",
56 , quote = 'quote'
62 code: "comment",
57 , list1 = 'variable-2'
63 quote: "quote",
58 , list2 = 'variable-3'
64 list1: "variable-2",
59 , list3 = 'keyword'
65 list2: "variable-3",
60 , hr = 'hr'
66 list3: "keyword",
61 , image = 'tag'
67 hr: "hr",
62 , formatting = 'formatting'
68 image: "tag",
63 , linkinline = 'link'
69 formatting: "formatting",
64 , linkemail = 'link'
70 linkInline: "link",
65 , linktext = 'link'
71 linkEmail: "link",
66 , linkhref = 'string'
72 linkText: "link",
67 , em = 'em'
73 linkHref: "string",
68 , strong = 'strong'
74 em: "em",
69 , strikethrough = 'strikethrough';
75 strong: "strong",
76 strikethrough: "strikethrough"
77 };
78
79 for (var tokenType in tokenTypes) {
80 if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) {
81 tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType];
82 }
83 }
70
84
71 var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
85 var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
72 , ulRE = /^[*\-+]\s+/
86 , ulRE = /^[*\-+]\s+/
73 , olRE = /^[0-9]+([.)])\s+/
87 , olRE = /^[0-9]+([.)])\s+/
74 , taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
88 , taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
75 , atxHeaderRE = /^(#+)(?: |$)/
89 , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
76 , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
90 , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
77 , textRE = /^[^#!\[\]*_\\<>` "'(~]+/;
91 , textRE = /^[^#!\[\]*_\\<>` "'(~]+/
92 , fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
93 ")[ \\t]*([\\w+#]*)");
78
94
79 function switchInline(stream, state, f) {
95 function switchInline(stream, state, f) {
80 state.f = state.inline = f;
96 state.f = state.inline = f;
@@ -86,6 +102,9 b' CodeMirror.defineMode("markdown", functi'
86 return f(stream, state);
102 return f(stream, state);
87 }
103 }
88
104
105 function lineIsEmpty(line) {
106 return !line || !/\S/.test(line.string)
107 }
89
108
90 // Blocks
109 // Blocks
91
110
@@ -110,7 +129,8 b' CodeMirror.defineMode("markdown", functi'
110 state.trailingSpace = 0;
129 state.trailingSpace = 0;
111 state.trailingSpaceNewLine = false;
130 state.trailingSpaceNewLine = false;
112 // Mark this line as blank
131 // Mark this line as blank
113 state.thisLineHasContent = false;
132 state.prevLine = state.thisLine
133 state.thisLine = null
114 return null;
134 return null;
115 }
135 }
116
136
@@ -141,10 +161,10 b' CodeMirror.defineMode("markdown", functi'
141 var match = null;
161 var match = null;
142 if (state.indentationDiff >= 4) {
162 if (state.indentationDiff >= 4) {
143 stream.skipToEnd();
163 stream.skipToEnd();
144 if (prevLineIsIndentedCode || !state.prevLineHasContent) {
164 if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
145 state.indentation -= 4;
165 state.indentation -= 4;
146 state.indentedCode = true;
166 state.indentedCode = true;
147 return code;
167 return tokenTypes.code;
148 } else {
168 } else {
149 return null;
169 return null;
150 }
170 }
@@ -155,7 +175,8 b' CodeMirror.defineMode("markdown", functi'
155 if (modeCfg.highlightFormatting) state.formatting = "header";
175 if (modeCfg.highlightFormatting) state.formatting = "header";
156 state.f = state.inline;
176 state.f = state.inline;
157 return getType(state);
177 return getType(state);
158 } else if (state.prevLineHasContent && !state.quote && !prevLineIsList && !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
178 } else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList &&
179 !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
159 state.header = match[0].charAt(0) == '=' ? 1 : 2;
180 state.header = match[0].charAt(0) == '=' ? 1 : 2;
160 if (modeCfg.highlightFormatting) state.formatting = "header";
181 if (modeCfg.highlightFormatting) state.formatting = "header";
161 state.f = state.inline;
182 state.f = state.inline;
@@ -169,8 +190,8 b' CodeMirror.defineMode("markdown", functi'
169 return switchInline(stream, state, footnoteLink);
190 return switchInline(stream, state, footnoteLink);
170 } else if (stream.match(hrRE, true)) {
191 } else if (stream.match(hrRE, true)) {
171 state.hr = true;
192 state.hr = true;
172 return hr;
193 return tokenTypes.hr;
173 } else if ((!state.prevLineHasContent || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
194 } else if ((lineIsEmpty(state.prevLine) || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
174 var listType = null;
195 var listType = null;
175 if (stream.match(ulRE, true)) {
196 if (stream.match(ulRE, true)) {
176 listType = 'ul';
197 listType = 'ul';
@@ -178,7 +199,7 b' CodeMirror.defineMode("markdown", functi'
178 stream.match(olRE, true);
199 stream.match(olRE, true);
179 listType = 'ol';
200 listType = 'ol';
180 }
201 }
181 state.indentation += 4;
202 state.indentation = stream.column() + stream.current().length;
182 state.list = true;
203 state.list = true;
183 state.listDepth++;
204 state.listDepth++;
184 if (modeCfg.taskLists && stream.match(taskListRE, false)) {
205 if (modeCfg.taskLists && stream.match(taskListRE, false)) {
@@ -187,9 +208,10 b' CodeMirror.defineMode("markdown", functi'
187 state.f = state.inline;
208 state.f = state.inline;
188 if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
209 if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
189 return getType(state);
210 return getType(state);
190 } else if (modeCfg.fencedCodeBlocks && stream.match(/^```[ \t]*([\w+#]*)/, true)) {
211 } else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) {
212 state.fencedChars = match[1]
191 // try switching mode
213 // try switching mode
192 state.localMode = getMode(RegExp.$1);
214 state.localMode = getMode(match[2]);
193 if (state.localMode) state.localState = state.localMode.startState();
215 if (state.localMode) state.localState = state.localMode.startState();
194 state.f = state.block = local;
216 state.f = state.block = local;
195 if (modeCfg.highlightFormatting) state.formatting = "code-block";
217 if (modeCfg.highlightFormatting) state.formatting = "code-block";
@@ -202,7 +224,8 b' CodeMirror.defineMode("markdown", functi'
202
224
203 function htmlBlock(stream, state) {
225 function htmlBlock(stream, state) {
204 var style = htmlMode.token(stream, state.htmlState);
226 var style = htmlMode.token(stream, state.htmlState);
205 if ((htmlFound && state.htmlState.tagStart === null && !state.htmlState.context) ||
227 if ((htmlFound && state.htmlState.tagStart === null &&
228 (!state.htmlState.context && state.htmlState.tokenize.isInText)) ||
206 (state.md_inside && stream.current().indexOf(">") > -1)) {
229 (state.md_inside && stream.current().indexOf(">") > -1)) {
207 state.f = inlineNormal;
230 state.f = inlineNormal;
208 state.block = blockNormal;
231 state.block = blockNormal;
@@ -212,7 +235,7 b' CodeMirror.defineMode("markdown", functi'
212 }
235 }
213
236
214 function local(stream, state) {
237 function local(stream, state) {
215 if (stream.sol() && stream.match("```", false)) {
238 if (state.fencedChars && stream.match(state.fencedChars, false)) {
216 state.localMode = state.localState = null;
239 state.localMode = state.localState = null;
217 state.f = state.block = leavingLocal;
240 state.f = state.block = leavingLocal;
218 return null;
241 return null;
@@ -220,14 +243,15 b' CodeMirror.defineMode("markdown", functi'
220 return state.localMode.token(stream, state.localState);
243 return state.localMode.token(stream, state.localState);
221 } else {
244 } else {
222 stream.skipToEnd();
245 stream.skipToEnd();
223 return code;
246 return tokenTypes.code;
224 }
247 }
225 }
248 }
226
249
227 function leavingLocal(stream, state) {
250 function leavingLocal(stream, state) {
228 stream.match("```");
251 stream.match(state.fencedChars);
229 state.block = blockNormal;
252 state.block = blockNormal;
230 state.f = inlineNormal;
253 state.f = inlineNormal;
254 state.fencedChars = null;
231 if (modeCfg.highlightFormatting) state.formatting = "code-block";
255 if (modeCfg.highlightFormatting) state.formatting = "code-block";
232 state.code = true;
256 state.code = true;
233 var returnType = getType(state);
257 var returnType = getType(state);
@@ -240,22 +264,22 b' CodeMirror.defineMode("markdown", functi'
240 var styles = [];
264 var styles = [];
241
265
242 if (state.formatting) {
266 if (state.formatting) {
243 styles.push(formatting);
267 styles.push(tokenTypes.formatting);
244
268
245 if (typeof state.formatting === "string") state.formatting = [state.formatting];
269 if (typeof state.formatting === "string") state.formatting = [state.formatting];
246
270
247 for (var i = 0; i < state.formatting.length; i++) {
271 for (var i = 0; i < state.formatting.length; i++) {
248 styles.push(formatting + "-" + state.formatting[i]);
272 styles.push(tokenTypes.formatting + "-" + state.formatting[i]);
249
273
250 if (state.formatting[i] === "header") {
274 if (state.formatting[i] === "header") {
251 styles.push(formatting + "-" + state.formatting[i] + "-" + state.header);
275 styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header);
252 }
276 }
253
277
254 // Add `formatting-quote` and `formatting-quote-#` for blockquotes
278 // Add `formatting-quote` and `formatting-quote-#` for blockquotes
255 // Add `error` instead if the maximum blockquote nesting depth is passed
279 // Add `error` instead if the maximum blockquote nesting depth is passed
256 if (state.formatting[i] === "quote") {
280 if (state.formatting[i] === "quote") {
257 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
281 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
258 styles.push(formatting + "-" + state.formatting[i] + "-" + state.quote);
282 styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote);
259 } else {
283 } else {
260 styles.push("error");
284 styles.push("error");
261 }
285 }
@@ -273,38 +297,36 b' CodeMirror.defineMode("markdown", functi'
273 }
297 }
274
298
275 if (state.linkHref) {
299 if (state.linkHref) {
276 styles.push(linkhref, "url");
300 styles.push(tokenTypes.linkHref, "url");
277 } else { // Only apply inline styles to non-url text
301 } else { // Only apply inline styles to non-url text
278 if (state.strong) { styles.push(strong); }
302 if (state.strong) { styles.push(tokenTypes.strong); }
279 if (state.em) { styles.push(em); }
303 if (state.em) { styles.push(tokenTypes.em); }
280 if (state.strikethrough) { styles.push(strikethrough); }
304 if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
281
305 if (state.linkText) { styles.push(tokenTypes.linkText); }
282 if (state.linkText) { styles.push(linktext); }
306 if (state.code) { styles.push(tokenTypes.code); }
283
284 if (state.code) { styles.push(code); }
285 }
307 }
286
308
287 if (state.header) { styles.push(header); styles.push(header + "-" + state.header); }
309 if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
288
310
289 if (state.quote) {
311 if (state.quote) {
290 styles.push(quote);
312 styles.push(tokenTypes.quote);
291
313
292 // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
314 // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
293 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
315 if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
294 styles.push(quote + "-" + state.quote);
316 styles.push(tokenTypes.quote + "-" + state.quote);
295 } else {
317 } else {
296 styles.push(quote + "-" + modeCfg.maxBlockquoteDepth);
318 styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
297 }
319 }
298 }
320 }
299
321
300 if (state.list !== false) {
322 if (state.list !== false) {
301 var listMod = (state.listDepth - 1) % 3;
323 var listMod = (state.listDepth - 1) % 3;
302 if (!listMod) {
324 if (!listMod) {
303 styles.push(list1);
325 styles.push(tokenTypes.list1);
304 } else if (listMod === 1) {
326 } else if (listMod === 1) {
305 styles.push(list2);
327 styles.push(tokenTypes.list2);
306 } else {
328 } else {
307 styles.push(list3);
329 styles.push(tokenTypes.list3);
308 }
330 }
309 }
331 }
310
332
@@ -360,7 +382,8 b' CodeMirror.defineMode("markdown", functi'
360 stream.next();
382 stream.next();
361 if (modeCfg.highlightFormatting) {
383 if (modeCfg.highlightFormatting) {
362 var type = getType(state);
384 var type = getType(state);
363 return type ? type + " formatting-escape" : "formatting-escape";
385 var formattingEscape = tokenTypes.formatting + "-escape";
386 return type ? type + " " + formattingEscape : formattingEscape;
364 }
387 }
365 }
388 }
366
389
@@ -374,7 +397,7 b' CodeMirror.defineMode("markdown", functi'
374 matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
397 matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
375 var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
398 var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
376 if (stream.match(new RegExp(regex), true)) {
399 if (stream.match(new RegExp(regex), true)) {
377 return linkhref;
400 return tokenTypes.linkHref;
378 }
401 }
379 }
402 }
380
403
@@ -405,7 +428,7 b' CodeMirror.defineMode("markdown", functi'
405 if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
428 if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
406 stream.match(/\[[^\]]*\]/);
429 stream.match(/\[[^\]]*\]/);
407 state.inline = state.f = linkHref;
430 state.inline = state.f = linkHref;
408 return image;
431 return tokenTypes.image;
409 }
432 }
410
433
411 if (ch === '[' && stream.match(/.*\](\(.*\)| ?\[.*\])/, false)) {
434 if (ch === '[' && stream.match(/.*\](\(.*\)| ?\[.*\])/, false)) {
@@ -431,7 +454,7 b' CodeMirror.defineMode("markdown", functi'
431 } else {
454 } else {
432 type = "";
455 type = "";
433 }
456 }
434 return type + linkinline;
457 return type + tokenTypes.linkInline;
435 }
458 }
436
459
437 if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
460 if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
@@ -443,15 +466,14 b' CodeMirror.defineMode("markdown", functi'
443 } else {
466 } else {
444 type = "";
467 type = "";
445 }
468 }
446 return type + linkemail;
469 return type + tokenTypes.linkEmail;
447 }
470 }
448
471
449 if (ch === '<' && stream.match(/^\w/, false)) {
472 if (ch === '<' && stream.match(/^(!--|\w)/, false)) {
450 if (stream.string.indexOf(">") != -1) {
473 var end = stream.string.indexOf(">", stream.pos);
451 var atts = stream.string.substring(1,stream.string.indexOf(">"));
474 if (end != -1) {
452 if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) {
475 var atts = stream.string.substring(stream.start, end);
453 state.md_inside = true;
476 if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true;
454 }
455 }
477 }
456 stream.backUp(1);
478 stream.backUp(1);
457 state.htmlState = CodeMirror.startState(htmlMode);
479 state.htmlState = CodeMirror.startState(htmlMode);
@@ -553,12 +575,12 b' CodeMirror.defineMode("markdown", functi'
553 } else {
575 } else {
554 type = "";
576 type = "";
555 }
577 }
556 return type + linkinline;
578 return type + tokenTypes.linkInline;
557 }
579 }
558
580
559 stream.match(/^[^>]+/, true);
581 stream.match(/^[^>]+/, true);
560
582
561 return linkinline;
583 return tokenTypes.linkInline;
562 }
584 }
563
585
564 function linkHref(stream, state) {
586 function linkHref(stream, state) {
@@ -598,7 +620,7 b' CodeMirror.defineMode("markdown", functi'
598 }
620 }
599
621
600 function footnoteLink(stream, state) {
622 function footnoteLink(stream, state) {
601 if (stream.match(/^[^\]]*\]:/, false)) {
623 if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) {
602 state.f = footnoteLinkInside;
624 state.f = footnoteLinkInside;
603 stream.next(); // Consume [
625 stream.next(); // Consume [
604 if (modeCfg.highlightFormatting) state.formatting = "link";
626 if (modeCfg.highlightFormatting) state.formatting = "link";
@@ -617,9 +639,9 b' CodeMirror.defineMode("markdown", functi'
617 return returnType;
639 return returnType;
618 }
640 }
619
641
620 stream.match(/^[^\]]+/, true);
642 stream.match(/^([^\]\\]|\\.)+/, true);
621
643
622 return linktext;
644 return tokenTypes.linkText;
623 }
645 }
624
646
625 function footnoteUrl(stream, state) {
647 function footnoteUrl(stream, state) {
@@ -636,7 +658,7 b' CodeMirror.defineMode("markdown", functi'
636 stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
658 stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
637 }
659 }
638 state.f = state.inline = inlineNormal;
660 state.f = state.inline = inlineNormal;
639 return linkhref + " url";
661 return tokenTypes.linkHref + " url";
640 }
662 }
641
663
642 var savedInlineRE = [];
664 var savedInlineRE = [];
@@ -656,8 +678,8 b' CodeMirror.defineMode("markdown", functi'
656 return {
678 return {
657 f: blockNormal,
679 f: blockNormal,
658
680
659 prevLineHasContent: false,
681 prevLine: null,
660 thisLineHasContent: false,
682 thisLine: null,
661
683
662 block: blockNormal,
684 block: blockNormal,
663 htmlState: null,
685 htmlState: null,
@@ -680,7 +702,8 b' CodeMirror.defineMode("markdown", functi'
680 quote: 0,
702 quote: 0,
681 trailingSpace: 0,
703 trailingSpace: 0,
682 trailingSpaceNewLine: false,
704 trailingSpaceNewLine: false,
683 strikethrough: false
705 strikethrough: false,
706 fencedChars: null
684 };
707 };
685 },
708 },
686
709
@@ -688,8 +711,8 b' CodeMirror.defineMode("markdown", functi'
688 return {
711 return {
689 f: s.f,
712 f: s.f,
690
713
691 prevLineHasContent: s.prevLineHasContent,
714 prevLine: s.prevLine,
692 thisLineHasContent: s.thisLineHasContent,
715 thisLine: s.thisLine,
693
716
694 block: s.block,
717 block: s.block,
695 htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
718 htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
@@ -702,6 +725,7 b' CodeMirror.defineMode("markdown", functi'
702 text: s.text,
725 text: s.text,
703 formatting: false,
726 formatting: false,
704 linkTitle: s.linkTitle,
727 linkTitle: s.linkTitle,
728 code: s.code,
705 em: s.em,
729 em: s.em,
706 strong: s.strong,
730 strong: s.strong,
707 strikethrough: s.strikethrough,
731 strikethrough: s.strikethrough,
@@ -714,7 +738,8 b' CodeMirror.defineMode("markdown", functi'
714 indentedCode: s.indentedCode,
738 indentedCode: s.indentedCode,
715 trailingSpace: s.trailingSpace,
739 trailingSpace: s.trailingSpace,
716 trailingSpaceNewLine: s.trailingSpaceNewLine,
740 trailingSpaceNewLine: s.trailingSpaceNewLine,
717 md_inside: s.md_inside
741 md_inside: s.md_inside,
742 fencedChars: s.fencedChars
718 };
743 };
719 },
744 },
720
745
@@ -723,28 +748,25 b' CodeMirror.defineMode("markdown", functi'
723 // Reset state.formatting
748 // Reset state.formatting
724 state.formatting = false;
749 state.formatting = false;
725
750
726 if (stream.sol()) {
751 if (stream != state.thisLine) {
727 var forceBlankLine = !!state.header || state.hr;
752 var forceBlankLine = state.header || state.hr;
728
753
729 // Reset state.header and state.hr
754 // Reset state.header and state.hr
730 state.header = 0;
755 state.header = 0;
731 state.hr = false;
756 state.hr = false;
732
757
733 if (stream.match(/^\s*$/, true) || forceBlankLine) {
758 if (stream.match(/^\s*$/, true) || forceBlankLine) {
734 state.prevLineHasContent = false;
735 blankLine(state);
759 blankLine(state);
736 return forceBlankLine ? this.token(stream, state) : null;
760 if (!forceBlankLine) return null
737 } else {
761 state.prevLine = null
738 state.prevLineHasContent = state.thisLineHasContent;
739 state.thisLineHasContent = true;
740 }
762 }
741
763
764 state.prevLine = state.thisLine
765 state.thisLine = stream
766
742 // Reset state.taskList
767 // Reset state.taskList
743 state.taskList = false;
768 state.taskList = false;
744
769
745 // Reset state.code
746 state.code = false;
747
748 // Reset state.trailingSpace
770 // Reset state.trailingSpace
749 state.trailingSpace = 0;
771 state.trailingSpace = 0;
750 state.trailingSpaceNewLine = false;
772 state.trailingSpaceNewLine = false;
@@ -14,18 +14,22 b''
14 CodeMirror.modeInfo = [
14 CodeMirror.modeInfo = [
15 {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
15 {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
16 {name: "PGP", mimes: ["application/pgp", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["pgp"]},
16 {name: "PGP", mimes: ["application/pgp", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["pgp"]},
17 {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn, asn1"]},
17 {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]},
18 {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i},
18 {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i},
19 {name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]},
19 {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]},
20 {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h"]},
20 {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]},
21 {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]},
21 {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]},
22 {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy"]},
22 {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]},
23 {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp"]},
23 {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj"]},
24 {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj"]},
25 {name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]},
26 {name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]},
24 {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/},
27 {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists.txt$/},
25 {name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
28 {name: "CoffeeScript", mime: "text/x-coffeescript", mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
26 {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]},
29 {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]},
27 {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]},
30 {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]},
28 {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]},
31 {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]},
32 {name: "Crystal", mime: "text/x-crystal", mode: "crystal", ext: ["cr"]},
29 {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]},
33 {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]},
30 {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]},
34 {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]},
31 {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]},
35 {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]},
@@ -53,6 +57,7 b''
53 {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy"]},
57 {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy"]},
54 {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
58 {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
55 {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]},
59 {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]},
60 {name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]},
56 {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]},
61 {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]},
57 {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]},
62 {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]},
58 {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]},
63 {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]},
@@ -66,9 +71,10 b''
66 mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]},
71 mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]},
67 {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]},
72 {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]},
68 {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]},
73 {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]},
74 {name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]},
69 {name: "Jinja2", mime: "null", mode: "jinja2"},
75 {name: "Jinja2", mime: "null", mode: "jinja2"},
70 {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]},
76 {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"]},
71 {name: "Kotlin", mime: "text/x-kotlin", mode: "kotlin", ext: ["kt"]},
77 {name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]},
72 {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
78 {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
73 {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]},
79 {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]},
74 {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]},
80 {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]},
@@ -81,10 +87,12 b''
81 {name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
87 {name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
82 {name: "MySQL", mime: "text/x-mysql", mode: "sql"},
88 {name: "MySQL", mime: "text/x-mysql", mode: "sql"},
83 {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i},
89 {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i},
90 {name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]},
84 {name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]},
91 {name: "NTriples", mime: "text/n-triples", mode: "ntriples", ext: ["nt"]},
85 {name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"]},
92 {name: "Objective C", mime: "text/x-objectivec", mode: "clike", ext: ["m", "mm"]},
86 {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
93 {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
87 {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
94 {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
95 {name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]},
88 {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]},
96 {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]},
89 {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]},
97 {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]},
90 {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]},
98 {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]},
@@ -106,7 +114,7 b''
106 {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
114 {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
107 {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
115 {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
108 {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]},
116 {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]},
109 {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"]},
117 {name: "Shell", mime: "text/x-sh", mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/},
110 {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]},
118 {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]},
111 {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
119 {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
112 {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
120 {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
@@ -116,6 +124,7 b''
116 {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
124 {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
117 {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
125 {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
118 {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
126 {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
127 {name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]},
119 {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]},
128 {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]},
120 {name: "MariaDB", mime: "text/x-mariadb", mode: "sql"},
129 {name: "MariaDB", mime: "text/x-mariadb", mode: "sql"},
121 {name: "sTeX", mime: "text/x-stex", mode: "stex"},
130 {name: "sTeX", mime: "text/x-stex", mode: "stex"},
@@ -137,10 +146,14 b''
137 {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]},
146 {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]},
138 {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]},
147 {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]},
139 {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
148 {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
149 {name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]},
140 {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], alias: ["rss", "wsdl", "xsd"]},
150 {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd"], alias: ["rss", "wsdl", "xsd"]},
141 {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
151 {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
142 {name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
152 {name: "YAML", mime: "text/x-yaml", mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
143 {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]}
153 {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]},
154 {name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]},
155 {name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]},
156 {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]}
144 ];
157 ];
145 // Ensure all modes have a mime property for backwards compatibility
158 // Ensure all modes have a mime property for backwards compatibility
146 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
159 for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
@@ -113,7 +113,7 b' MIME_TO_EXT = {'
113 "text/x-fortran": {"exts": ["*.f","*.f90","*.F","*.F90","*.for","*.f77"], "mode": "fortran"},
113 "text/x-fortran": {"exts": ["*.f","*.f90","*.F","*.F90","*.for","*.f77"], "mode": "fortran"},
114 "text/x-fsharp": {"exts": ["*.fs","*.fsi"], "mode": "mllike"},
114 "text/x-fsharp": {"exts": ["*.fs","*.fsi"], "mode": "mllike"},
115 "text/x-gas": {"exts": ["*.s","*.S"], "mode": "gas"},
115 "text/x-gas": {"exts": ["*.s","*.S"], "mode": "gas"},
116 "text/x-gfm": {"exts": ["*.md","*.MD"], "mode": "markdown"},
116 "text/x-gfm": {"exts": ["*.md","*.MD"], "mode": "gfm"},
117 "text/x-gherkin": {"exts": ["*.feature"], "mode": ""},
117 "text/x-gherkin": {"exts": ["*.feature"], "mode": ""},
118 "text/x-glslsrc": {"exts": ["*.vert","*.frag","*.geo"], "mode": ""},
118 "text/x-glslsrc": {"exts": ["*.vert","*.frag","*.geo"], "mode": ""},
119 "text/x-gnuplot": {"exts": ["*.plot","*.plt"], "mode": ""},
119 "text/x-gnuplot": {"exts": ["*.plot","*.plt"], "mode": ""},
@@ -137,11 +137,11 b' MIME_TO_EXT = {'
137 "text/x-julia": {"exts": ["*.jl"], "mode": "julia"},
137 "text/x-julia": {"exts": ["*.jl"], "mode": "julia"},
138 "text/x-kconfig": {"exts": ["Kconfig","*Config.in*","external.in*","standard-modules.in"], "mode": ""},
138 "text/x-kconfig": {"exts": ["Kconfig","*Config.in*","external.in*","standard-modules.in"], "mode": ""},
139 "text/x-koka": {"exts": ["*.kk","*.kki"], "mode": ""},
139 "text/x-koka": {"exts": ["*.kk","*.kki"], "mode": ""},
140 "text/x-kotlin": {"exts": ["*.kt"], "mode": "kotlin"},
140 "text/x-kotlin": {"exts": ["*.kt"], "mode": "clike"},
141 "text/x-lasso": {"exts": ["*.lasso","*.lasso[89]"], "mode": ""},
141 "text/x-lasso": {"exts": ["*.lasso","*.lasso[89]"], "mode": ""},
142 "text/x-latex": {"exts": ["*.ltx","*.text"], "mode": "stex"},
142 "text/x-latex": {"exts": ["*.ltx","*.text"], "mode": "stex"},
143 "text/x-less": {"exts": ["*.less"], "mode": "css"},
143 "text/x-less": {"exts": ["*.less"], "mode": "css"},
144 "text/x-literate-haskell": {"exts": ["*.lhs"], "mode": ""},
144 "text/x-literate-haskell": {"exts": ["*.lhs"], "mode": "haskell-literate"},
145 "text/x-livescript": {"exts": ["*.ls"], "mode": "livescript"},
145 "text/x-livescript": {"exts": ["*.ls"], "mode": "livescript"},
146 "text/x-llvm": {"exts": ["*.ll"], "mode": ""},
146 "text/x-llvm": {"exts": ["*.ll"], "mode": ""},
147 "text/x-logos": {"exts": ["*.x","*.xi","*.xm","*.xmi"], "mode": ""},
147 "text/x-logos": {"exts": ["*.x","*.xi","*.xm","*.xmi"], "mode": ""},
@@ -162,7 +162,7 b' MIME_TO_EXT = {'
162 "text/x-newspeak": {"exts": ["*.ns2"], "mode": ""},
162 "text/x-newspeak": {"exts": ["*.ns2"], "mode": ""},
163 "text/x-nginx-conf": {"exts": ["*.conf"], "mode": "nginx"},
163 "text/x-nginx-conf": {"exts": ["*.conf"], "mode": "nginx"},
164 "text/x-nimrod": {"exts": ["*.nim","*.nimrod"], "mode": ""},
164 "text/x-nimrod": {"exts": ["*.nim","*.nimrod"], "mode": ""},
165 "text/x-nsis": {"exts": ["*.nsi","*.nsh"], "mode": ""},
165 "text/x-nsis": {"exts": ["*.nsi","*.nsh"], "mode": "nsis"},
166 "text/x-objdump": {"exts": ["*.objdump"], "mode": ""},
166 "text/x-objdump": {"exts": ["*.objdump"], "mode": ""},
167 "text/x-objective-c": {"exts": ["*.m","*.h"], "mode": ""},
167 "text/x-objective-c": {"exts": ["*.m","*.h"], "mode": ""},
168 "text/x-objective-c++": {"exts": ["*.mm","*.hh"], "mode": ""},
168 "text/x-objective-c++": {"exts": ["*.mm","*.hh"], "mode": ""},
@@ -217,7 +217,7 b' MIME_TO_EXT = {'
217 "text/x-vb": {"exts": ["*.vb"], "mode": "vb"},
217 "text/x-vb": {"exts": ["*.vb"], "mode": "vb"},
218 "text/x-vbnet": {"exts": ["*.vb","*.bas"], "mode": ""},
218 "text/x-vbnet": {"exts": ["*.vb","*.bas"], "mode": ""},
219 "text/x-verilog": {"exts": ["*.v"], "mode": "verilog"},
219 "text/x-verilog": {"exts": ["*.v"], "mode": "verilog"},
220 "text/x-vhdl": {"exts": ["*.vhdl","*.vhd"], "mode": ""},
220 "text/x-vhdl": {"exts": ["*.vhdl","*.vhd"], "mode": "vhdl"},
221 "text/x-vim": {"exts": ["*.vim",".vimrc",".exrc",".gvimrc","_vimrc","_exrc","_gvimrc","vimrc","gvimrc"], "mode": ""},
221 "text/x-vim": {"exts": ["*.vim",".vimrc",".exrc",".gvimrc","_vimrc","_exrc","_gvimrc","vimrc","gvimrc"], "mode": ""},
222 "text/x-windows-registry": {"exts": ["*.reg"], "mode": ""},
222 "text/x-windows-registry": {"exts": ["*.reg"], "mode": ""},
223 "text/x-xtend": {"exts": ["*.xtend"], "mode": ""},
223 "text/x-xtend": {"exts": ["*.xtend"], "mode": ""},
@@ -173,6 +173,6 b' CodeMirror.defineMode("nginx", function('
173 };
173 };
174 });
174 });
175
175
176 CodeMirror.defineMIME("text/nginx", "text/x-nginx-conf");
176 CodeMirror.defineMIME("text/x-nginx-conf", "nginx");
177
177
178 });
178 });
@@ -86,7 +86,7 b''
86 "die echo empty exit eval include include_once isset list require require_once return " +
86 "die echo empty exit eval include include_once isset list require require_once return " +
87 "print unset __halt_compiler self static parent yield insteadof finally";
87 "print unset __halt_compiler self static parent yield insteadof finally";
88 var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__";
88 var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__";
89 var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once json_decode json_encode json_last_error json_last_error_msg curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_pause curl_reset curl_setopt_array curl_setopt curl_share_close curl_share_init curl_share_setopt curl_strerror curl_unescape curl_version mysqli_affected_rows mysqli_autocommit mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect_errno mysqli_connect_error mysqli_connect mysqli_data_seek mysqli_debug mysqli_dump_debug_info mysqli_errno mysqli_error_list mysqli_error mysqli_fetch_all mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_charset mysqli_get_client_info mysqli_get_client_stats mysqli_get_client_version mysqli_get_connection_stats mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_more_results mysqli_multi_query mysqli_next_result mysqli_num_fields mysqli_num_rows mysqli_options mysqli_ping mysqli_prepare mysqli_query mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reap_async_query mysqli_refresh mysqli_rollback mysqli_select_db mysqli_set_charset mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_init mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count";
89 var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents file_put_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once json_decode json_encode json_last_error json_last_error_msg curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_pause curl_reset curl_setopt_array curl_setopt curl_share_close curl_share_init curl_share_setopt curl_strerror curl_unescape curl_version mysqli_affected_rows mysqli_autocommit mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect_errno mysqli_connect_error mysqli_connect mysqli_data_seek mysqli_debug mysqli_dump_debug_info mysqli_errno mysqli_error_list mysqli_error mysqli_fetch_all mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_charset mysqli_get_client_info mysqli_get_client_stats mysqli_get_client_version mysqli_get_connection_stats mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_more_results mysqli_multi_query mysqli_next_result mysqli_num_fields mysqli_num_rows mysqli_options mysqli_ping mysqli_prepare mysqli_query mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reap_async_query mysqli_refresh mysqli_rollback mysqli_select_db mysqli_set_charset mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_init mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count";
90 CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
90 CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
91 CodeMirror.registerHelper("wordChars", "php", /[\w$]/);
91 CodeMirror.registerHelper("wordChars", "php", /[\w$]/);
92
92
@@ -105,14 +105,15 b''
105 return "variable-2";
105 return "variable-2";
106 },
106 },
107 "<": function(stream, state) {
107 "<": function(stream, state) {
108 if (stream.match(/<</)) {
108 var before;
109 var nowDoc = stream.eat("'");
109 if (before = stream.match(/<<\s*/)) {
110 var quoted = stream.eat(/['"]/);
110 stream.eatWhile(/[\w\.]/);
111 stream.eatWhile(/[\w\.]/);
111 var delim = stream.current().slice(3 + (nowDoc ? 1 : 0));
112 var delim = stream.current().slice(before[0].length + (quoted ? 2 : 1));
112 if (nowDoc) stream.eat("'");
113 if (quoted) stream.eat(quoted);
113 if (delim) {
114 if (delim) {
114 (state.tokStack || (state.tokStack = [])).push(delim, 0);
115 (state.tokStack || (state.tokStack = [])).push(delim, 0);
115 state.tokenize = phpString(delim, nowDoc ? false : true);
116 state.tokenize = phpString(delim, quoted != "'");
116 return "string";
117 return "string";
117 }
118 }
118 }
119 }
@@ -159,6 +160,7 b''
159 if (!isPHP) {
160 if (!isPHP) {
160 if (stream.match(/^<\?\w*/)) {
161 if (stream.match(/^<\?\w*/)) {
161 state.curMode = phpMode;
162 state.curMode = phpMode;
163 if (!state.php) state.php = CodeMirror.startState(phpMode, htmlMode.indent(state.html, ""))
162 state.curState = state.php;
164 state.curState = state.php;
163 return "meta";
165 return "meta";
164 }
166 }
@@ -182,6 +184,7 b''
182 } else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
184 } else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
183 state.curMode = htmlMode;
185 state.curMode = htmlMode;
184 state.curState = state.html;
186 state.curState = state.html;
187 if (!state.php.context.prev) state.php = null;
185 return "meta";
188 return "meta";
186 } else {
189 } else {
187 return phpMode.token(stream, state.curState);
190 return phpMode.token(stream, state.curState);
@@ -190,7 +193,8 b''
190
193
191 return {
194 return {
192 startState: function() {
195 startState: function() {
193 var html = CodeMirror.startState(htmlMode), php = CodeMirror.startState(phpMode);
196 var html = CodeMirror.startState(htmlMode)
197 var php = parserConfig.startOpen ? CodeMirror.startState(phpMode) : null
194 return {html: html,
198 return {html: html,
195 php: php,
199 php: php,
196 curMode: parserConfig.startOpen ? phpMode : htmlMode,
200 curMode: parserConfig.startOpen ? phpMode : htmlMode,
@@ -200,7 +204,7 b''
200
204
201 copyState: function(state) {
205 copyState: function(state) {
202 var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
206 var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
203 php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur;
207 php = state.php, phpNew = php && CodeMirror.copyState(phpMode, php), cur;
204 if (state.curMode == htmlMode) cur = htmlNew;
208 if (state.curMode == htmlMode) cur = htmlNew;
205 else cur = phpNew;
209 else cur = phpNew;
206 return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
210 return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
@@ -48,18 +48,18 b''
48 CodeMirror.defineMode("python", function(conf, parserConf) {
48 CodeMirror.defineMode("python", function(conf, parserConf) {
49 var ERRORCLASS = "error";
49 var ERRORCLASS = "error";
50
50
51 var singleDelimiters = parserConf.singleDelimiters || new RegExp("^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]");
51 var singleDelimiters = parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\.]/;
52 var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
52 var doubleOperators = parserConf.doubleOperators || /^([!<>]==|<>|<<|>>|\/\/|\*\*)/;
53 var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
53 var doubleDelimiters = parserConf.doubleDelimiters || /^(\+=|\-=|\*=|%=|\/=|&=|\|=|\^=)/;
54 var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))");
54 var tripleDelimiters = parserConf.tripleDelimiters || /^(\/\/=|>>=|<<=|\*\*=)/;
55
55
56 if (parserConf.version && parseInt(parserConf.version, 10) == 3){
56 if (parserConf.version && parseInt(parserConf.version, 10) == 3){
57 // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
57 // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
58 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!@]");
58 var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!@]/;
59 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*");
59 var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*/;
60 } else {
60 } else {
61 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
61 var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!]/;
62 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9]*");
62 var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
63 }
63 }
64
64
65 var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
65 var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
@@ -160,13 +160,16 b''
160
160
161 // Handle operators and Delimiters
161 // Handle operators and Delimiters
162 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
162 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
163 return null;
163 return "punctuation";
164
164
165 if (stream.match(doubleOperators) || stream.match(singleOperators))
165 if (stream.match(doubleOperators) || stream.match(singleOperators))
166 return "operator";
166 return "operator";
167
167
168 if (stream.match(singleDelimiters))
168 if (stream.match(singleDelimiters))
169 return null;
169 return "punctuation";
170
171 if (state.lastToken == "." && stream.match(identifiers))
172 return "property";
170
173
171 if (stream.match(keywords) || stream.match(wordOperators))
174 if (stream.match(keywords) || stream.match(wordOperators))
172 return "keyword";
175 return "keyword";
@@ -246,17 +249,6 b''
246 var style = state.tokenize(stream, state);
249 var style = state.tokenize(stream, state);
247 var current = stream.current();
250 var current = stream.current();
248
251
249 // Handle '.' connected identifiers
250 if (current == ".") {
251 style = stream.match(identifiers, false) ? null : ERRORCLASS;
252 if (style == null && state.lastStyle == "meta") {
253 // Apply 'meta' style to '.' connected identifiers when
254 // appropriate.
255 style = "meta";
256 }
257 return style;
258 }
259
260 // Handle decorators
252 // Handle decorators
261 if (current == "@"){
253 if (current == "@"){
262 if(parserConf.version && parseInt(parserConf.version, 10) == 3){
254 if(parserConf.version && parseInt(parserConf.version, 10) == 3){
@@ -267,7 +259,7 b''
267 }
259 }
268
260
269 if ((style == "variable" || style == "builtin")
261 if ((style == "variable" || style == "builtin")
270 && state.lastStyle == "meta")
262 && state.lastToken == "meta")
271 style = "meta";
263 style = "meta";
272
264
273 // Handle scope changes.
265 // Handle scope changes.
@@ -300,7 +292,6 b''
300 return {
292 return {
301 tokenize: tokenBase,
293 tokenize: tokenBase,
302 scopes: [{offset: basecolumn || 0, type: "py", align: null}],
294 scopes: [{offset: basecolumn || 0, type: "py", align: null}],
303 lastStyle: null,
304 lastToken: null,
295 lastToken: null,
305 lambda: false,
296 lambda: false,
306 dedent: 0
297 dedent: 0
@@ -312,11 +303,9 b''
312 if (addErr) state.errorToken = false;
303 if (addErr) state.errorToken = false;
313 var style = tokenLexer(stream, state);
304 var style = tokenLexer(stream, state);
314
305
315 state.lastStyle = style;
306 if (style && style != "comment")
316
307 state.lastToken = (style == "keyword" || style == "punctuation") ? stream.current() : style;
317 var current = stream.current();
308 if (style == "punctuation") style = null;
318 if (current && style)
319 state.lastToken = current;
320
309
321 if (stream.eol() && state.lambda)
310 if (stream.eol() && state.lambda)
322 state.lambda = false;
311 state.lambda = false;
@@ -34,10 +34,10 b' CodeMirror.defineMIME("text/x-rpm-change'
34 // Quick and dirty spec file highlighting
34 // Quick and dirty spec file highlighting
35
35
36 CodeMirror.defineMode("rpm-spec", function() {
36 CodeMirror.defineMode("rpm-spec", function() {
37 var arch = /^(i386|i586|i686|x86_64|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/;
37 var arch = /^(i386|i586|i686|x86_64|ppc64le|ppc64|ppc|ia64|s390x|s390|sparc64|sparcv9|sparc|noarch|alphaev6|alpha|hppa|mipsel)/;
38
38
39 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):/;
39 var preamble = /^[a-zA-Z0-9()]+:/;
40 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)/;
40 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)/;
41 var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros
41 var control_flow_complex = /^%(ifnarch|ifarch|if)/; // rpm control flow macros
42 var control_flow_simple = /^%(else|endif)/; // rpm control flow macros
42 var control_flow_simple = /^%(else|endif)/; // rpm control flow macros
43 var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros
43 var operators = /^(\!|\?|\<\=|\<|\>\=|\>|\=\=|\&\&|\|\|)/; // operators in control flow macros
@@ -55,8 +55,8 b' CodeMirror.defineMode("rpm-spec", functi'
55 if (ch == "#") { stream.skipToEnd(); return "comment"; }
55 if (ch == "#") { stream.skipToEnd(); return "comment"; }
56
56
57 if (stream.sol()) {
57 if (stream.sol()) {
58 if (stream.match(preamble)) { return "preamble"; }
58 if (stream.match(preamble)) { return "header"; }
59 if (stream.match(section)) { return "section"; }
59 if (stream.match(section)) { return "atom"; }
60 }
60 }
61
61
62 if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT'
62 if (stream.match(/^\$\w+/)) { return "def"; } // Variables like '$RPM_BUILD_ROOT'
@@ -73,21 +73,29 b' CodeMirror.defineMode("rpm-spec", functi'
73 if (stream.eol()) { state.controlFlow = false; }
73 if (stream.eol()) { state.controlFlow = false; }
74 }
74 }
75
75
76 if (stream.match(arch)) { return "number"; }
76 if (stream.match(arch)) {
77 if (stream.eol()) { state.controlFlow = false; }
78 return "number";
79 }
77
80
78 // Macros like '%make_install' or '%attr(0775,root,root)'
81 // Macros like '%make_install' or '%attr(0775,root,root)'
79 if (stream.match(/^%[\w]+/)) {
82 if (stream.match(/^%[\w]+/)) {
80 if (stream.match(/^\(/)) { state.macroParameters = true; }
83 if (stream.match(/^\(/)) { state.macroParameters = true; }
81 return "macro";
84 return "keyword";
82 }
85 }
83 if (state.macroParameters) {
86 if (state.macroParameters) {
84 if (stream.match(/^\d+/)) { return "number";}
87 if (stream.match(/^\d+/)) { return "number";}
85 if (stream.match(/^\)/)) {
88 if (stream.match(/^\)/)) {
86 state.macroParameters = false;
89 state.macroParameters = false;
87 return "macro";
90 return "keyword";
88 }
91 }
89 }
92 }
90 if (stream.match(/^%\{\??[\w \-]+\}/)) { return "macro"; } // Macros like '%{defined fedora}'
93
94 // Macros like '%{defined fedora}'
95 if (stream.match(/^%\{\??[\w \-\:\!]+\}/)) {
96 if (stream.eol()) { state.controlFlow = false; }
97 return "def";
98 }
91
99
92 //TODO: Include bash script sub-parser (CodeMirror supports that)
100 //TODO: Include bash script sub-parser (CodeMirror supports that)
93 stream.next();
101 stream.next();
@@ -25,7 +25,7 b' CodeMirror.defineMode("ruby", function(c'
25 "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
25 "caller", "lambda", "proc", "public", "protected", "private", "require", "load",
26 "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
26 "require_relative", "extend", "autoload", "__END__", "__FILE__", "__LINE__", "__dir__"
27 ]);
27 ]);
28 var indentWords = wordObj(["def", "class", "case", "for", "while", "module", "then",
28 var indentWords = wordObj(["def", "class", "case", "for", "while", "until", "module", "then",
29 "catch", "loop", "proc", "begin"]);
29 "catch", "loop", "proc", "begin"]);
30 var dedentWords = wordObj(["end", "until"]);
30 var dedentWords = wordObj(["end", "until"]);
31 var matching = {"[": "]", "{": "}", "(": ")"};
31 var matching = {"[": "]", "{": "}", "(": ")"};
@@ -37,7 +37,6 b' CodeMirror.defineMode("ruby", function(c'
37 }
37 }
38
38
39 function tokenBase(stream, state) {
39 function tokenBase(stream, state) {
40 curPunc = null;
41 if (stream.sol() && stream.match("=begin") && stream.eol()) {
40 if (stream.sol() && stream.match("=begin") && stream.eol()) {
42 state.tokenize.push(readBlockComment);
41 state.tokenize.push(readBlockComment);
43 return "comment";
42 return "comment";
@@ -232,6 +231,7 b' CodeMirror.defineMode("ruby", function(c'
232 },
231 },
233
232
234 token: function(stream, state) {
233 token: function(stream, state) {
234 curPunc = null;
235 if (stream.sol()) state.indented = stream.indentation();
235 if (stream.sol()) state.indented = stream.indentation();
236 var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
236 var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;
237 var thisTok = curPunc;
237 var thisTok = curPunc;
@@ -275,7 +275,7 b' CodeMirror.defineMode("ruby", function(c'
275 (state.continuedLine ? config.indentUnit : 0);
275 (state.continuedLine ? config.indentUnit : 0);
276 },
276 },
277
277
278 electricChars: "}de", // enD and rescuE
278 electricInput: /^\s*(?:end|rescue|\})$/,
279 lineComment: "#"
279 lineComment: "#"
280 };
280 };
281 });
281 });
@@ -3,449 +3,69 b''
3
3
4 (function(mod) {
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"));
6 mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
7 else if (typeof define == "function" && define.amd) // AMD
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod);
8 define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
9 else // Plain browser env
9 else // Plain browser env
10 mod(CodeMirror);
10 mod(CodeMirror);
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("rust", function() {
14 CodeMirror.defineSimpleMode("rust",{
15 var indentUnit = 4, altIndentUnit = 2;
15 start: [
16 var valKeywords = {
16 // string and byte string
17 "if": "if-style", "while": "if-style", "loop": "else-style", "else": "else-style",
17 {regex: /b?"/, token: "string", next: "string"},
18 "do": "else-style", "ret": "else-style", "fail": "else-style",
18 // raw string and raw byte string
19 "break": "atom", "cont": "atom", "const": "let", "resource": "fn",
19 {regex: /b?r"/, token: "string", next: "string_raw"},
20 "let": "let", "fn": "fn", "for": "for", "alt": "alt", "iface": "iface",
20 {regex: /b?r#+"/, token: "string", next: "string_raw_hash"},
21 "impl": "impl", "type": "type", "enum": "enum", "mod": "mod",
21 // character
22 "as": "op", "true": "atom", "false": "atom", "assert": "op", "check": "op",
22 {regex: /'(?:[^'\\]|\\(?:[nrt0'"]|x[\da-fA-F]{2}|u\{[\da-fA-F]{6}\}))'/, token: "string-2"},
23 "claim": "op", "native": "ignore", "unsafe": "ignore", "import": "else-style",
23 // byte
24 "export": "else-style", "copy": "op", "log": "op", "log_err": "op",
24 {regex: /b'(?:[^']|\\(?:['\\nrt0]|x[\da-fA-F]{2}))'/, token: "string-2"},
25 "use": "op", "bind": "op", "self": "atom", "struct": "enum"
26 };
27 var typeKeywords = function() {
28 var keywords = {"fn": "fn", "block": "fn", "obj": "obj"};
29 var atoms = "bool uint int i8 i16 i32 i64 u8 u16 u32 u64 float f32 f64 str char".split(" ");
30 for (var i = 0, e = atoms.length; i < e; ++i) keywords[atoms[i]] = "atom";
31 return keywords;
32 }();
33 var operatorChar = /[+\-*&%=<>!?|\.@]/;
34
35 // Tokenizer
36
37 // Used as scratch variable to communicate multiple values without
38 // consing up tons of objects.
39 var tcat, content;
40 function r(tc, style) {
41 tcat = tc;
42 return style;
43 }
44
45 function tokenBase(stream, state) {
46 var ch = stream.next();
47 if (ch == '"') {
48 state.tokenize = tokenString;
49 return state.tokenize(stream, state);
50 }
51 if (ch == "'") {
52 tcat = "atom";
53 if (stream.eat("\\")) {
54 if (stream.skipTo("'")) { stream.next(); return "string"; }
55 else { return "error"; }
56 } else {
57 stream.next();
58 return stream.eat("'") ? "string" : "error";
59 }
60 }
61 if (ch == "/") {
62 if (stream.eat("/")) { stream.skipToEnd(); return "comment"; }
63 if (stream.eat("*")) {
64 state.tokenize = tokenComment(1);
65 return state.tokenize(stream, state);
66 }
67 }
68 if (ch == "#") {
69 if (stream.eat("[")) { tcat = "open-attr"; return null; }
70 stream.eatWhile(/\w/);
71 return r("macro", "meta");
72 }
73 if (ch == ":" && stream.match(":<")) {
74 return r("op", null);
75 }
76 if (ch.match(/\d/) || (ch == "." && stream.eat(/\d/))) {
77 var flp = false;
78 if (!stream.match(/^x[\da-f]+/i) && !stream.match(/^b[01]+/)) {
79 stream.eatWhile(/\d/);
80 if (stream.eat(".")) { flp = true; stream.eatWhile(/\d/); }
81 if (stream.match(/^e[+\-]?\d+/i)) { flp = true; }
82 }
83 if (flp) stream.match(/^f(?:32|64)/);
84 else stream.match(/^[ui](?:8|16|32|64)/);
85 return r("atom", "number");
86 }
87 if (ch.match(/[()\[\]{}:;,]/)) return r(ch, null);
88 if (ch == "-" && stream.eat(">")) return r("->", null);
89 if (ch.match(operatorChar)) {
90 stream.eatWhile(operatorChar);
91 return r("op", null);
92 }
93 stream.eatWhile(/\w/);
94 content = stream.current();
95 if (stream.match(/^::\w/)) {
96 stream.backUp(1);
97 return r("prefix", "variable-2");
98 }
99 if (state.keywords.propertyIsEnumerable(content))
100 return r(state.keywords[content], content.match(/true|false/) ? "atom" : "keyword");
101 return r("name", "variable");
102 }
103
104 function tokenString(stream, state) {
105 var ch, escaped = false;
106 while (ch = stream.next()) {
107 if (ch == '"' && !escaped) {
108 state.tokenize = tokenBase;
109 return r("atom", "string");
110 }
111 escaped = !escaped && ch == "\\";
112 }
113 // Hack to not confuse the parser when a string is split in
114 // pieces.
115 return r("op", "string");
116 }
117
118 function tokenComment(depth) {
119 return function(stream, state) {
120 var lastCh = null, ch;
121 while (ch = stream.next()) {
122 if (ch == "/" && lastCh == "*") {
123 if (depth == 1) {
124 state.tokenize = tokenBase;
125 break;
126 } else {
127 state.tokenize = tokenComment(depth - 1);
128 return state.tokenize(stream, state);
129 }
130 }
131 if (ch == "*" && lastCh == "/") {
132 state.tokenize = tokenComment(depth + 1);
133 return state.tokenize(stream, state);
134 }
135 lastCh = ch;
136 }
137 return "comment";
138 };
139 }
140
141 // Parser
142
143 var cx = {state: null, stream: null, marked: null, cc: null};
144 function pass() {
145 for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
146 }
147 function cont() {
148 pass.apply(null, arguments);
149 return true;
150 }
151
152 function pushlex(type, info) {
153 var result = function() {
154 var state = cx.state;
155 state.lexical = {indented: state.indented, column: cx.stream.column(),
156 type: type, prev: state.lexical, info: info};
157 };
158 result.lex = true;
159 return result;
160 }
161 function poplex() {
162 var state = cx.state;
163 if (state.lexical.prev) {
164 if (state.lexical.type == ")")
165 state.indented = state.lexical.indented;
166 state.lexical = state.lexical.prev;
167 }
168 }
169 function typecx() { cx.state.keywords = typeKeywords; }
170 function valcx() { cx.state.keywords = valKeywords; }
171 poplex.lex = typecx.lex = valcx.lex = true;
172
173 function commasep(comb, end) {
174 function more(type) {
175 if (type == ",") return cont(comb, more);
176 if (type == end) return cont();
177 return cont(more);
178 }
179 return function(type) {
180 if (type == end) return cont();
181 return pass(comb, more);
182 };
183 }
184
25
185 function stat_of(comb, tag) {
26 {regex: /(?:(?:[0-9][0-9_]*)(?:(?:[Ee][+-]?[0-9_]+)|\.[0-9_]+(?:[Ee][+-]?[0-9_]+)?)(?:f32|f64)?)|(?:0(?:b[01_]+|(?:o[0-7_]+)|(?:x[0-9a-fA-F_]+))|(?:[0-9][0-9_]*))(?:u8|u16|u32|u64|i8|i16|i32|i64|isize|usize)?/,
186 return cont(pushlex("stat", tag), comb, poplex, block);
27 token: "number"},
187 }
28 {regex: /(let(?:\s+mut)?|fn|enum|mod|struct|type)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/, token: ["keyword", null, "def"]},
188 function block(type) {
29 {regex: /(?:abstract|alignof|as|box|break|continue|const|crate|do|else|enum|extern|fn|for|final|if|impl|in|loop|macro|match|mod|move|offsetof|override|priv|proc|pub|pure|ref|return|self|sizeof|static|struct|super|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/, token: "keyword"},
189 if (type == "}") return cont();
30 {regex: /\b(?:Self|isize|usize|char|bool|u8|u16|u32|u64|f16|f32|f64|i8|i16|i32|i64|str|Option)\b/, token: "atom"},
190 if (type == "let") return stat_of(letdef1, "let");
31 {regex: /\b(?:true|false|Some|None|Ok|Err)\b/, token: "builtin"},
191 if (type == "fn") return stat_of(fndef);
32 {regex: /\b(fn)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)/,
192 if (type == "type") return cont(pushlex("stat"), tydef, endstatement, poplex, block);
33 token: ["keyword", null ,"def"]},
193 if (type == "enum") return stat_of(enumdef);
34 {regex: /#!?\[.*\]/, token: "meta"},
194 if (type == "mod") return stat_of(mod);
35 {regex: /\/\/.*/, token: "comment"},
195 if (type == "iface") return stat_of(iface);
36 {regex: /\/\*/, token: "comment", next: "comment"},
196 if (type == "impl") return stat_of(impl);
37 {regex: /[-+\/*=<>!]+/, token: "operator"},
197 if (type == "open-attr") return cont(pushlex("]"), commasep(expression, "]"), poplex);
38 {regex: /[a-zA-Z_]\w*!/,token: "variable-3"},
198 if (type == "ignore" || type.match(/[\]\);,]/)) return cont(block);
39 {regex: /[a-zA-Z_]\w*/, token: "variable"},
199 return pass(pushlex("stat"), expression, poplex, endstatement, block);
40 {regex: /[\{\[\(]/, indent: true},
200 }
41 {regex: /[\}\]\)]/, dedent: true}
201 function endstatement(type) {
42 ],
202 if (type == ";") return cont();
43 string: [
203 return pass();
44 {regex: /"/, token: "string", next: "start"},
204 }
45 {regex: /(?:[^\\"]|\\(?:.|$))*/, token: "string"}
205 function expression(type) {
46 ],
206 if (type == "atom" || type == "name") return cont(maybeop);
47 string_raw: [
207 if (type == "{") return cont(pushlex("}"), exprbrace, poplex);
48 {regex: /"/, token: "string", next: "start"},
208 if (type.match(/[\[\(]/)) return matchBrackets(type, expression);
49 {regex: /[^"]*/, token: "string"}
209 if (type.match(/[\]\)\};,]/)) return pass();
50 ],
210 if (type == "if-style") return cont(expression, expression);
51 string_raw_hash: [
211 if (type == "else-style" || type == "op") return cont(expression);
52 {regex: /"#+/, token: "string", next: "start"},
212 if (type == "for") return cont(pattern, maybetype, inop, expression, expression);
53 {regex: /(?:[^"]|"(?!#))*/, token: "string"}
213 if (type == "alt") return cont(expression, altbody);
54 ],
214 if (type == "fn") return cont(fndef);
55 comment: [
215 if (type == "macro") return cont(macro);
56 {regex: /.*?\*\//, token: "comment", next: "start"},
216 return cont();
57 {regex: /.*/, token: "comment"}
217 }
58 ],
218 function maybeop(type) {
59 meta: {
219 if (content == ".") return cont(maybeprop);
60 dontIndentStates: ["comment"],
220 if (content == "::<"){return cont(typarams, maybeop);}
61 electricInput: /^\s*\}$/,
221 if (type == "op" || content == ":") return cont(expression);
222 if (type == "(" || type == "[") return matchBrackets(type, expression);
223 return pass();
224 }
225 function maybeprop() {
226 if (content.match(/^\w+$/)) {cx.marked = "variable"; return cont(maybeop);}
227 return pass(expression);
228 }
229 function exprbrace(type) {
230 if (type == "op") {
231 if (content == "|") return cont(blockvars, poplex, pushlex("}", "block"), block);
232 if (content == "||") return cont(poplex, pushlex("}", "block"), block);
233 }
234 if (content == "mutable" || (content.match(/^\w+$/) && cx.stream.peek() == ":"
235 && !cx.stream.match("::", false)))
236 return pass(record_of(expression));
237 return pass(block);
238 }
239 function record_of(comb) {
240 function ro(type) {
241 if (content == "mutable" || content == "with") {cx.marked = "keyword"; return cont(ro);}
242 if (content.match(/^\w*$/)) {cx.marked = "variable"; return cont(ro);}
243 if (type == ":") return cont(comb, ro);
244 if (type == "}") return cont();
245 return cont(ro);
246 }
247 return ro;
248 }
249 function blockvars(type) {
250 if (type == "name") {cx.marked = "def"; return cont(blockvars);}
251 if (type == "op" && content == "|") return cont();
252 return cont(blockvars);
253 }
254
255 function letdef1(type) {
256 if (type.match(/[\]\)\};]/)) return cont();
257 if (content == "=") return cont(expression, letdef2);
258 if (type == ",") return cont(letdef1);
259 return pass(pattern, maybetype, letdef1);
260 }
261 function letdef2(type) {
262 if (type.match(/[\]\)\};,]/)) return pass(letdef1);
263 else return pass(expression, letdef2);
264 }
265 function maybetype(type) {
266 if (type == ":") return cont(typecx, rtype, valcx);
267 return pass();
268 }
269 function inop(type) {
270 if (type == "name" && content == "in") {cx.marked = "keyword"; return cont();}
271 return pass();
272 }
273 function fndef(type) {
274 if (content == "@" || content == "~") {cx.marked = "keyword"; return cont(fndef);}
275 if (type == "name") {cx.marked = "def"; return cont(fndef);}
276 if (content == "<") return cont(typarams, fndef);
277 if (type == "{") return pass(expression);
278 if (type == "(") return cont(pushlex(")"), commasep(argdef, ")"), poplex, fndef);
279 if (type == "->") return cont(typecx, rtype, valcx, fndef);
280 if (type == ";") return cont();
281 return cont(fndef);
282 }
283 function tydef(type) {
284 if (type == "name") {cx.marked = "def"; return cont(tydef);}
285 if (content == "<") return cont(typarams, tydef);
286 if (content == "=") return cont(typecx, rtype, valcx);
287 return cont(tydef);
288 }
289 function enumdef(type) {
290 if (type == "name") {cx.marked = "def"; return cont(enumdef);}
291 if (content == "<") return cont(typarams, enumdef);
292 if (content == "=") return cont(typecx, rtype, valcx, endstatement);
293 if (type == "{") return cont(pushlex("}"), typecx, enumblock, valcx, poplex);
294 return cont(enumdef);
295 }
296 function enumblock(type) {
297 if (type == "}") return cont();
298 if (type == "(") return cont(pushlex(")"), commasep(rtype, ")"), poplex, enumblock);
299 if (content.match(/^\w+$/)) cx.marked = "def";
300 return cont(enumblock);
301 }
302 function mod(type) {
303 if (type == "name") {cx.marked = "def"; return cont(mod);}
304 if (type == "{") return cont(pushlex("}"), block, poplex);
305 return pass();
306 }
307 function iface(type) {
308 if (type == "name") {cx.marked = "def"; return cont(iface);}
309 if (content == "<") return cont(typarams, iface);
310 if (type == "{") return cont(pushlex("}"), block, poplex);
311 return pass();
312 }
313 function impl(type) {
314 if (content == "<") return cont(typarams, impl);
315 if (content == "of" || content == "for") {cx.marked = "keyword"; return cont(rtype, impl);}
316 if (type == "name") {cx.marked = "def"; return cont(impl);}
317 if (type == "{") return cont(pushlex("}"), block, poplex);
318 return pass();
319 }
320 function typarams() {
321 if (content == ">") return cont();
322 if (content == ",") return cont(typarams);
323 if (content == ":") return cont(rtype, typarams);
324 return pass(rtype, typarams);
325 }
326 function argdef(type) {
327 if (type == "name") {cx.marked = "def"; return cont(argdef);}
328 if (type == ":") return cont(typecx, rtype, valcx);
329 return pass();
330 }
331 function rtype(type) {
332 if (type == "name") {cx.marked = "variable-3"; return cont(rtypemaybeparam); }
333 if (content == "mutable") {cx.marked = "keyword"; return cont(rtype);}
334 if (type == "atom") return cont(rtypemaybeparam);
335 if (type == "op" || type == "obj") return cont(rtype);
336 if (type == "fn") return cont(fntype);
337 if (type == "{") return cont(pushlex("{"), record_of(rtype), poplex);
338 return matchBrackets(type, rtype);
339 }
340 function rtypemaybeparam() {
341 if (content == "<") return cont(typarams);
342 return pass();
343 }
344 function fntype(type) {
345 if (type == "(") return cont(pushlex("("), commasep(rtype, ")"), poplex, fntype);
346 if (type == "->") return cont(rtype);
347 return pass();
348 }
349 function pattern(type) {
350 if (type == "name") {cx.marked = "def"; return cont(patternmaybeop);}
351 if (type == "atom") return cont(patternmaybeop);
352 if (type == "op") return cont(pattern);
353 if (type.match(/[\]\)\};,]/)) return pass();
354 return matchBrackets(type, pattern);
355 }
356 function patternmaybeop(type) {
357 if (type == "op" && content == ".") return cont();
358 if (content == "to") {cx.marked = "keyword"; return cont(pattern);}
359 else return pass();
360 }
361 function altbody(type) {
362 if (type == "{") return cont(pushlex("}", "alt"), altblock1, poplex);
363 return pass();
364 }
365 function altblock1(type) {
366 if (type == "}") return cont();
367 if (type == "|") return cont(altblock1);
368 if (content == "when") {cx.marked = "keyword"; return cont(expression, altblock2);}
369 if (type.match(/[\]\);,]/)) return cont(altblock1);
370 return pass(pattern, altblock2);
371 }
372 function altblock2(type) {
373 if (type == "{") return cont(pushlex("}", "alt"), block, poplex, altblock1);
374 else return pass(altblock1);
375 }
376
377 function macro(type) {
378 if (type.match(/[\[\(\{]/)) return matchBrackets(type, expression);
379 return pass();
380 }
381 function matchBrackets(type, comb) {
382 if (type == "[") return cont(pushlex("]"), commasep(comb, "]"), poplex);
383 if (type == "(") return cont(pushlex(")"), commasep(comb, ")"), poplex);
384 if (type == "{") return cont(pushlex("}"), commasep(comb, "}"), poplex);
385 return cont();
386 }
387
388 function parse(state, stream, style) {
389 var cc = state.cc;
390 // Communicate our context to the combinators.
391 // (Less wasteful than consing up a hundred closures on every call.)
392 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
393
394 while (true) {
395 var combinator = cc.length ? cc.pop() : block;
396 if (combinator(tcat)) {
397 while(cc.length && cc[cc.length - 1].lex)
398 cc.pop()();
399 return cx.marked || style;
400 }
401 }
402 }
403
404 return {
405 startState: function() {
406 return {
407 tokenize: tokenBase,
408 cc: [],
409 lexical: {indented: -indentUnit, column: 0, type: "top", align: false},
410 keywords: valKeywords,
411 indented: 0
412 };
413 },
414
415 token: function(stream, state) {
416 if (stream.sol()) {
417 if (!state.lexical.hasOwnProperty("align"))
418 state.lexical.align = false;
419 state.indented = stream.indentation();
420 }
421 if (stream.eatSpace()) return null;
422 tcat = content = null;
423 var style = state.tokenize(stream, state);
424 if (style == "comment") return style;
425 if (!state.lexical.hasOwnProperty("align"))
426 state.lexical.align = true;
427 if (tcat == "prefix") return style;
428 if (!content) content = stream.current();
429 return parse(state, stream, style);
430 },
431
432 indent: function(state, textAfter) {
433 if (state.tokenize != tokenBase) return 0;
434 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
435 type = lexical.type, closing = firstChar == type;
436 if (type == "stat") return lexical.indented + indentUnit;
437 if (lexical.align) return lexical.column + (closing ? 0 : 1);
438 return lexical.indented + (closing ? 0 : (lexical.info == "alt" ? altIndentUnit : indentUnit));
439 },
440
441 electricChars: "{}",
442 blockCommentStart: "/*",
62 blockCommentStart: "/*",
443 blockCommentEnd: "*/",
63 blockCommentEnd: "*/",
444 lineComment: "//",
64 lineComment: "//",
445 fold: "brace"
65 fold: "brace"
446 };
66 }
447 });
67 });
448
68
69
449 CodeMirror.defineMIME("text/x-rustsrc", "rust");
70 CodeMirror.defineMIME("text/x-rustsrc", "rust");
450
451 });
71 });
@@ -165,7 +165,9 b' CodeMirror.defineMode("sparql", function'
165 return context.col + (closing ? 0 : 1);
165 return context.col + (closing ? 0 : 1);
166 else
166 else
167 return context.indent + (closing ? 0 : indentUnit);
167 return context.indent + (closing ? 0 : indentUnit);
168 }
168 },
169
170 lineComment: "#"
169 };
171 };
170 });
172 });
171
173
@@ -257,7 +257,7 b' CodeMirror.defineMode("sql", function(co'
257 }
257 }
258
258
259 // these keywords are used by all SQL dialects (however, a mode can still overwrite it)
259 // these keywords are used by all SQL dialects (however, a mode can still overwrite it)
260 var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where ";
260 var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where limit";
261
261
262 // turn a space-separated list into an array
262 // turn a space-separated list into an array
263 function set(str) {
263 function set(str) {
@@ -126,19 +126,16 b''
126 if (stream.match(/^&{1}\s*$/)) {
126 if (stream.match(/^&{1}\s*$/)) {
127 return ["variable-3", "reference"];
127 return ["variable-3", "reference"];
128 }
128 }
129 // Variable
130 if (ch == "$" && stream.match(/^\$[\w-]+/i)) {
131 return ["variable-2", "variable-name"];
132 }
133 // Word operator
129 // Word operator
134 if (stream.match(wordOperatorKeywordsRegexp)) {
130 if (stream.match(wordOperatorKeywordsRegexp)) {
135 return ["operator", "operator"];
131 return ["operator", "operator"];
136 }
132 }
137 // Word
133 // Word
138 if (stream.match(/^[-_]*[a-z0-9]+[\w-]*/i)) {
134 if (stream.match(/^\$?[-_]*[a-z0-9]+[\w-]*/i)) {
135 // Variable
139 if (stream.match(/^(\.|\[)[\w-\'\"\]]+/i, false)) {
136 if (stream.match(/^(\.|\[)[\w-\'\"\]]+/i, false)) {
140 if (!wordIsTag(stream.current())) {
137 if (!wordIsTag(stream.current())) {
141 stream.match(/[\w-]+/);
138 stream.match(/\./);
142 return ["variable-2", "variable-name"];
139 return ["variable-2", "variable-name"];
143 }
140 }
144 }
141 }
@@ -323,7 +320,7 b''
323 return pushContext(state, stream, "block", 0);
320 return pushContext(state, stream, "block", 0);
324 }
321 }
325 if (type == "variable-name") {
322 if (type == "variable-name") {
326 if ((stream.indentation() == 0 && startOfLine(stream)) || wordIsBlock(firstWordOfLine(stream))) {
323 if (stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/) || wordIsBlock(firstWordOfLine(stream))) {
327 return pushContext(state, stream, "variableName");
324 return pushContext(state, stream, "variableName");
328 }
325 }
329 else {
326 else {
@@ -429,6 +426,11 b''
429 return pushContext(state, stream, "block");
426 return pushContext(state, stream, "block");
430 }
427 }
431 if (word == "return") return pushContext(state, stream, "block", 0);
428 if (word == "return") return pushContext(state, stream, "block", 0);
429
430 // Placeholder selector
431 if (override == "variable-2" && stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/)) {
432 return pushContext(state, stream, "block");
433 }
432 }
434 }
433 return state.context.type;
435 return state.context.type;
434 };
436 };
@@ -639,7 +641,6 b''
639 states.variableName = function(type, stream, state) {
641 states.variableName = function(type, stream, state) {
640 if (type == "string" || type == "[" || type == "]" || stream.current().match(/^(\.|\$)/)) {
642 if (type == "string" || type == "[" || type == "]" || stream.current().match(/^(\.|\$)/)) {
641 if (stream.current().match(/^\.[\w-]+/i)) override = "variable-2";
643 if (stream.current().match(/^\.[\w-]+/i)) override = "variable-2";
642 if (endOfLine(stream)) return popContext(state);
643 return "variableName";
644 return "variableName";
644 }
645 }
645 return popAndPass(type, stream, state);
646 return popAndPass(type, stream, state);
@@ -735,7 +736,7 b''
735 var nonStandardPropertyKeywords_ = ["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"];
736 var nonStandardPropertyKeywords_ = ["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"];
736 var fontProperties_ = ["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"];
737 var fontProperties_ = ["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"];
737 var colorKeywords_ = ["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"];
738 var colorKeywords_ = ["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"];
738 var valueKeywords_ = ["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","contain","content","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","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","solid","somali","source-atop","source-in","source-out","source-over","space","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","x-large","x-small","xor","xx-large","xx-small","bicubic","optimizespeed","grayscale"];
739 var valueKeywords_ = ["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","compact","condensed","contain","content","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","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","solid","somali","source-atop","source-in","source-out","source-over","space","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","x-large","x-small","xor","xx-large","xx-small","bicubic","optimizespeed","grayscale","row","row-reverse","wrap","wrap-reverse","column-reverse","flex-start","flex-end","space-between","space-around"];
739
740
740 var wordOperatorKeywords_ = ["in","and","or","not","is not","is a","is","isnt","defined","if unless"],
741 var wordOperatorKeywords_ = ["in","and","or","not","is not","is a","is","isnt","defined","if unless"],
741 blockKeywords_ = ["for","if","else","unless", "from", "to"],
742 blockKeywords_ = ["for","if","else","unless", "from", "to"],
@@ -13,189 +13,188 b''
13 })(function(CodeMirror) {
13 })(function(CodeMirror) {
14 "use strict"
14 "use strict"
15
15
16 function trim(str) { return /^\s*(.*?)\s*$/.exec(str)[1] }
16 function wordSet(words) {
17
17 var set = {}
18 var separators = [" ","\\\+","\\\-","\\\(","\\\)","\\\*","/",":","\\\?","\\\<","\\\>"," ","\\\."]
18 for (var i = 0; i < words.length; i++) set[words[i]] = true
19 var tokens = new RegExp(separators.join("|"),"g")
19 return set
20
21 function getWord(string, pos) {
22 var index = -1, count = 1
23 var words = string.split(tokens)
24 for (var i = 0; i < words.length; i++) {
25 for(var j = 1; j <= words[i].length; j++) {
26 if (count==pos) index = i
27 count++
28 }
29 count++
30 }
31 var ret = ["", ""]
32 if (pos == 0) {
33 ret[1] = words[0]
34 ret[0] = null
35 } else {
36 ret[1] = words[index]
37 ret[0] = words[index-1]
38 }
39 return ret
40 }
20 }
41
21
42 CodeMirror.defineMode("swift", function() {
22 var keywords = wordSet(["var","let","class","deinit","enum","extension","func","import","init","protocol",
43 var keywords=["var","let","class","deinit","enum","extension","func","import","init","let","protocol","static","struct","subscript","typealias","var","as","dynamicType","is","new","super","self","Self","Type","__COLUMN__","__FILE__","__FUNCTION__","__LINE__","break","case","continue","default","do","else","fallthrough","if","in","for","return","switch","where","while","associativity","didSet","get","infix","inout","left","mutating","none","nonmutating","operator","override","postfix","precedence","prefix","right","set","unowned","unowned(safe)","unowned(unsafe)","weak","willSet"]
23 "static","struct","subscript","typealias","as","dynamicType","is","new","super",
44 var commonConstants=["Infinity","NaN","undefined","null","true","false","on","off","yes","no","nil","null","this","super"]
24 "self","Self","Type","__COLUMN__","__FILE__","__FUNCTION__","__LINE__","break","case",
45 var types=["String","bool","int","string","double","Double","Int","Float","float","public","private","extension"]
25 "continue","default","do","else","fallthrough","if","in","for","return","switch",
46 var numbers=["0","1","2","3","4","5","6","7","8","9"]
26 "where","while","associativity","didSet","get","infix","inout","left","mutating",
47 var operators=["+","-","/","*","%","=","|","&","<",">"]
27 "none","nonmutating","operator","override","postfix","precedence","prefix","right",
48 var punc=[";",",",".","(",")","{","}","[","]"]
28 "set","unowned","weak","willSet"])
49 var delimiters=/^(?:[()\[\]{},:`=;]|\.\.?\.?)/
29 var definingKeywords = wordSet(["var","let","class","enum","extension","func","import","protocol","struct",
50 var identifiers=/^[_A-Za-z$][_A-Za-z$0-9]*/
30 "typealias","dynamicType","for"])
51 var properties=/^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/
31 var atoms = wordSet(["Infinity","NaN","undefined","null","true","false","on","off","yes","no","nil","null",
52 var regexPrefixes=/^(\/{3}|\/)/
32 "this","super"])
33 var types = wordSet(["String","bool","int","string","double","Double","Int","Float","float","public",
34 "private","extension"])
35 var operators = "+-/*%=|&<>#"
36 var punc = ";,.(){}[]"
37 var number = /^-?(?:(?:[\d_]+\.[_\d]*|\.[_\d]+|0o[0-7_\.]+|0b[01_\.]+)(?:e-?[\d_]+)?|0x[\d_a-f\.]+(?:p-?[\d_]+)?)/i
38 var identifier = /^[_A-Za-z$][_A-Za-z$0-9]*/
39 var property = /^[@\.][_A-Za-z$][_A-Za-z$0-9]*/
40 var regexp = /^\/(?!\s)(?:\/\/)?(?:\\.|[^\/])+\//
41
42 function tokenBase(stream, state, prev) {
43 if (stream.sol()) state.indented = stream.indentation()
44 if (stream.eatSpace()) return null
45
46 var ch = stream.peek()
47 if (ch == "/") {
48 if (stream.match("//")) {
49 stream.skipToEnd()
50 return "comment"
51 }
52 if (stream.match("/*")) {
53 state.tokenize.push(tokenComment)
54 return tokenComment(stream, state)
55 }
56 if (stream.match(regexp)) return "string-2"
57 }
58 if (operators.indexOf(ch) > -1) {
59 stream.next()
60 return "operator"
61 }
62 if (punc.indexOf(ch) > -1) {
63 stream.next()
64 stream.match("..")
65 return "punctuation"
66 }
67 if (ch == '"' || ch == "'") {
68 stream.next()
69 var tokenize = tokenString(ch)
70 state.tokenize.push(tokenize)
71 return tokenize(stream, state)
72 }
73
74 if (stream.match(number)) return "number"
75 if (stream.match(property)) return "property"
76
77 if (stream.match(identifier)) {
78 var ident = stream.current()
79 if (keywords.hasOwnProperty(ident)) {
80 if (definingKeywords.hasOwnProperty(ident))
81 state.prev = "define"
82 return "keyword"
83 }
84 if (types.hasOwnProperty(ident)) return "variable-2"
85 if (atoms.hasOwnProperty(ident)) return "atom"
86 if (prev == "define") return "def"
87 return "variable"
88 }
53
89
90 stream.next()
91 return null
92 }
93
94 function tokenUntilClosingParen() {
95 var depth = 0
96 return function(stream, state, prev) {
97 var inner = tokenBase(stream, state, prev)
98 if (inner == "punctuation") {
99 if (stream.current() == "(") ++depth
100 else if (stream.current() == ")") {
101 if (depth == 0) {
102 stream.backUp(1)
103 state.tokenize.pop()
104 return state.tokenize[state.tokenize.length - 1](stream, state)
105 }
106 else --depth
107 }
108 }
109 return inner
110 }
111 }
112
113 function tokenString(quote) {
114 return function(stream, state) {
115 var ch, escaped = false
116 while (ch = stream.next()) {
117 if (escaped) {
118 if (ch == "(") {
119 state.tokenize.push(tokenUntilClosingParen())
120 return "string"
121 }
122 escaped = false
123 } else if (ch == quote) {
124 break
125 } else {
126 escaped = ch == "\\"
127 }
128 }
129 state.tokenize.pop()
130 return "string"
131 }
132 }
133
134 function tokenComment(stream, state) {
135 stream.match(/^(?:[^*]|\*(?!\/))*/)
136 if (stream.match("*/")) state.tokenize.pop()
137 return "comment"
138 }
139
140 function Context(prev, align, indented) {
141 this.prev = prev
142 this.align = align
143 this.indented = indented
144 }
145
146 function pushContext(state, stream) {
147 var align = stream.match(/^\s*($|\/[\/\*])/, false) ? null : stream.column() + 1
148 state.context = new Context(state.context, align, state.indented)
149 }
150
151 function popContext(state) {
152 if (state.context) {
153 state.indented = state.context.indented
154 state.context = state.context.prev
155 }
156 }
157
158 CodeMirror.defineMode("swift", function(config) {
54 return {
159 return {
55 startState: function() {
160 startState: function() {
56 return {
161 return {
57 prev: false,
162 prev: null,
58 string: false,
163 context: null,
59 escape: false,
164 indented: 0,
60 inner: false,
165 tokenize: []
61 comment: false,
62 num_left: 0,
63 num_right: 0,
64 doubleString: false,
65 singleString: false
66 }
166 }
67 },
167 },
68 token: function(stream, state) {
69 if (stream.eatSpace()) return null
70
168
71 var ch = stream.next()
169 token: function(stream, state) {
72 if (state.string) {
170 var prev = state.prev
73 if (state.escape) {
171 state.prev = null
74 state.escape = false
172 var tokenize = state.tokenize[state.tokenize.length - 1] || tokenBase
75 return "string"
173 var style = tokenize(stream, state, prev)
76 } else {
174 if (!style || style == "comment") state.prev = prev
77 if ((ch == "\"" && (state.doubleString && !state.singleString) ||
175 else if (!state.prev) state.prev = style
78 (ch == "'" && (!state.doubleString && state.singleString))) &&
79 !state.escape) {
80 state.string = false
81 state.doubleString = false
82 state.singleString = false
83 return "string"
84 } else if (ch == "\\" && stream.peek() == "(") {
85 state.inner = true
86 state.string = false
87 return "keyword"
88 } else if (ch == "\\" && stream.peek() != "(") {
89 state.escape = true
90 state.string = true
91 return "string"
92 } else {
93 return "string"
94 }
95 }
96 } else if (state.comment) {
97 if (ch == "*" && stream.peek() == "/") {
98 state.prev = "*"
99 return "comment"
100 } else if (ch == "/" && state.prev == "*") {
101 state.prev = false
102 state.comment = false
103 return "comment"
104 }
105 return "comment"
106 } else {
107 if (ch == "/") {
108 if (stream.peek() == "/") {
109 stream.skipToEnd()
110 return "comment"
111 }
112 if (stream.peek() == "*") {
113 state.comment = true
114 return "comment"
115 }
116 }
117 if (ch == "(" && state.inner) {
118 state.num_left++
119 return null
120 }
121 if (ch == ")" && state.inner) {
122 state.num_right++
123 if (state.num_left == state.num_right) {
124 state.inner=false
125 state.string=true
126 }
127 return null
128 }
129
176
130 var ret = getWord(stream.string, stream.pos)
177 if (style == "punctuation") {
131 var the_word = ret[1]
178 var bracket = /[\(\[\{]|([\]\)\}])/.exec(stream.current())
132 var prev_word = ret[0]
179 if (bracket) (bracket[1] ? popContext : pushContext)(state, stream)
180 }
133
181
134 if (operators.indexOf(ch + "") > -1) return "operator"
182 return style
135 if (punc.indexOf(ch) > -1) return "punctuation"
183 },
136
137 if (typeof the_word != "undefined") {
138 the_word = trim(the_word)
139 if (typeof prev_word != "undefined") prev_word = trim(prev_word)
140 if (the_word.charAt(0) == "#") return null
141
142 if (types.indexOf(the_word) > -1) return "def"
143 if (commonConstants.indexOf(the_word) > -1) return "atom"
144 if (numbers.indexOf(the_word) > -1) return "number"
145
146 if ((numbers.indexOf(the_word.charAt(0) + "") > -1 ||
147 operators.indexOf(the_word.charAt(0) + "") > -1) &&
148 numbers.indexOf(ch) > -1) {
149 return "number"
150 }
151
184
152 if (keywords.indexOf(the_word) > -1 ||
185 indent: function(state, textAfter) {
153 keywords.indexOf(the_word.split(tokens)[0]) > -1)
186 var cx = state.context
154 return "keyword"
187 if (!cx) return 0
155 if (keywords.indexOf(prev_word) > -1) return "def"
188 var closing = /^[\]\}\)]/.test(textAfter)
156 }
189 if (cx.align != null) return cx.align - (closing ? 1 : 0)
157 if (ch == '"' && !state.doubleString) {
190 return cx.indented + (closing ? 0 : config.indentUnit)
158 state.string = true
191 },
159 state.doubleString = true
192
160 return "string"
193 electricInput: /^\s*[\)\}\]]$/,
161 }
194
162 if (ch == "'" && !state.singleString) {
195 lineComment: "//",
163 state.string = true
196 blockCommentStart: "/*",
164 state.singleString = true
197 blockCommentEnd: "*/"
165 return "string"
166 }
167 if (ch == "(" && state.inner)
168 state.num_left++
169 if (ch == ")" && state.inner) {
170 state.num_right++
171 if (state.num_left == state.num_right) {
172 state.inner = false
173 state.string = true
174 }
175 return null
176 }
177 if (stream.match(/^-?[0-9\.]/, false)) {
178 if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i) ||
179 stream.match(/^-?\d+\.\d*/) ||
180 stream.match(/^-?\.\d+/)) {
181 if (stream.peek() == ".") stream.backUp(1)
182 return "number"
183 }
184 if (stream.match(/^-?0x[0-9a-f]+/i) ||
185 stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/) ||
186 stream.match(/^-?0(?![\dx])/i))
187 return "number"
188 }
189 if (stream.match(regexPrefixes)) {
190 if (stream.current()!="/" || stream.match(/^.*\//,false)) return "string"
191 else stream.backUp(1)
192 }
193 if (stream.match(delimiters)) return "punctuation"
194 if (stream.match(identifiers)) return "variable"
195 if (stream.match(properties)) return "property"
196 return "variable"
197 }
198 }
199 }
198 }
200 })
199 })
201
200
@@ -11,54 +11,56 b''
11 })(function(CodeMirror) {
11 })(function(CodeMirror) {
12 "use strict";
12 "use strict";
13
13
14 CodeMirror.defineMode("xml", function(config, parserConfig) {
14 var htmlConfig = {
15 var indentUnit = config.indentUnit;
15 autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
16 var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
16 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
17 var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag;
17 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
18 if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true;
18 'track': true, 'wbr': true, 'menuitem': true},
19 implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
20 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
21 'th': true, 'tr': true},
22 contextGrabbers: {
23 'dd': {'dd': true, 'dt': true},
24 'dt': {'dd': true, 'dt': true},
25 'li': {'li': true},
26 'option': {'option': true, 'optgroup': true},
27 'optgroup': {'optgroup': true},
28 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
29 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
30 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
31 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
32 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
33 'rp': {'rp': true, 'rt': true},
34 'rt': {'rp': true, 'rt': true},
35 'tbody': {'tbody': true, 'tfoot': true},
36 'td': {'td': true, 'th': true},
37 'tfoot': {'tbody': true},
38 'th': {'td': true, 'th': true},
39 'thead': {'tbody': true, 'tfoot': true},
40 'tr': {'tr': true}
41 },
42 doNotIndent: {"pre": true},
43 allowUnquoted: true,
44 allowMissing: true,
45 caseFold: true
46 }
19
47
20 var Kludges = parserConfig.htmlMode ? {
48 var xmlConfig = {
21 autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
49 autoSelfClosers: {},
22 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
50 implicitlyClosed: {},
23 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
51 contextGrabbers: {},
24 'track': true, 'wbr': true, 'menuitem': true},
52 doNotIndent: {},
25 implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
53 allowUnquoted: false,
26 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
54 allowMissing: false,
27 'th': true, 'tr': true},
55 caseFold: false
28 contextGrabbers: {
56 }
29 'dd': {'dd': true, 'dt': true},
57
30 'dt': {'dd': true, 'dt': true},
58 CodeMirror.defineMode("xml", function(editorConf, config_) {
31 'li': {'li': true},
59 var indentUnit = editorConf.indentUnit
32 'option': {'option': true, 'optgroup': true},
60 var config = {}
33 'optgroup': {'optgroup': true},
61 var defaults = config_.htmlMode ? htmlConfig : xmlConfig
34 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
62 for (var prop in defaults) config[prop] = defaults[prop]
35 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
63 for (var prop in config_) config[prop] = config_[prop]
36 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
37 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
38 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
39 'rp': {'rp': true, 'rt': true},
40 'rt': {'rp': true, 'rt': true},
41 'tbody': {'tbody': true, 'tfoot': true},
42 'td': {'td': true, 'th': true},
43 'tfoot': {'tbody': true},
44 'th': {'td': true, 'th': true},
45 'thead': {'tbody': true, 'tfoot': true},
46 'tr': {'tr': true}
47 },
48 doNotIndent: {"pre": true},
49 allowUnquoted: true,
50 allowMissing: true,
51 caseFold: true
52 } : {
53 autoSelfClosers: {},
54 implicitlyClosed: {},
55 contextGrabbers: {},
56 doNotIndent: {},
57 allowUnquoted: false,
58 allowMissing: false,
59 caseFold: false
60 };
61 var alignCDATA = parserConfig.alignCDATA;
62
64
63 // Return variables for tokenizers
65 // Return variables for tokenizers
64 var type, setStyle;
66 var type, setStyle;
@@ -109,6 +111,7 b' CodeMirror.defineMode("xml", function(co'
109 return null;
111 return null;
110 }
112 }
111 }
113 }
114 inText.isInText = true;
112
115
113 function inTag(stream, state) {
116 function inTag(stream, state) {
114 var ch = stream.next();
117 var ch = stream.next();
@@ -187,7 +190,7 b' CodeMirror.defineMode("xml", function(co'
187 this.tagName = tagName;
190 this.tagName = tagName;
188 this.indent = state.indented;
191 this.indent = state.indented;
189 this.startOfLine = startOfLine;
192 this.startOfLine = startOfLine;
190 if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
193 if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
191 this.noIndent = true;
194 this.noIndent = true;
192 }
195 }
193 function popContext(state) {
196 function popContext(state) {
@@ -200,8 +203,8 b' CodeMirror.defineMode("xml", function(co'
200 return;
203 return;
201 }
204 }
202 parentTagName = state.context.tagName;
205 parentTagName = state.context.tagName;
203 if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
206 if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
204 !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
207 !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
205 return;
208 return;
206 }
209 }
207 popContext(state);
210 popContext(state);
@@ -232,7 +235,7 b' CodeMirror.defineMode("xml", function(co'
232 if (type == "word") {
235 if (type == "word") {
233 var tagName = stream.current();
236 var tagName = stream.current();
234 if (state.context && state.context.tagName != tagName &&
237 if (state.context && state.context.tagName != tagName &&
235 Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName))
238 config.implicitlyClosed.hasOwnProperty(state.context.tagName))
236 popContext(state);
239 popContext(state);
237 if (state.context && state.context.tagName == tagName) {
240 if (state.context && state.context.tagName == tagName) {
238 setStyle = "tag";
241 setStyle = "tag";
@@ -268,7 +271,7 b' CodeMirror.defineMode("xml", function(co'
268 var tagName = state.tagName, tagStart = state.tagStart;
271 var tagName = state.tagName, tagStart = state.tagStart;
269 state.tagName = state.tagStart = null;
272 state.tagName = state.tagStart = null;
270 if (type == "selfcloseTag" ||
273 if (type == "selfcloseTag" ||
271 Kludges.autoSelfClosers.hasOwnProperty(tagName)) {
274 config.autoSelfClosers.hasOwnProperty(tagName)) {
272 maybePopContext(state, tagName);
275 maybePopContext(state, tagName);
273 } else {
276 } else {
274 maybePopContext(state, tagName);
277 maybePopContext(state, tagName);
@@ -281,12 +284,12 b' CodeMirror.defineMode("xml", function(co'
281 }
284 }
282 function attrEqState(type, stream, state) {
285 function attrEqState(type, stream, state) {
283 if (type == "equals") return attrValueState;
286 if (type == "equals") return attrValueState;
284 if (!Kludges.allowMissing) setStyle = "error";
287 if (!config.allowMissing) setStyle = "error";
285 return attrState(type, stream, state);
288 return attrState(type, stream, state);
286 }
289 }
287 function attrValueState(type, stream, state) {
290 function attrValueState(type, stream, state) {
288 if (type == "string") return attrContinuedState;
291 if (type == "string") return attrContinuedState;
289 if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
292 if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
290 setStyle = "error";
293 setStyle = "error";
291 return attrState(type, stream, state);
294 return attrState(type, stream, state);
292 }
295 }
@@ -296,12 +299,14 b' CodeMirror.defineMode("xml", function(co'
296 }
299 }
297
300
298 return {
301 return {
299 startState: function() {
302 startState: function(baseIndent) {
300 return {tokenize: inText,
303 var state = {tokenize: inText,
301 state: baseState,
304 state: baseState,
302 indented: 0,
305 indented: baseIndent || 0,
303 tagName: null, tagStart: null,
306 tagName: null, tagStart: null,
304 context: null};
307 context: null}
308 if (baseIndent != null) state.baseIndent = baseIndent
309 return state
305 },
310 },
306
311
307 token: function(stream, state) {
312 token: function(stream, state) {
@@ -334,19 +339,19 b' CodeMirror.defineMode("xml", function(co'
334 return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
339 return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
335 // Indent the starts of attribute names.
340 // Indent the starts of attribute names.
336 if (state.tagName) {
341 if (state.tagName) {
337 if (multilineTagIndentPastTag)
342 if (config.multilineTagIndentPastTag !== false)
338 return state.tagStart + state.tagName.length + 2;
343 return state.tagStart + state.tagName.length + 2;
339 else
344 else
340 return state.tagStart + indentUnit * multilineTagIndentFactor;
345 return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
341 }
346 }
342 if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
347 if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
343 var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
348 var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
344 if (tagAfter && tagAfter[1]) { // Closing tag spotted
349 if (tagAfter && tagAfter[1]) { // Closing tag spotted
345 while (context) {
350 while (context) {
346 if (context.tagName == tagAfter[2]) {
351 if (context.tagName == tagAfter[2]) {
347 context = context.prev;
352 context = context.prev;
348 break;
353 break;
349 } else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) {
354 } else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
350 context = context.prev;
355 context = context.prev;
351 } else {
356 } else {
352 break;
357 break;
@@ -354,25 +359,30 b' CodeMirror.defineMode("xml", function(co'
354 }
359 }
355 } else if (tagAfter) { // Opening tag spotted
360 } else if (tagAfter) { // Opening tag spotted
356 while (context) {
361 while (context) {
357 var grabbers = Kludges.contextGrabbers[context.tagName];
362 var grabbers = config.contextGrabbers[context.tagName];
358 if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
363 if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
359 context = context.prev;
364 context = context.prev;
360 else
365 else
361 break;
366 break;
362 }
367 }
363 }
368 }
364 while (context && !context.startOfLine)
369 while (context && context.prev && !context.startOfLine)
365 context = context.prev;
370 context = context.prev;
366 if (context) return context.indent + indentUnit;
371 if (context) return context.indent + indentUnit;
367 else return 0;
372 else return state.baseIndent || 0;
368 },
373 },
369
374
370 electricInput: /<\/[\s\w:]+>$/,
375 electricInput: /<\/[\s\w:]+>$/,
371 blockCommentStart: "<!--",
376 blockCommentStart: "<!--",
372 blockCommentEnd: "-->",
377 blockCommentEnd: "-->",
373
378
374 configuration: parserConfig.htmlMode ? "html" : "xml",
379 configuration: config.htmlMode ? "html" : "xml",
375 helperType: parserConfig.htmlMode ? "html" : "xml"
380 helperType: config.htmlMode ? "html" : "xml",
381
382 skipAttribute: function(state) {
383 if (state.state == attrValueState)
384 state.state = attrState
385 }
376 };
386 };
377 });
387 });
378
388
This diff has been collapsed as it changes many lines, (573 lines changed) Show them Hide them
@@ -13,7 +13,7 b''
13 else if (typeof define == "function" && define.amd) // AMD
13 else if (typeof define == "function" && define.amd) // AMD
14 return define([], mod);
14 return define([], mod);
15 else // Plain browser env
15 else // Plain browser env
16 this.CodeMirror = mod();
16 (this || window).CodeMirror = mod();
17 })(function() {
17 })(function() {
18 "use strict";
18 "use strict";
19
19
@@ -21,27 +21,29 b''
21
21
22 // Kludges for bugs and behavior differences that can't be feature
22 // Kludges for bugs and behavior differences that can't be feature
23 // detected are enabled based on userAgent etc sniffing.
23 // detected are enabled based on userAgent etc sniffing.
24
24 var userAgent = navigator.userAgent;
25 var gecko = /gecko\/\d/i.test(navigator.userAgent);
25 var platform = navigator.platform;
26 var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
26
27 var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
27 var gecko = /gecko\/\d/i.test(userAgent);
28 var ie_upto10 = /MSIE \d/.test(userAgent);
29 var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent);
28 var ie = ie_upto10 || ie_11up;
30 var ie = ie_upto10 || ie_11up;
29 var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
31 var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
30 var webkit = /WebKit\//.test(navigator.userAgent);
32 var webkit = /WebKit\//.test(userAgent);
31 var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
33 var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent);
32 var chrome = /Chrome\//.test(navigator.userAgent);
34 var chrome = /Chrome\//.test(userAgent);
33 var presto = /Opera\//.test(navigator.userAgent);
35 var presto = /Opera\//.test(userAgent);
34 var safari = /Apple Computer/.test(navigator.vendor);
36 var safari = /Apple Computer/.test(navigator.vendor);
35 var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
37 var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);
36 var phantom = /PhantomJS/.test(navigator.userAgent);
38 var phantom = /PhantomJS/.test(userAgent);
37
39
38 var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
40 var ios = /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent);
39 // This is woefully incomplete. Suggestions for alternative methods welcome.
41 // This is woefully incomplete. Suggestions for alternative methods welcome.
40 var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
42 var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent);
41 var mac = ios || /Mac/.test(navigator.platform);
43 var mac = ios || /Mac/.test(platform);
42 var windows = /win/i.test(navigator.platform);
44 var windows = /win/i.test(platform);
43
45
44 var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
46 var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/);
45 if (presto_version) presto_version = Number(presto_version[1]);
47 if (presto_version) presto_version = Number(presto_version[1]);
46 if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
48 if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
47 // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
49 // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
@@ -65,7 +67,7 b''
65 setGuttersForLineNumbers(options);
67 setGuttersForLineNumbers(options);
66
68
67 var doc = options.value;
69 var doc = options.value;
68 if (typeof doc == "string") doc = new Doc(doc, options.mode);
70 if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator);
69 this.doc = doc;
71 this.doc = doc;
70
72
71 var input = new CodeMirror.inputStyles[options.inputStyle](this);
73 var input = new CodeMirror.inputStyles[options.inputStyle](this);
@@ -87,6 +89,7 b''
87 focused: false,
89 focused: false,
88 suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
90 suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
89 pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll
91 pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll
92 selectingText: false,
90 draggingText: false,
93 draggingText: false,
91 highlight: new Delayed(), // stores highlight worker timeout
94 highlight: new Delayed(), // stores highlight worker timeout
92 keySeq: null, // Unfinished key sequence
95 keySeq: null, // Unfinished key sequence
@@ -407,7 +410,7 b''
407 if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal");
410 if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal");
408 });
411 });
409
412
410 this.checkedOverlay = false;
413 this.checkedZeroWidth = false;
411 // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
414 // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
412 if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px";
415 if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px";
413 }
416 }
@@ -442,29 +445,43 b''
442 this.horiz.firstChild.style.width = "0";
445 this.horiz.firstChild.style.width = "0";
443 }
446 }
444
447
445 if (!this.checkedOverlay && measure.clientHeight > 0) {
448 if (!this.checkedZeroWidth && measure.clientHeight > 0) {
446 if (sWidth == 0) this.overlayHack();
449 if (sWidth == 0) this.zeroWidthHack();
447 this.checkedOverlay = true;
450 this.checkedZeroWidth = true;
448 }
451 }
449
452
450 return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};
453 return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};
451 },
454 },
452 setScrollLeft: function(pos) {
455 setScrollLeft: function(pos) {
453 if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;
456 if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;
457 if (this.disableHoriz) this.enableZeroWidthBar(this.horiz, this.disableHoriz);
454 },
458 },
455 setScrollTop: function(pos) {
459 setScrollTop: function(pos) {
456 if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;
460 if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;
457 },
461 if (this.disableVert) this.enableZeroWidthBar(this.vert, this.disableVert);
458 overlayHack: function() {
462 },
463 zeroWidthHack: function() {
459 var w = mac && !mac_geMountainLion ? "12px" : "18px";
464 var w = mac && !mac_geMountainLion ? "12px" : "18px";
460 this.horiz.style.minHeight = this.vert.style.minWidth = w;
465 this.horiz.style.height = this.vert.style.width = w;
461 var self = this;
466 this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none";
462 var barMouseDown = function(e) {
467 this.disableHoriz = new Delayed;
463 if (e_target(e) != self.vert && e_target(e) != self.horiz)
468 this.disableVert = new Delayed;
464 operation(self.cm, onMouseDown)(e);
469 },
465 };
470 enableZeroWidthBar: function(bar, delay) {
466 on(this.vert, "mousedown", barMouseDown);
471 bar.style.pointerEvents = "auto";
467 on(this.horiz, "mousedown", barMouseDown);
472 function maybeDisable() {
473 // To find out whether the scrollbar is still visible, we
474 // check whether the element under the pixel in the bottom
475 // left corner of the scrollbar box is the scrollbar box
476 // itself (when the bar is still visible) or its filler child
477 // (when the bar is hidden). If it is still visible, we keep
478 // it enabled, if it's hidden, we disable pointer events.
479 var box = bar.getBoundingClientRect();
480 var elt = document.elementFromPoint(box.left + 1, box.bottom - 1);
481 if (elt != bar) bar.style.pointerEvents = "none";
482 else delay.set(1000, maybeDisable);
483 }
484 delay.set(1000, maybeDisable);
468 },
485 },
469 clear: function() {
486 clear: function() {
470 var parent = this.horiz.parentNode;
487 var parent = this.horiz.parentNode;
@@ -714,7 +731,7 b''
714 // width and height.
731 // width and height.
715 removeChildren(display.cursorDiv);
732 removeChildren(display.cursorDiv);
716 removeChildren(display.selectionDiv);
733 removeChildren(display.selectionDiv);
717 display.gutters.style.height = 0;
734 display.gutters.style.height = display.sizer.style.minHeight = 0;
718
735
719 if (different) {
736 if (different) {
720 display.lastWrapHeight = update.wrapperHeight;
737 display.lastWrapHeight = update.wrapperHeight;
@@ -806,7 +823,7 b''
806 // given line.
823 // given line.
807 function updateWidgetHeight(line) {
824 function updateWidgetHeight(line) {
808 if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
825 if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
809 line.widgets[i].height = line.widgets[i].node.offsetHeight;
826 line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight;
810 }
827 }
811
828
812 // Do a bulk-read of the DOM positions and sizes needed to draw the
829 // Do a bulk-read of the DOM positions and sizes needed to draw the
@@ -955,12 +972,22 b''
955 lineView.node.removeChild(lineView.gutter);
972 lineView.node.removeChild(lineView.gutter);
956 lineView.gutter = null;
973 lineView.gutter = null;
957 }
974 }
975 if (lineView.gutterBackground) {
976 lineView.node.removeChild(lineView.gutterBackground);
977 lineView.gutterBackground = null;
978 }
979 if (lineView.line.gutterClass) {
980 var wrap = ensureLineWrapped(lineView);
981 lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
982 "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
983 "px; width: " + dims.gutterTotalWidth + "px");
984 wrap.insertBefore(lineView.gutterBackground, lineView.text);
985 }
958 var markers = lineView.line.gutterMarkers;
986 var markers = lineView.line.gutterMarkers;
959 if (cm.options.lineNumbers || markers) {
987 if (cm.options.lineNumbers || markers) {
960 var wrap = ensureLineWrapped(lineView);
988 var wrap = ensureLineWrapped(lineView);
961 var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " +
989 var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " +
962 (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
990 (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px");
963 "px; width: " + dims.gutterTotalWidth + "px");
964 cm.display.input.setUneditable(gutterWrap);
991 cm.display.input.setUneditable(gutterWrap);
965 wrap.insertBefore(gutterWrap, lineView.text);
992 wrap.insertBefore(gutterWrap, lineView.text);
966 if (lineView.line.gutterClass)
993 if (lineView.line.gutterClass)
@@ -1067,10 +1094,6 b''
1067 if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
1094 if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
1068 }
1095 }
1069
1096
1070 function isReadOnly(cm) {
1071 return cm.options.readOnly || cm.doc.cantEdit;
1072 }
1073
1074 // This will be set to an array of strings when copying, so that,
1097 // This will be set to an array of strings when copying, so that,
1075 // when pasting, we know what kind of selections the copied text
1098 // when pasting, we know what kind of selections the copied text
1076 // was made out of.
1099 // was made out of.
@@ -1082,13 +1105,18 b''
1082 if (!sel) sel = doc.sel;
1105 if (!sel) sel = doc.sel;
1083
1106
1084 var paste = cm.state.pasteIncoming || origin == "paste";
1107 var paste = cm.state.pasteIncoming || origin == "paste";
1085 var textLines = splitLines(inserted), multiPaste = null;
1108 var textLines = doc.splitLines(inserted), multiPaste = null;
1086 // When pasing N lines into N selections, insert one line per selection
1109 // When pasing N lines into N selections, insert one line per selection
1087 if (paste && sel.ranges.length > 1) {
1110 if (paste && sel.ranges.length > 1) {
1088 if (lastCopied && lastCopied.join("\n") == inserted)
1111 if (lastCopied && lastCopied.join("\n") == inserted) {
1089 multiPaste = sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines);
1112 if (sel.ranges.length % lastCopied.length == 0) {
1090 else if (textLines.length == sel.ranges.length)
1113 multiPaste = [];
1114 for (var i = 0; i < lastCopied.length; i++)
1115 multiPaste.push(doc.splitLines(lastCopied[i]));
1116 }
1117 } else if (textLines.length == sel.ranges.length) {
1091 multiPaste = map(textLines, function(l) { return [l]; });
1118 multiPaste = map(textLines, function(l) { return [l]; });
1119 }
1092 }
1120 }
1093
1121
1094 // Normal behavior is to insert the new text into every selection
1122 // Normal behavior is to insert the new text into every selection
@@ -1120,7 +1148,8 b''
1120 var pasted = e.clipboardData && e.clipboardData.getData("text/plain");
1148 var pasted = e.clipboardData && e.clipboardData.getData("text/plain");
1121 if (pasted) {
1149 if (pasted) {
1122 e.preventDefault();
1150 e.preventDefault();
1123 runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); });
1151 if (!cm.isReadOnly() && !cm.options.disableInput)
1152 runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); });
1124 return true;
1153 return true;
1125 }
1154 }
1126 }
1155 }
@@ -1222,13 +1251,14 b''
1222 });
1251 });
1223
1252
1224 on(te, "paste", function(e) {
1253 on(te, "paste", function(e) {
1225 if (handlePaste(e, cm)) return true;
1254 if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return
1226
1255
1227 cm.state.pasteIncoming = true;
1256 cm.state.pasteIncoming = true;
1228 input.fastPoll();
1257 input.fastPoll();
1229 });
1258 });
1230
1259
1231 function prepareCopyCut(e) {
1260 function prepareCopyCut(e) {
1261 if (signalDOMEvent(cm, e)) return
1232 if (cm.somethingSelected()) {
1262 if (cm.somethingSelected()) {
1233 lastCopied = cm.getSelections();
1263 lastCopied = cm.getSelections();
1234 if (input.inaccurateSelection) {
1264 if (input.inaccurateSelection) {
@@ -1256,7 +1286,7 b''
1256 on(te, "copy", prepareCopyCut);
1286 on(te, "copy", prepareCopyCut);
1257
1287
1258 on(display.scroller, "paste", function(e) {
1288 on(display.scroller, "paste", function(e) {
1259 if (eventInWidget(display, e)) return;
1289 if (eventInWidget(display, e) || signalDOMEvent(cm, e)) return;
1260 cm.state.pasteIncoming = true;
1290 cm.state.pasteIncoming = true;
1261 input.focus();
1291 input.focus();
1262 });
1292 });
@@ -1268,6 +1298,7 b''
1268
1298
1269 on(te, "compositionstart", function() {
1299 on(te, "compositionstart", function() {
1270 var start = cm.getCursor("from");
1300 var start = cm.getCursor("from");
1301 if (input.composing) input.composing.range.clear()
1271 input.composing = {
1302 input.composing = {
1272 start: start,
1303 start: start,
1273 range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
1304 range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
@@ -1388,8 +1419,8 b''
1388 // will be the case when there is a lot of text in the textarea,
1419 // will be the case when there is a lot of text in the textarea,
1389 // in which case reading its value would be expensive.
1420 // in which case reading its value would be expensive.
1390 if (this.contextMenuPending || !cm.state.focused ||
1421 if (this.contextMenuPending || !cm.state.focused ||
1391 (hasSelection(input) && !prevInput) ||
1422 (hasSelection(input) && !prevInput && !this.composing) ||
1392 isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq)
1423 cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq)
1393 return false;
1424 return false;
1394
1425
1395 var text = input.value;
1426 var text = input.value;
@@ -1516,6 +1547,10 b''
1516 }
1547 }
1517 },
1548 },
1518
1549
1550 readOnlyChanged: function(val) {
1551 if (!val) this.reset();
1552 },
1553
1519 setUneditable: nothing,
1554 setUneditable: nothing,
1520
1555
1521 needsContentAttribute: false
1556 needsContentAttribute: false
@@ -1534,10 +1569,11 b''
1534 init: function(display) {
1569 init: function(display) {
1535 var input = this, cm = input.cm;
1570 var input = this, cm = input.cm;
1536 var div = input.div = display.lineDiv;
1571 var div = input.div = display.lineDiv;
1537 div.contentEditable = "true";
1538 disableBrowserMagic(div);
1572 disableBrowserMagic(div);
1539
1573
1540 on(div, "paste", function(e) { handlePaste(e, cm); })
1574 on(div, "paste", function(e) {
1575 if (!signalDOMEvent(cm, e)) handlePaste(e, cm);
1576 })
1541
1577
1542 on(div, "compositionstart", function(e) {
1578 on(div, "compositionstart", function(e) {
1543 var data = e.data;
1579 var data = e.data;
@@ -1575,11 +1611,12 b''
1575
1611
1576 on(div, "input", function() {
1612 on(div, "input", function() {
1577 if (input.composing) return;
1613 if (input.composing) return;
1578 if (!input.pollContent())
1614 if (cm.isReadOnly() || !input.pollContent())
1579 runInOp(input.cm, function() {regChange(cm);});
1615 runInOp(input.cm, function() {regChange(cm);});
1580 });
1616 });
1581
1617
1582 function onCopyCut(e) {
1618 function onCopyCut(e) {
1619 if (signalDOMEvent(cm, e)) return
1583 if (cm.somethingSelected()) {
1620 if (cm.somethingSelected()) {
1584 lastCopied = cm.getSelections();
1621 lastCopied = cm.getSelections();
1585 if (e.type == "cut") cm.replaceSelection("", null, "cut");
1622 if (e.type == "cut") cm.replaceSelection("", null, "cut");
@@ -1655,8 +1692,13 b''
1655 try { var rng = range(start.node, start.offset, end.offset, end.node); }
1692 try { var rng = range(start.node, start.offset, end.offset, end.node); }
1656 catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
1693 catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
1657 if (rng) {
1694 if (rng) {
1658 sel.removeAllRanges();
1695 if (!gecko && this.cm.state.focused) {
1659 sel.addRange(rng);
1696 sel.collapse(start.node, start.offset);
1697 if (!rng.collapsed) sel.addRange(rng);
1698 } else {
1699 sel.removeAllRanges();
1700 sel.addRange(rng);
1701 }
1660 if (old && sel.anchorNode == null) sel.addRange(old);
1702 if (old && sel.anchorNode == null) sel.addRange(old);
1661 else if (gecko) this.startGracePeriod();
1703 else if (gecko) this.startGracePeriod();
1662 }
1704 }
@@ -1756,7 +1798,7 b''
1756 var toNode = display.view[toIndex + 1].node.previousSibling;
1798 var toNode = display.view[toIndex + 1].node.previousSibling;
1757 }
1799 }
1758
1800
1759 var newText = splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
1801 var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
1760 var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
1802 var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
1761 while (newText.length > 1 && oldText.length > 1) {
1803 while (newText.length > 1 && oldText.length > 1) {
1762 if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
1804 if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
@@ -1800,17 +1842,24 b''
1800 this.div.focus();
1842 this.div.focus();
1801 },
1843 },
1802 applyComposition: function(composing) {
1844 applyComposition: function(composing) {
1803 if (composing.data && composing.data != composing.startData)
1845 if (this.cm.isReadOnly())
1846 operation(this.cm, regChange)(this.cm)
1847 else if (composing.data && composing.data != composing.startData)
1804 operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel);
1848 operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel);
1805 },
1849 },
1806
1850
1807 setUneditable: function(node) {
1851 setUneditable: function(node) {
1808 node.setAttribute("contenteditable", "false");
1852 node.contentEditable = "false"
1809 },
1853 },
1810
1854
1811 onKeyPress: function(e) {
1855 onKeyPress: function(e) {
1812 e.preventDefault();
1856 e.preventDefault();
1813 operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0);
1857 if (!this.cm.isReadOnly())
1858 operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0);
1859 },
1860
1861 readOnlyChanged: function(val) {
1862 this.div.contentEditable = String(val != "nocursor")
1814 },
1863 },
1815
1864
1816 onContextMenu: nothing,
1865 onContextMenu: nothing,
@@ -1912,7 +1961,7 b''
1912 }
1961 }
1913
1962
1914 function domTextBetween(cm, from, to, fromLine, toLine) {
1963 function domTextBetween(cm, from, to, fromLine, toLine) {
1915 var text = "", closing = false;
1964 var text = "", closing = false, lineSep = cm.doc.lineSeparator();
1916 function recognizeMarker(id) { return function(marker) { return marker.id == id; }; }
1965 function recognizeMarker(id) { return function(marker) { return marker.id == id; }; }
1917 function walk(node) {
1966 function walk(node) {
1918 if (node.nodeType == 1) {
1967 if (node.nodeType == 1) {
@@ -1926,7 +1975,7 b''
1926 if (markerID) {
1975 if (markerID) {
1927 var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
1976 var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
1928 if (found.length && (range = found[0].find()))
1977 if (found.length && (range = found[0].find()))
1929 text += getBetween(cm.doc, range.from, range.to).join("\n");
1978 text += getBetween(cm.doc, range.from, range.to).join(lineSep);
1930 return;
1979 return;
1931 }
1980 }
1932 if (node.getAttribute("contenteditable") == "false") return;
1981 if (node.getAttribute("contenteditable") == "false") return;
@@ -1938,7 +1987,7 b''
1938 var val = node.nodeValue;
1987 var val = node.nodeValue;
1939 if (!val) return;
1988 if (!val) return;
1940 if (closing) {
1989 if (closing) {
1941 text += "\n";
1990 text += lineSep;
1942 closing = false;
1991 closing = false;
1943 }
1992 }
1944 text += val;
1993 text += val;
@@ -2110,7 +2159,7 b''
2110
2159
2111 // Give beforeSelectionChange handlers a change to influence a
2160 // Give beforeSelectionChange handlers a change to influence a
2112 // selection update.
2161 // selection update.
2113 function filterSelectionChange(doc, sel) {
2162 function filterSelectionChange(doc, sel, options) {
2114 var obj = {
2163 var obj = {
2115 ranges: sel.ranges,
2164 ranges: sel.ranges,
2116 update: function(ranges) {
2165 update: function(ranges) {
@@ -2118,7 +2167,8 b''
2118 for (var i = 0; i < ranges.length; i++)
2167 for (var i = 0; i < ranges.length; i++)
2119 this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
2168 this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
2120 clipPos(doc, ranges[i].head));
2169 clipPos(doc, ranges[i].head));
2121 }
2170 },
2171 origin: options && options.origin
2122 };
2172 };
2123 signal(doc, "beforeSelectionChange", doc, obj);
2173 signal(doc, "beforeSelectionChange", doc, obj);
2124 if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
2174 if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
@@ -2144,7 +2194,7 b''
2144
2194
2145 function setSelectionNoUndo(doc, sel, options) {
2195 function setSelectionNoUndo(doc, sel, options) {
2146 if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
2196 if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
2147 sel = filterSelectionChange(doc, sel);
2197 sel = filterSelectionChange(doc, sel, options);
2148
2198
2149 var bias = options && options.bias ||
2199 var bias = options && options.bias ||
2150 (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
2200 (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
@@ -2178,8 +2228,9 b''
2178 var out;
2228 var out;
2179 for (var i = 0; i < sel.ranges.length; i++) {
2229 for (var i = 0; i < sel.ranges.length; i++) {
2180 var range = sel.ranges[i];
2230 var range = sel.ranges[i];
2181 var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);
2231 var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i];
2182 var newHead = skipAtomic(doc, range.head, bias, mayClear);
2232 var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear);
2233 var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear);
2183 if (out || newAnchor != range.anchor || newHead != range.head) {
2234 if (out || newAnchor != range.anchor || newHead != range.head) {
2184 if (!out) out = sel.ranges.slice(0, i);
2235 if (!out) out = sel.ranges.slice(0, i);
2185 out[i] = new Range(newAnchor, newHead);
2236 out[i] = new Range(newAnchor, newHead);
@@ -2188,54 +2239,59 b''
2188 return out ? normalizeSelection(out, sel.primIndex) : sel;
2239 return out ? normalizeSelection(out, sel.primIndex) : sel;
2189 }
2240 }
2190
2241
2191 // Ensure a given position is not inside an atomic range.
2242 function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
2192 function skipAtomic(doc, pos, bias, mayClear) {
2243 var line = getLine(doc, pos.line);
2193 var flipped = false, curPos = pos;
2244 if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
2194 var dir = bias || 1;
2245 var sp = line.markedSpans[i], m = sp.marker;
2195 doc.cantEdit = false;
2246 if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
2196 search: for (;;) {
2247 (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
2197 var line = getLine(doc, curPos.line);
2248 if (mayClear) {
2198 if (line.markedSpans) {
2249 signal(m, "beforeCursorEnter");
2199 for (var i = 0; i < line.markedSpans.length; ++i) {
2250 if (m.explicitlyCleared) {
2200 var sp = line.markedSpans[i], m = sp.marker;
2251 if (!line.markedSpans) break;
2201 if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
2252 else {--i; continue;}
2202 (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
2203 if (mayClear) {
2204 signal(m, "beforeCursorEnter");
2205 if (m.explicitlyCleared) {
2206 if (!line.markedSpans) break;
2207 else {--i; continue;}
2208 }
2209 }
2210 if (!m.atomic) continue;
2211 var newPos = m.find(dir < 0 ? -1 : 1);
2212 if (cmp(newPos, curPos) == 0) {
2213 newPos.ch += dir;
2214 if (newPos.ch < 0) {
2215 if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
2216 else newPos = null;
2217 } else if (newPos.ch > line.text.length) {
2218 if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
2219 else newPos = null;
2220 }
2221 if (!newPos) {
2222 if (flipped) {
2223 // Driven in a corner -- no valid cursor position found at all
2224 // -- try again *with* clearing, if we didn't already
2225 if (!mayClear) return skipAtomic(doc, pos, bias, true);
2226 // Otherwise, turn off editing until further notice, and return the start of the doc
2227 doc.cantEdit = true;
2228 return Pos(doc.first, 0);
2229 }
2230 flipped = true; newPos = pos; dir = -dir;
2231 }
2232 }
2233 curPos = newPos;
2234 continue search;
2235 }
2253 }
2236 }
2254 }
2237 }
2255 if (!m.atomic) continue;
2238 return curPos;
2256
2257 if (oldPos) {
2258 var near = m.find(dir < 0 ? 1 : -1), diff;
2259 if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) near = movePos(doc, near, -dir, line);
2260 if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
2261 return skipAtomicInner(doc, near, pos, dir, mayClear);
2262 }
2263
2264 var far = m.find(dir < 0 ? -1 : 1);
2265 if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) far = movePos(doc, far, dir, line);
2266 return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null;
2267 }
2268 }
2269 return pos;
2270 }
2271
2272 // Ensure a given position is not inside an atomic range.
2273 function skipAtomic(doc, pos, oldPos, bias, mayClear) {
2274 var dir = bias || 1;
2275 var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||
2276 (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||
2277 skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||
2278 (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true));
2279 if (!found) {
2280 doc.cantEdit = true;
2281 return Pos(doc.first, 0);
2282 }
2283 return found;
2284 }
2285
2286 function movePos(doc, pos, dir, line) {
2287 if (dir < 0 && pos.ch == 0) {
2288 if (pos.line > doc.first) return clipPos(doc, Pos(pos.line - 1));
2289 else return null;
2290 } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {
2291 if (pos.line < doc.first + doc.size - 1) return Pos(pos.line + 1, 0);
2292 else return null;
2293 } else {
2294 return new Pos(pos.line, pos.ch + dir);
2239 }
2295 }
2240 }
2296 }
2241
2297
@@ -2255,7 +2311,7 b''
2255 var range = doc.sel.ranges[i];
2311 var range = doc.sel.ranges[i];
2256 var collapsed = range.empty();
2312 var collapsed = range.empty();
2257 if (collapsed || cm.options.showCursorWhenSelecting)
2313 if (collapsed || cm.options.showCursorWhenSelecting)
2258 drawSelectionCursor(cm, range, curFragment);
2314 drawSelectionCursor(cm, range.head, curFragment);
2259 if (!collapsed)
2315 if (!collapsed)
2260 drawSelectionRange(cm, range, selFragment);
2316 drawSelectionRange(cm, range, selFragment);
2261 }
2317 }
@@ -2263,8 +2319,8 b''
2263 }
2319 }
2264
2320
2265 // Draws a cursor for the given range
2321 // Draws a cursor for the given range
2266 function drawSelectionCursor(cm, range, output) {
2322 function drawSelectionCursor(cm, head, output) {
2267 var pos = cursorCoords(cm, range.head, "div", null, null, !cm.options.singleCursorHeightPerLine);
2323 var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine);
2268
2324
2269 var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
2325 var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
2270 cursor.style.left = pos.left + "px";
2326 cursor.style.left = pos.left + "px";
@@ -2388,8 +2444,8 b''
2388
2444
2389 doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
2445 doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
2390 if (doc.frontier >= cm.display.viewFrom) { // Visible
2446 if (doc.frontier >= cm.display.viewFrom) { // Visible
2391 var oldStyles = line.styles;
2447 var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength;
2392 var highlighted = highlightLine(cm, line, state, true);
2448 var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true);
2393 line.styles = highlighted.styles;
2449 line.styles = highlighted.styles;
2394 var oldCls = line.styleClasses, newCls = highlighted.classes;
2450 var oldCls = line.styleClasses, newCls = highlighted.classes;
2395 if (newCls) line.styleClasses = newCls;
2451 if (newCls) line.styleClasses = newCls;
@@ -2398,9 +2454,10 b''
2398 oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
2454 oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
2399 for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
2455 for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
2400 if (ischange) changedLines.push(doc.frontier);
2456 if (ischange) changedLines.push(doc.frontier);
2401 line.stateAfter = copyState(doc.mode, state);
2457 line.stateAfter = tooLong ? state : copyState(doc.mode, state);
2402 } else {
2458 } else {
2403 processLine(cm, line.text, state);
2459 if (line.text.length <= cm.options.maxHighlightLength)
2460 processLine(cm, line.text, state);
2404 line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
2461 line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
2405 }
2462 }
2406 ++doc.frontier;
2463 ++doc.frontier;
@@ -2545,10 +2602,12 b''
2545 function prepareMeasureForLine(cm, line) {
2602 function prepareMeasureForLine(cm, line) {
2546 var lineN = lineNo(line);
2603 var lineN = lineNo(line);
2547 var view = findViewForLine(cm, lineN);
2604 var view = findViewForLine(cm, lineN);
2548 if (view && !view.text)
2605 if (view && !view.text) {
2549 view = null;
2606 view = null;
2550 else if (view && view.changes)
2607 } else if (view && view.changes) {
2551 updateLineForChanges(cm, view, lineN, getDimensions(cm));
2608 updateLineForChanges(cm, view, lineN, getDimensions(cm));
2609 cm.curOp.forceUpdate = true;
2610 }
2552 if (!view)
2611 if (!view)
2553 view = updateExternalMeasurement(cm, line);
2612 view = updateExternalMeasurement(cm, line);
2554
2613
@@ -2961,12 +3020,12 b''
2961 var callbacks = group.delayedCallbacks, i = 0;
3020 var callbacks = group.delayedCallbacks, i = 0;
2962 do {
3021 do {
2963 for (; i < callbacks.length; i++)
3022 for (; i < callbacks.length; i++)
2964 callbacks[i]();
3023 callbacks[i].call(null);
2965 for (var j = 0; j < group.ops.length; j++) {
3024 for (var j = 0; j < group.ops.length; j++) {
2966 var op = group.ops[j];
3025 var op = group.ops[j];
2967 if (op.cursorActivityHandlers)
3026 if (op.cursorActivityHandlers)
2968 while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
3027 while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
2969 op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm);
3028 op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm);
2970 }
3029 }
2971 } while (i < callbacks.length);
3030 } while (i < callbacks.length);
2972 }
3031 }
@@ -3060,7 +3119,8 b''
3060
3119
3061 if (cm.state.focused && op.updateInput)
3120 if (cm.state.focused && op.updateInput)
3062 cm.display.input.reset(op.typing);
3121 cm.display.input.reset(op.typing);
3063 if (op.focus && op.focus == activeElt()) ensureFocus(op.cm);
3122 if (op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus()))
3123 ensureFocus(op.cm);
3064 }
3124 }
3065
3125
3066 function endOperation_finish(op) {
3126 function endOperation_finish(op) {
@@ -3375,7 +3435,7 b''
3375 return dx * dx + dy * dy > 20 * 20;
3435 return dx * dx + dy * dy > 20 * 20;
3376 }
3436 }
3377 on(d.scroller, "touchstart", function(e) {
3437 on(d.scroller, "touchstart", function(e) {
3378 if (!isMouseLikeTouchEvent(e)) {
3438 if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) {
3379 clearTimeout(touchFinished);
3439 clearTimeout(touchFinished);
3380 var now = +new Date;
3440 var now = +new Date;
3381 d.activeTouch = {start: now, moved: false,
3441 d.activeTouch = {start: now, moved: false,
@@ -3426,9 +3486,11 b''
3426 on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
3486 on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
3427
3487
3428 d.dragFunctions = {
3488 d.dragFunctions = {
3429 simple: function(e) {if (!signalDOMEvent(cm, e)) e_stop(e);},
3489 enter: function(e) {if (!signalDOMEvent(cm, e)) e_stop(e);},
3490 over: function(e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); }},
3430 start: function(e){onDragStart(cm, e);},
3491 start: function(e){onDragStart(cm, e);},
3431 drop: operation(cm, onDrop)
3492 drop: operation(cm, onDrop),
3493 leave: function() {clearDragCursor(cm);}
3432 };
3494 };
3433
3495
3434 var inp = d.input.getField();
3496 var inp = d.input.getField();
@@ -3445,8 +3507,9 b''
3445 var funcs = cm.display.dragFunctions;
3507 var funcs = cm.display.dragFunctions;
3446 var toggle = value ? on : off;
3508 var toggle = value ? on : off;
3447 toggle(cm.display.scroller, "dragstart", funcs.start);
3509 toggle(cm.display.scroller, "dragstart", funcs.start);
3448 toggle(cm.display.scroller, "dragenter", funcs.simple);
3510 toggle(cm.display.scroller, "dragenter", funcs.enter);
3449 toggle(cm.display.scroller, "dragover", funcs.simple);
3511 toggle(cm.display.scroller, "dragover", funcs.over);
3512 toggle(cm.display.scroller, "dragleave", funcs.leave);
3450 toggle(cm.display.scroller, "drop", funcs.drop);
3513 toggle(cm.display.scroller, "drop", funcs.drop);
3451 }
3514 }
3452 }
3515 }
@@ -3501,7 +3564,7 b''
3501 // not interfere with, such as a scrollbar or widget.
3564 // not interfere with, such as a scrollbar or widget.
3502 function onMouseDown(e) {
3565 function onMouseDown(e) {
3503 var cm = this, display = cm.display;
3566 var cm = this, display = cm.display;
3504 if (display.activeTouch && display.input.supportsTouch() || signalDOMEvent(cm, e)) return;
3567 if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) return;
3505 display.shift = e.shiftKey;
3568 display.shift = e.shiftKey;
3506
3569
3507 if (eventInWidget(display, e)) {
3570 if (eventInWidget(display, e)) {
@@ -3519,7 +3582,10 b''
3519
3582
3520 switch (e_button(e)) {
3583 switch (e_button(e)) {
3521 case 1:
3584 case 1:
3522 if (start)
3585 // #3261: make sure, that we're not starting a second selection
3586 if (cm.state.selectingText)
3587 cm.state.selectingText(e);
3588 else if (start)
3523 leftButtonDown(cm, e, start);
3589 leftButtonDown(cm, e, start);
3524 else if (e_target(e) == display.scroller)
3590 else if (e_target(e) == display.scroller)
3525 e_preventDefault(e);
3591 e_preventDefault(e);
@@ -3554,7 +3620,7 b''
3554 }
3620 }
3555
3621
3556 var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained;
3622 var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained;
3557 if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&
3623 if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&
3558 type == "single" && (contained = sel.contains(start)) > -1 &&
3624 type == "single" && (contained = sel.contains(start)) > -1 &&
3559 (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) &&
3625 (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) &&
3560 (cmp(contained.to(), start) > 0 || start.xRel < 0))
3626 (cmp(contained.to(), start) > 0 || start.xRel < 0))
@@ -3639,7 +3705,8 b''
3639 setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
3705 setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
3640 {scroll: false, origin: "*mouse"});
3706 {scroll: false, origin: "*mouse"});
3641 } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) {
3707 } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) {
3642 setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0));
3708 setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
3709 {scroll: false, origin: "*mouse"});
3643 startSel = doc.sel;
3710 startSel = doc.sel;
3644 } else {
3711 } else {
3645 replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
3712 replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
@@ -3717,6 +3784,7 b''
3717 }
3784 }
3718
3785
3719 function done(e) {
3786 function done(e) {
3787 cm.state.selectingText = false;
3720 counter = Infinity;
3788 counter = Infinity;
3721 e_preventDefault(e);
3789 e_preventDefault(e);
3722 display.input.focus();
3790 display.input.focus();
@@ -3730,13 +3798,14 b''
3730 else extend(e);
3798 else extend(e);
3731 });
3799 });
3732 var up = operation(cm, done);
3800 var up = operation(cm, done);
3801 cm.state.selectingText = up;
3733 on(document, "mousemove", move);
3802 on(document, "mousemove", move);
3734 on(document, "mouseup", up);
3803 on(document, "mouseup", up);
3735 }
3804 }
3736
3805
3737 // Determines whether an event happened in the gutter, and fires the
3806 // Determines whether an event happened in the gutter, and fires the
3738 // handlers for the corresponding event.
3807 // handlers for the corresponding event.
3739 function gutterEvent(cm, e, type, prevent, signalfn) {
3808 function gutterEvent(cm, e, type, prevent) {
3740 try { var mX = e.clientX, mY = e.clientY; }
3809 try { var mX = e.clientX, mY = e.clientY; }
3741 catch(e) { return false; }
3810 catch(e) { return false; }
3742 if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
3811 if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
@@ -3753,14 +3822,14 b''
3753 if (g && g.getBoundingClientRect().right >= mX) {
3822 if (g && g.getBoundingClientRect().right >= mX) {
3754 var line = lineAtHeight(cm.doc, mY);
3823 var line = lineAtHeight(cm.doc, mY);
3755 var gutter = cm.options.gutters[i];
3824 var gutter = cm.options.gutters[i];
3756 signalfn(cm, type, cm, line, gutter, e);
3825 signal(cm, type, cm, line, gutter, e);
3757 return e_defaultPrevented(e);
3826 return e_defaultPrevented(e);
3758 }
3827 }
3759 }
3828 }
3760 }
3829 }
3761
3830
3762 function clickInGutter(cm, e) {
3831 function clickInGutter(cm, e) {
3763 return gutterEvent(cm, e, "gutterClick", true, signalLater);
3832 return gutterEvent(cm, e, "gutterClick", true);
3764 }
3833 }
3765
3834
3766 // Kludge to work around strange IE behavior where it'll sometimes
3835 // Kludge to work around strange IE behavior where it'll sometimes
@@ -3769,23 +3838,32 b''
3769
3838
3770 function onDrop(e) {
3839 function onDrop(e) {
3771 var cm = this;
3840 var cm = this;
3841 clearDragCursor(cm);
3772 if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
3842 if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
3773 return;
3843 return;
3774 e_preventDefault(e);
3844 e_preventDefault(e);
3775 if (ie) lastDrop = +new Date;
3845 if (ie) lastDrop = +new Date;
3776 var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
3846 var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
3777 if (!pos || isReadOnly(cm)) return;
3847 if (!pos || cm.isReadOnly()) return;
3778 // Might be a file drop, in which case we simply extract the text
3848 // Might be a file drop, in which case we simply extract the text
3779 // and insert it.
3849 // and insert it.
3780 if (files && files.length && window.FileReader && window.File) {
3850 if (files && files.length && window.FileReader && window.File) {
3781 var n = files.length, text = Array(n), read = 0;
3851 var n = files.length, text = Array(n), read = 0;
3782 var loadFile = function(file, i) {
3852 var loadFile = function(file, i) {
3853 if (cm.options.allowDropFileTypes &&
3854 indexOf(cm.options.allowDropFileTypes, file.type) == -1)
3855 return;
3856
3783 var reader = new FileReader;
3857 var reader = new FileReader;
3784 reader.onload = operation(cm, function() {
3858 reader.onload = operation(cm, function() {
3785 text[i] = reader.result;
3859 var content = reader.result;
3860 if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) content = "";
3861 text[i] = content;
3786 if (++read == n) {
3862 if (++read == n) {
3787 pos = clipPos(cm.doc, pos);
3863 pos = clipPos(cm.doc, pos);
3788 var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"};
3864 var change = {from: pos, to: pos,
3865 text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
3866 origin: "paste"};
3789 makeChange(cm.doc, change);
3867 makeChange(cm.doc, change);
3790 setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
3868 setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
3791 }
3869 }
@@ -3839,6 +3917,25 b''
3839 }
3917 }
3840 }
3918 }
3841
3919
3920 function onDragOver(cm, e) {
3921 var pos = posFromMouse(cm, e);
3922 if (!pos) return;
3923 var frag = document.createDocumentFragment();
3924 drawSelectionCursor(cm, pos, frag);
3925 if (!cm.display.dragCursor) {
3926 cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors");
3927 cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv);
3928 }
3929 removeChildrenAndAdd(cm.display.dragCursor, frag);
3930 }
3931
3932 function clearDragCursor(cm) {
3933 if (cm.display.dragCursor) {
3934 cm.display.lineSpace.removeChild(cm.display.dragCursor);
3935 cm.display.dragCursor = null;
3936 }
3937 }
3938
3842 // SCROLL EVENTS
3939 // SCROLL EVENTS
3843
3940
3844 // Sync the scrollable area and scrollbars, ensure the viewport
3941 // Sync the scrollable area and scrollbars, ensure the viewport
@@ -3903,8 +4000,9 b''
3903
4000
3904 var display = cm.display, scroll = display.scroller;
4001 var display = cm.display, scroll = display.scroller;
3905 // Quit if there's nothing to scroll here
4002 // Quit if there's nothing to scroll here
3906 if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
4003 var canScrollX = scroll.scrollWidth > scroll.clientWidth;
3907 dy && scroll.scrollHeight > scroll.clientHeight)) return;
4004 var canScrollY = scroll.scrollHeight > scroll.clientHeight;
4005 if (!(dx && canScrollX || dy && canScrollY)) return;
3908
4006
3909 // Webkit browsers on OS X abort momentum scrolls when the target
4007 // Webkit browsers on OS X abort momentum scrolls when the target
3910 // of the scroll event is removed from the scrollable element.
4008 // of the scroll event is removed from the scrollable element.
@@ -3928,10 +4026,15 b''
3928 // scrolling entirely here. It'll be slightly off from native, but
4026 // scrolling entirely here. It'll be slightly off from native, but
3929 // better than glitching out.
4027 // better than glitching out.
3930 if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
4028 if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
3931 if (dy)
4029 if (dy && canScrollY)
3932 setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
4030 setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
3933 setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
4031 setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
3934 e_preventDefault(e);
4032 // Only prevent default scrolling if vertical scrolling is
4033 // actually possible. Otherwise, it causes vertical scroll
4034 // jitter on OSX trackpads when deltaX is small and deltaY
4035 // is large (issue #3579)
4036 if (!dy || (dy && canScrollY))
4037 e_preventDefault(e);
3935 display.wheelStartX = null; // Abort measurement, if in progress
4038 display.wheelStartX = null; // Abort measurement, if in progress
3936 return;
4039 return;
3937 }
4040 }
@@ -3980,7 +4083,7 b''
3980 cm.display.input.ensurePolled();
4083 cm.display.input.ensurePolled();
3981 var prevShift = cm.display.shift, done = false;
4084 var prevShift = cm.display.shift, done = false;
3982 try {
4085 try {
3983 if (isReadOnly(cm)) cm.state.suppressEdits = true;
4086 if (cm.isReadOnly()) cm.state.suppressEdits = true;
3984 if (dropShift) cm.display.shift = false;
4087 if (dropShift) cm.display.shift = false;
3985 done = bound(cm) != Pass;
4088 done = bound(cm) != Pass;
3986 } finally {
4089 } finally {
@@ -4159,12 +4262,13 b''
4159 // right-click take effect on it.
4262 // right-click take effect on it.
4160 function onContextMenu(cm, e) {
4263 function onContextMenu(cm, e) {
4161 if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return;
4264 if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return;
4265 if (signalDOMEvent(cm, e, "contextmenu")) return;
4162 cm.display.input.onContextMenu(e);
4266 cm.display.input.onContextMenu(e);
4163 }
4267 }
4164
4268
4165 function contextMenuInGutter(cm, e) {
4269 function contextMenuInGutter(cm, e) {
4166 if (!hasHandler(cm, "gutterContextMenu")) return false;
4270 if (!hasHandler(cm, "gutterContextMenu")) return false;
4167 return gutterEvent(cm, e, "gutterContextMenu", false, signal);
4271 return gutterEvent(cm, e, "gutterContextMenu", false);
4168 }
4272 }
4169
4273
4170 // UPDATING
4274 // UPDATING
@@ -4468,7 +4572,7 b''
4468 function replaceRange(doc, code, from, to, origin) {
4572 function replaceRange(doc, code, from, to, origin) {
4469 if (!to) to = from;
4573 if (!to) to = from;
4470 if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
4574 if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
4471 if (typeof code == "string") code = splitLines(code);
4575 if (typeof code == "string") code = doc.splitLines(code);
4472 makeChange(doc, {from: from, to: to, text: code, origin: origin});
4576 makeChange(doc, {from: from, to: to, text: code, origin: origin});
4473 }
4577 }
4474
4578
@@ -4712,10 +4816,9 b''
4712 function findPosH(doc, pos, dir, unit, visually) {
4816 function findPosH(doc, pos, dir, unit, visually) {
4713 var line = pos.line, ch = pos.ch, origDir = dir;
4817 var line = pos.line, ch = pos.ch, origDir = dir;
4714 var lineObj = getLine(doc, line);
4818 var lineObj = getLine(doc, line);
4715 var possible = true;
4716 function findNextLine() {
4819 function findNextLine() {
4717 var l = line + dir;
4820 var l = line + dir;
4718 if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
4821 if (l < doc.first || l >= doc.first + doc.size) return false
4719 line = l;
4822 line = l;
4720 return lineObj = getLine(doc, l);
4823 return lineObj = getLine(doc, l);
4721 }
4824 }
@@ -4725,14 +4828,16 b''
4725 if (!boundToLine && findNextLine()) {
4828 if (!boundToLine && findNextLine()) {
4726 if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
4829 if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
4727 else ch = dir < 0 ? lineObj.text.length : 0;
4830 else ch = dir < 0 ? lineObj.text.length : 0;
4728 } else return (possible = false);
4831 } else return false
4729 } else ch = next;
4832 } else ch = next;
4730 return true;
4833 return true;
4731 }
4834 }
4732
4835
4733 if (unit == "char") moveOnce();
4836 if (unit == "char") {
4734 else if (unit == "column") moveOnce(true);
4837 moveOnce()
4735 else if (unit == "word" || unit == "group") {
4838 } else if (unit == "column") {
4839 moveOnce(true)
4840 } else if (unit == "word" || unit == "group") {
4736 var sawType = null, group = unit == "group";
4841 var sawType = null, group = unit == "group";
4737 var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
4842 var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
4738 for (var first = true;; first = false) {
4843 for (var first = true;; first = false) {
@@ -4752,8 +4857,8 b''
4752 if (dir > 0 && !moveOnce(!first)) break;
4857 if (dir > 0 && !moveOnce(!first)) break;
4753 }
4858 }
4754 }
4859 }
4755 var result = skipAtomic(doc, Pos(line, ch), origDir, true);
4860 var result = skipAtomic(doc, Pos(line, ch), pos, origDir, true);
4756 if (!possible) result.hitSide = true;
4861 if (!cmp(pos, result)) result.hitSide = true;
4757 return result;
4862 return result;
4758 }
4863 }
4759
4864
@@ -5045,7 +5150,7 b''
5045
5150
5046 execCommand: function(cmd) {
5151 execCommand: function(cmd) {
5047 if (commands.hasOwnProperty(cmd))
5152 if (commands.hasOwnProperty(cmd))
5048 return commands[cmd](this);
5153 return commands[cmd].call(null, this);
5049 },
5154 },
5050
5155
5051 triggerElectric: methodOp(function(text) { triggerElectric(this, text); }),
5156 triggerElectric: methodOp(function(text) { triggerElectric(this, text); }),
@@ -5140,6 +5245,7 b''
5140 signal(this, "overwriteToggle", this, this.state.overwrite);
5245 signal(this, "overwriteToggle", this, this.state.overwrite);
5141 },
5246 },
5142 hasFocus: function() { return this.display.input.getField() == activeElt(); },
5247 hasFocus: function() { return this.display.input.getField() == activeElt(); },
5248 isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit); },
5143
5249
5144 scrollTo: methodOp(function(x, y) {
5250 scrollTo: methodOp(function(x, y) {
5145 if (x != null || y != null) resolveScrollToPos(this);
5251 if (x != null || y != null) resolveScrollToPos(this);
@@ -5263,6 +5369,22 b''
5263 clearCaches(cm);
5369 clearCaches(cm);
5264 regChange(cm);
5370 regChange(cm);
5265 }, true);
5371 }, true);
5372 option("lineSeparator", null, function(cm, val) {
5373 cm.doc.lineSep = val;
5374 if (!val) return;
5375 var newBreaks = [], lineNo = cm.doc.first;
5376 cm.doc.iter(function(line) {
5377 for (var pos = 0;;) {
5378 var found = line.text.indexOf(val, pos);
5379 if (found == -1) break;
5380 pos = found + val.length;
5381 newBreaks.push(Pos(lineNo, found));
5382 }
5383 lineNo++;
5384 });
5385 for (var i = newBreaks.length - 1; i >= 0; i--)
5386 replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length))
5387 });
5266 option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) {
5388 option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) {
5267 cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
5389 cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
5268 if (old != CodeMirror.Init) cm.refresh();
5390 if (old != CodeMirror.Init) cm.refresh();
@@ -5321,11 +5443,12 b''
5321 cm.display.disabled = true;
5443 cm.display.disabled = true;
5322 } else {
5444 } else {
5323 cm.display.disabled = false;
5445 cm.display.disabled = false;
5324 if (!val) cm.display.input.reset();
5446 }
5325 }
5447 cm.display.input.readOnlyChanged(val)
5326 });
5448 });
5327 option("disableInput", false, function(cm, val) {if (!val) cm.display.input.reset();}, true);
5449 option("disableInput", false, function(cm, val) {if (!val) cm.display.input.reset();}, true);
5328 option("dragDrop", true, dragDropChanged);
5450 option("dragDrop", true, dragDropChanged);
5451 option("allowDropFileTypes", null);
5329
5452
5330 option("cursorBlinkRate", 530);
5453 option("cursorBlinkRate", 530);
5331 option("cursorScrollMargin", 0);
5454 option("cursorScrollMargin", 0);
@@ -5613,7 +5736,8 b''
5613 } else if (cur.line > cm.doc.first) {
5736 } else if (cur.line > cm.doc.first) {
5614 var prev = getLine(cm.doc, cur.line - 1).text;
5737 var prev = getLine(cm.doc, cur.line - 1).text;
5615 if (prev)
5738 if (prev)
5616 cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
5739 cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
5740 prev.charAt(prev.length - 1),
5617 Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
5741 Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
5618 }
5742 }
5619 }
5743 }
@@ -5627,10 +5751,10 b''
5627 var len = cm.listSelections().length;
5751 var len = cm.listSelections().length;
5628 for (var i = 0; i < len; i++) {
5752 for (var i = 0; i < len; i++) {
5629 var range = cm.listSelections()[i];
5753 var range = cm.listSelections()[i];
5630 cm.replaceRange("\n", range.anchor, range.head, "+input");
5754 cm.replaceRange(cm.doc.lineSeparator(), range.anchor, range.head, "+input");
5631 cm.indentLine(range.from().line + 1, null, true);
5755 cm.indentLine(range.from().line + 1, null, true);
5632 ensureCursorVisible(cm);
5633 }
5756 }
5757 ensureCursorVisible(cm);
5634 });
5758 });
5635 },
5759 },
5636 toggleOverwrite: function(cm) {cm.toggleOverwrite();}
5760 toggleOverwrite: function(cm) {cm.toggleOverwrite();}
@@ -6558,7 +6682,7 b''
6558 parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;";
6682 parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;";
6559 removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
6683 removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
6560 }
6684 }
6561 return widget.height = widget.node.offsetHeight;
6685 return widget.height = widget.node.parentNode.offsetHeight;
6562 }
6686 }
6563
6687
6564 function addLineWidget(doc, handle, node, options) {
6688 function addLineWidget(doc, handle, node, options) {
@@ -6747,7 +6871,9 b''
6747
6871
6748 function getLineStyles(cm, line, updateFrontier) {
6872 function getLineStyles(cm, line, updateFrontier) {
6749 if (!line.styles || line.styles[0] != cm.state.modeGen) {
6873 if (!line.styles || line.styles[0] != cm.state.modeGen) {
6750 var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
6874 var state = getStateBefore(cm, lineNo(line));
6875 var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state);
6876 line.stateAfter = state;
6751 line.styles = result.styles;
6877 line.styles = result.styles;
6752 if (result.classes) line.styleClasses = result.classes;
6878 if (result.classes) line.styleClasses = result.classes;
6753 else if (line.styleClasses) line.styleClasses = null;
6879 else if (line.styleClasses) line.styleClasses = null;
@@ -6764,7 +6890,7 b''
6764 var stream = new StringStream(text, cm.options.tabSize);
6890 var stream = new StringStream(text, cm.options.tabSize);
6765 stream.start = stream.pos = startAt || 0;
6891 stream.start = stream.pos = startAt || 0;
6766 if (text == "") callBlankLine(mode, state);
6892 if (text == "") callBlankLine(mode, state);
6767 while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
6893 while (!stream.eol()) {
6768 readToken(mode, stream, state);
6894 readToken(mode, stream, state);
6769 stream.start = stream.pos;
6895 stream.start = stream.pos;
6770 }
6896 }
@@ -6791,7 +6917,7 b''
6791 // is needed on Webkit to be able to get line-level bounding
6917 // is needed on Webkit to be able to get line-level bounding
6792 // rectangles for it (in measureChar).
6918 // rectangles for it (in measureChar).
6793 var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
6919 var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
6794 var builder = {pre: elt("pre", [content]), content: content,
6920 var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content,
6795 col: 0, pos: 0, cm: cm,
6921 col: 0, pos: 0, cm: cm,
6796 splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")};
6922 splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")};
6797 lineView.measure = {};
6923 lineView.measure = {};
@@ -6881,6 +7007,10 b''
6881 txt.setAttribute("role", "presentation");
7007 txt.setAttribute("role", "presentation");
6882 txt.setAttribute("cm-text", "\t");
7008 txt.setAttribute("cm-text", "\t");
6883 builder.col += tabWidth;
7009 builder.col += tabWidth;
7010 } else if (m[0] == "\r" || m[0] == "\n") {
7011 var txt = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar"));
7012 txt.setAttribute("cm-text", m[0]);
7013 builder.col += 1;
6884 } else {
7014 } else {
6885 var txt = builder.cm.options.specialCharPlaceholder(m[0]);
7015 var txt = builder.cm.options.specialCharPlaceholder(m[0]);
6886 txt.setAttribute("cm-text", m[0]);
7016 txt.setAttribute("cm-text", m[0]);
@@ -6962,7 +7092,7 b''
6962 if (nextChange == pos) { // Update current marker set
7092 if (nextChange == pos) { // Update current marker set
6963 spanStyle = spanEndStyle = spanStartStyle = title = css = "";
7093 spanStyle = spanEndStyle = spanStartStyle = title = css = "";
6964 collapsed = null; nextChange = Infinity;
7094 collapsed = null; nextChange = Infinity;
6965 var foundBookmarks = [];
7095 var foundBookmarks = [], endStyles
6966 for (var j = 0; j < spans.length; ++j) {
7096 for (var j = 0; j < spans.length; ++j) {
6967 var sp = spans[j], m = sp.marker;
7097 var sp = spans[j], m = sp.marker;
6968 if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
7098 if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
@@ -6973,9 +7103,9 b''
6973 spanEndStyle = "";
7103 spanEndStyle = "";
6974 }
7104 }
6975 if (m.className) spanStyle += " " + m.className;
7105 if (m.className) spanStyle += " " + m.className;
6976 if (m.css) css = m.css;
7106 if (m.css) css = (css ? css + ";" : "") + m.css;
6977 if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
7107 if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
6978 if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
7108 if (m.endStyle && sp.to == nextChange) (endStyles || (endStyles = [])).push(m.endStyle, sp.to)
6979 if (m.title && !title) title = m.title;
7109 if (m.title && !title) title = m.title;
6980 if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
7110 if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
6981 collapsed = sp;
7111 collapsed = sp;
@@ -6983,14 +7113,17 b''
6983 nextChange = sp.from;
7113 nextChange = sp.from;
6984 }
7114 }
6985 }
7115 }
7116 if (endStyles) for (var j = 0; j < endStyles.length; j += 2)
7117 if (endStyles[j + 1] == nextChange) spanEndStyle += " " + endStyles[j]
7118
7119 if (!collapsed || collapsed.from == pos) for (var j = 0; j < foundBookmarks.length; ++j)
7120 buildCollapsedSpan(builder, 0, foundBookmarks[j]);
6986 if (collapsed && (collapsed.from || 0) == pos) {
7121 if (collapsed && (collapsed.from || 0) == pos) {
6987 buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
7122 buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
6988 collapsed.marker, collapsed.from == null);
7123 collapsed.marker, collapsed.from == null);
6989 if (collapsed.to == null) return;
7124 if (collapsed.to == null) return;
6990 if (collapsed.to == pos) collapsed = false;
7125 if (collapsed.to == pos) collapsed = false;
6991 }
7126 }
6992 if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
6993 buildCollapsedSpan(builder, 0, foundBookmarks[j]);
6994 }
7127 }
6995 if (pos >= len) break;
7128 if (pos >= len) break;
6996
7129
@@ -7226,8 +7359,8 b''
7226 };
7359 };
7227
7360
7228 var nextDocId = 0;
7361 var nextDocId = 0;
7229 var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
7362 var Doc = CodeMirror.Doc = function(text, mode, firstLine, lineSep) {
7230 if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
7363 if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep);
7231 if (firstLine == null) firstLine = 0;
7364 if (firstLine == null) firstLine = 0;
7232
7365
7233 BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
7366 BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
@@ -7241,8 +7374,10 b''
7241 this.history = new History(null);
7374 this.history = new History(null);
7242 this.id = ++nextDocId;
7375 this.id = ++nextDocId;
7243 this.modeOption = mode;
7376 this.modeOption = mode;
7244
7377 this.lineSep = lineSep;
7245 if (typeof text == "string") text = splitLines(text);
7378 this.extend = false;
7379
7380 if (typeof text == "string") text = this.splitLines(text);
7246 updateDoc(this, {from: start, to: start, text: text});
7381 updateDoc(this, {from: start, to: start, text: text});
7247 setSelection(this, simpleSelection(start), sel_dontScroll);
7382 setSelection(this, simpleSelection(start), sel_dontScroll);
7248 };
7383 };
@@ -7272,12 +7407,12 b''
7272 getValue: function(lineSep) {
7407 getValue: function(lineSep) {
7273 var lines = getLines(this, this.first, this.first + this.size);
7408 var lines = getLines(this, this.first, this.first + this.size);
7274 if (lineSep === false) return lines;
7409 if (lineSep === false) return lines;
7275 return lines.join(lineSep || "\n");
7410 return lines.join(lineSep || this.lineSeparator());
7276 },
7411 },
7277 setValue: docMethodOp(function(code) {
7412 setValue: docMethodOp(function(code) {
7278 var top = Pos(this.first, 0), last = this.first + this.size - 1;
7413 var top = Pos(this.first, 0), last = this.first + this.size - 1;
7279 makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
7414 makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
7280 text: splitLines(code), origin: "setValue", full: true}, true);
7415 text: this.splitLines(code), origin: "setValue", full: true}, true);
7281 setSelection(this, simpleSelection(top));
7416 setSelection(this, simpleSelection(top));
7282 }),
7417 }),
7283 replaceRange: function(code, from, to, origin) {
7418 replaceRange: function(code, from, to, origin) {
@@ -7288,7 +7423,7 b''
7288 getRange: function(from, to, lineSep) {
7423 getRange: function(from, to, lineSep) {
7289 var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
7424 var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
7290 if (lineSep === false) return lines;
7425 if (lineSep === false) return lines;
7291 return lines.join(lineSep || "\n");
7426 return lines.join(lineSep || this.lineSeparator());
7292 },
7427 },
7293
7428
7294 getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
7429 getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
@@ -7328,10 +7463,11 b''
7328 extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
7463 extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
7329 }),
7464 }),
7330 extendSelections: docMethodOp(function(heads, options) {
7465 extendSelections: docMethodOp(function(heads, options) {
7331 extendSelections(this, clipPosArray(this, heads, options));
7466 extendSelections(this, clipPosArray(this, heads), options);
7332 }),
7467 }),
7333 extendSelectionsBy: docMethodOp(function(f, options) {
7468 extendSelectionsBy: docMethodOp(function(f, options) {
7334 extendSelections(this, map(this.sel.ranges, f), options);
7469 var heads = map(this.sel.ranges, f);
7470 extendSelections(this, clipPosArray(this, heads), options);
7335 }),
7471 }),
7336 setSelections: docMethodOp(function(ranges, primary, options) {
7472 setSelections: docMethodOp(function(ranges, primary, options) {
7337 if (!ranges.length) return;
7473 if (!ranges.length) return;
@@ -7354,13 +7490,13 b''
7354 lines = lines ? lines.concat(sel) : sel;
7490 lines = lines ? lines.concat(sel) : sel;
7355 }
7491 }
7356 if (lineSep === false) return lines;
7492 if (lineSep === false) return lines;
7357 else return lines.join(lineSep || "\n");
7493 else return lines.join(lineSep || this.lineSeparator());
7358 },
7494 },
7359 getSelections: function(lineSep) {
7495 getSelections: function(lineSep) {
7360 var parts = [], ranges = this.sel.ranges;
7496 var parts = [], ranges = this.sel.ranges;
7361 for (var i = 0; i < ranges.length; i++) {
7497 for (var i = 0; i < ranges.length; i++) {
7362 var sel = getBetween(this, ranges[i].from(), ranges[i].to());
7498 var sel = getBetween(this, ranges[i].from(), ranges[i].to());
7363 if (lineSep !== false) sel = sel.join(lineSep || "\n");
7499 if (lineSep !== false) sel = sel.join(lineSep || this.lineSeparator());
7364 parts[i] = sel;
7500 parts[i] = sel;
7365 }
7501 }
7366 return parts;
7502 return parts;
@@ -7375,7 +7511,7 b''
7375 var changes = [], sel = this.sel;
7511 var changes = [], sel = this.sel;
7376 for (var i = 0; i < sel.ranges.length; i++) {
7512 for (var i = 0; i < sel.ranges.length; i++) {
7377 var range = sel.ranges[i];
7513 var range = sel.ranges[i];
7378 changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};
7514 changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin};
7379 }
7515 }
7380 var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
7516 var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
7381 for (var i = changes.length - 1; i >= 0; i--)
7517 for (var i = changes.length - 1; i >= 0; i--)
@@ -7456,7 +7592,7 b''
7456 removeLineWidget: function(widget) { widget.clear(); },
7592 removeLineWidget: function(widget) { widget.clear(); },
7457
7593
7458 markText: function(from, to, options) {
7594 markText: function(from, to, options) {
7459 return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
7595 return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range");
7460 },
7596 },
7461 setBookmark: function(pos, options) {
7597 setBookmark: function(pos, options) {
7462 var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
7598 var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
@@ -7525,7 +7661,8 b''
7525 },
7661 },
7526
7662
7527 copy: function(copyHistory) {
7663 copy: function(copyHistory) {
7528 var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
7664 var doc = new Doc(getLines(this, this.first, this.first + this.size),
7665 this.modeOption, this.first, this.lineSep);
7529 doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
7666 doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
7530 doc.sel = this.sel;
7667 doc.sel = this.sel;
7531 doc.extend = false;
7668 doc.extend = false;
@@ -7541,7 +7678,7 b''
7541 var from = this.first, to = this.first + this.size;
7678 var from = this.first, to = this.first + this.size;
7542 if (options.from != null && options.from > from) from = options.from;
7679 if (options.from != null && options.from > from) from = options.from;
7543 if (options.to != null && options.to < to) to = options.to;
7680 if (options.to != null && options.to < to) to = options.to;
7544 var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
7681 var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep);
7545 if (options.sharedHist) copy.history = this.history;
7682 if (options.sharedHist) copy.history = this.history;
7546 (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
7683 (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
7547 copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
7684 copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
@@ -7570,7 +7707,13 b''
7570 iterLinkedDocs: function(f) {linkedDocs(this, f);},
7707 iterLinkedDocs: function(f) {linkedDocs(this, f);},
7571
7708
7572 getMode: function() {return this.mode;},
7709 getMode: function() {return this.mode;},
7573 getEditor: function() {return this.cm;}
7710 getEditor: function() {return this.cm;},
7711
7712 splitLines: function(str) {
7713 if (this.lineSep) return str.split(this.lineSep);
7714 return splitLinesAuto(str);
7715 },
7716 lineSeparator: function() { return this.lineSep || "\n"; }
7574 });
7717 });
7575
7718
7576 // Public alias.
7719 // Public alias.
@@ -8010,24 +8153,30 b''
8010 }
8153 }
8011 };
8154 };
8012
8155
8156 var noHandlers = []
8157 function getHandlers(emitter, type, copy) {
8158 var arr = emitter._handlers && emitter._handlers[type]
8159 if (copy) return arr && arr.length > 0 ? arr.slice() : noHandlers
8160 else return arr || noHandlers
8161 }
8162
8013 var off = CodeMirror.off = function(emitter, type, f) {
8163 var off = CodeMirror.off = function(emitter, type, f) {
8014 if (emitter.removeEventListener)
8164 if (emitter.removeEventListener)
8015 emitter.removeEventListener(type, f, false);
8165 emitter.removeEventListener(type, f, false);
8016 else if (emitter.detachEvent)
8166 else if (emitter.detachEvent)
8017 emitter.detachEvent("on" + type, f);
8167 emitter.detachEvent("on" + type, f);
8018 else {
8168 else {
8019 var arr = emitter._handlers && emitter._handlers[type];
8169 var handlers = getHandlers(emitter, type, false)
8020 if (!arr) return;
8170 for (var i = 0; i < handlers.length; ++i)
8021 for (var i = 0; i < arr.length; ++i)
8171 if (handlers[i] == f) { handlers.splice(i, 1); break; }
8022 if (arr[i] == f) { arr.splice(i, 1); break; }
8023 }
8172 }
8024 };
8173 };
8025
8174
8026 var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
8175 var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
8027 var arr = emitter._handlers && emitter._handlers[type];
8176 var handlers = getHandlers(emitter, type, true)
8028 if (!arr) return;
8177 if (!handlers.length) return;
8029 var args = Array.prototype.slice.call(arguments, 2);
8178 var args = Array.prototype.slice.call(arguments, 2);
8030 for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
8179 for (var i = 0; i < handlers.length; ++i) handlers[i].apply(null, args);
8031 };
8180 };
8032
8181
8033 var orphanDelayedCallbacks = null;
8182 var orphanDelayedCallbacks = null;
@@ -8040,8 +8189,8 b''
8040 // them to be executed when the last operation ends, or, if no
8189 // them to be executed when the last operation ends, or, if no
8041 // operation is active, when a timeout fires.
8190 // operation is active, when a timeout fires.
8042 function signalLater(emitter, type /*, values...*/) {
8191 function signalLater(emitter, type /*, values...*/) {
8043 var arr = emitter._handlers && emitter._handlers[type];
8192 var arr = getHandlers(emitter, type, false)
8044 if (!arr) return;
8193 if (!arr.length) return;
8045 var args = Array.prototype.slice.call(arguments, 2), list;
8194 var args = Array.prototype.slice.call(arguments, 2), list;
8046 if (operationGroup) {
8195 if (operationGroup) {
8047 list = operationGroup.delayedCallbacks;
8196 list = operationGroup.delayedCallbacks;
@@ -8081,8 +8230,7 b''
8081 }
8230 }
8082
8231
8083 function hasHandler(emitter, type) {
8232 function hasHandler(emitter, type) {
8084 var arr = emitter._handlers && emitter._handlers[type];
8233 return getHandlers(emitter, type).length > 0
8085 return arr && arr.length > 0;
8086 }
8234 }
8087
8235
8088 // Add on and off methods to a constructor's prototype, to make
8236 // Add on and off methods to a constructor's prototype, to make
@@ -8129,7 +8277,7 b''
8129
8277
8130 // The inverse of countColumn -- find the offset that corresponds to
8278 // The inverse of countColumn -- find the offset that corresponds to
8131 // a particular column.
8279 // a particular column.
8132 function findColumn(string, goal, tabSize) {
8280 var findColumn = CodeMirror.findColumn = function(string, goal, tabSize) {
8133 for (var pos = 0, col = 0;;) {
8281 for (var pos = 0, col = 0;;) {
8134 var nextTab = string.indexOf("\t", pos);
8282 var nextTab = string.indexOf("\t", pos);
8135 if (nextTab == -1) nextTab = string.length;
8283 if (nextTab == -1) nextTab = string.length;
@@ -8269,7 +8417,12 b''
8269 } while (child = child.parentNode);
8417 } while (child = child.parentNode);
8270 };
8418 };
8271
8419
8272 function activeElt() { return document.activeElement; }
8420 function activeElt() {
8421 var activeElement = document.activeElement;
8422 while (activeElement && activeElement.root && activeElement.root.activeElement)
8423 activeElement = activeElement.root.activeElement;
8424 return activeElement;
8425 }
8273 // Older versions of IE throws unspecified error when touching
8426 // Older versions of IE throws unspecified error when touching
8274 // document.activeElement in some cases (during loading, in iframe)
8427 // document.activeElement in some cases (during loading, in iframe)
8275 if (ie && ie_version < 11) activeElt = function() {
8428 if (ie && ie_version < 11) activeElt = function() {
@@ -8371,7 +8524,7 b''
8371
8524
8372 // See if "".split is the broken IE version, if so, provide an
8525 // See if "".split is the broken IE version, if so, provide an
8373 // alternative way to split lines.
8526 // alternative way to split lines.
8374 var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
8527 var splitLinesAuto = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
8375 var pos = 0, result = [], l = string.length;
8528 var pos = 0, result = [], l = string.length;
8376 while (pos <= l) {
8529 while (pos <= l) {
8377 var nl = string.indexOf("\n", pos);
8530 var nl = string.indexOf("\n", pos);
@@ -8417,14 +8570,16 b''
8417
8570
8418 // KEY NAMES
8571 // KEY NAMES
8419
8572
8420 var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
8573 var keyNames = CodeMirror.keyNames = {
8421 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
8574 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
8422 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
8575 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
8423 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete",
8576 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
8424 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
8577 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
8425 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
8578 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete",
8426 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"};
8579 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
8427 CodeMirror.keyNames = keyNames;
8580 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
8581 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
8582 };
8428 (function() {
8583 (function() {
8429 // Number keys
8584 // Number keys
8430 for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
8585 for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
@@ -8729,7 +8884,7 b''
8729
8884
8730 // THE END
8885 // THE END
8731
8886
8732 CodeMirror.version = "5.4.0";
8887 CodeMirror.version = "5.11.0";
8733
8888
8734 return CodeMirror;
8889 return CodeMirror;
8735 });
8890 });
@@ -25,8 +25,18 b''
25 };
25 };
26
26
27 CodeMirror.defineExtension("showHint", function(options) {
27 CodeMirror.defineExtension("showHint", function(options) {
28 // We want a single cursor position.
28 options = parseOptions(this, this.getCursor("start"), options);
29 if (this.listSelections().length > 1 || this.somethingSelected()) return;
29 var selections = this.listSelections()
30 if (selections.length > 1) return;
31 // By default, don't allow completion when something is selected.
32 // A hint function can have a `supportsSelection` property to
33 // indicate that it can handle selections.
34 if (this.somethingSelected()) {
35 if (!options.hint.supportsSelection) return;
36 // Don't try with cross-line selections
37 for (var i = 0; i < selections.length; i++)
38 if (selections[i].head.line != selections[i].anchor.line) return;
39 }
30
40
31 if (this.state.completionActive) this.state.completionActive.close();
41 if (this.state.completionActive) this.state.completionActive.close();
32 var completion = this.state.completionActive = new Completion(this, options);
42 var completion = this.state.completionActive = new Completion(this, options);
@@ -38,12 +48,12 b''
38
48
39 function Completion(cm, options) {
49 function Completion(cm, options) {
40 this.cm = cm;
50 this.cm = cm;
41 this.options = this.buildOptions(options);
51 this.options = options;
42 this.widget = null;
52 this.widget = null;
43 this.debounce = 0;
53 this.debounce = 0;
44 this.tick = 0;
54 this.tick = 0;
45 this.startPos = this.cm.getCursor();
55 this.startPos = this.cm.getCursor("start");
46 this.startLen = this.cm.getLine(this.startPos.line).length;
56 this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
47
57
48 var self = this;
58 var self = this;
49 cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
59 cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
@@ -99,7 +109,6 b''
99
109
100 update: function(first) {
110 update: function(first) {
101 if (this.tick == null) return;
111 if (this.tick == null) return;
102 if (this.data) CodeMirror.signal(this.data, "update");
103 if (!this.options.hint.async) {
112 if (!this.options.hint.async) {
104 this.finishUpdate(this.options.hint(this.cm, this.options), first);
113 this.finishUpdate(this.options.hint(this.cm, this.options), first);
105 } else {
114 } else {
@@ -111,6 +120,8 b''
111 },
120 },
112
121
113 finishUpdate: function(data, first) {
122 finishUpdate: function(data, first) {
123 if (this.data) CodeMirror.signal(this.data, "update");
124 if (data && this.data && CodeMirror.cmpPos(data.from, this.data.from)) data = null;
114 this.data = data;
125 this.data = data;
115
126
116 var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
127 var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
@@ -123,20 +134,21 b''
123 CodeMirror.signal(data, "shown");
134 CodeMirror.signal(data, "shown");
124 }
135 }
125 }
136 }
126 },
127
128 buildOptions: function(options) {
129 var editor = this.cm.options.hintOptions;
130 var out = {};
131 for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
132 if (editor) for (var prop in editor)
133 if (editor[prop] !== undefined) out[prop] = editor[prop];
134 if (options) for (var prop in options)
135 if (options[prop] !== undefined) out[prop] = options[prop];
136 return out;
137 }
137 }
138 };
138 };
139
139
140 function parseOptions(cm, pos, options) {
141 var editor = cm.options.hintOptions;
142 var out = {};
143 for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
144 if (editor) for (var prop in editor)
145 if (editor[prop] !== undefined) out[prop] = editor[prop];
146 if (options) for (var prop in options)
147 if (options[prop] !== undefined) out[prop] = options[prop];
148 if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
149 return out;
150 }
151
140 function getText(completion) {
152 function getText(completion) {
141 if (typeof completion == "string") return completion;
153 if (typeof completion == "string") return completion;
142 else return completion.text;
154 else return completion.text;
@@ -335,34 +347,79 b''
335 }
347 }
336 };
348 };
337
349
338 CodeMirror.registerHelper("hint", "auto", function(cm, options) {
350 function applicableHelpers(cm, helpers) {
339 var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
351 if (!cm.somethingSelected()) return helpers
352 var result = []
353 for (var i = 0; i < helpers.length; i++)
354 if (helpers[i].supportsSelection) result.push(helpers[i])
355 return result
356 }
357
358 function resolveAutoHints(cm, pos) {
359 var helpers = cm.getHelpers(pos, "hint"), words
340 if (helpers.length) {
360 if (helpers.length) {
341 for (var i = 0; i < helpers.length; i++) {
361 var async = false, resolved
342 var cur = helpers[i](cm, options);
362 for (var i = 0; i < helpers.length; i++) if (helpers[i].async) async = true
343 if (cur && cur.list.length) return cur;
363 if (async) {
364 resolved = function(cm, callback, options) {
365 var app = applicableHelpers(cm, helpers)
366 function run(i, result) {
367 if (i == app.length) return callback(null)
368 var helper = app[i]
369 if (helper.async) {
370 helper(cm, function(result) {
371 if (result) callback(result)
372 else run(i + 1)
373 }, options)
374 } else {
375 var result = helper(cm, options)
376 if (result) callback(result)
377 else run(i + 1)
378 }
379 }
380 run(0)
381 }
382 resolved.async = true
383 } else {
384 resolved = function(cm, options) {
385 var app = applicableHelpers(cm, helpers)
386 for (var i = 0; i < app.length; i++) {
387 var cur = app[i](cm, options)
388 if (cur && cur.list.length) return cur
389 }
390 }
344 }
391 }
392 resolved.supportsSelection = true
393 return resolved
345 } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
394 } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
346 if (words) return CodeMirror.hint.fromList(cm, {words: words});
395 return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
347 } else if (CodeMirror.hint.anyword) {
396 } else if (CodeMirror.hint.anyword) {
348 return CodeMirror.hint.anyword(cm, options);
397 return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
398 } else {
399 return function() {}
349 }
400 }
401 }
402
403 CodeMirror.registerHelper("hint", "auto", {
404 resolve: resolveAutoHints
350 });
405 });
351
406
352 CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
407 CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
353 var cur = cm.getCursor(), token = cm.getTokenAt(cur);
408 var cur = cm.getCursor(), token = cm.getTokenAt(cur);
409 var to = CodeMirror.Pos(cur.line, token.end);
410 if (token.string && /\w/.test(token.string[token.string.length - 1])) {
411 var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
412 } else {
413 var term = "", from = to;
414 }
354 var found = [];
415 var found = [];
355 for (var i = 0; i < options.words.length; i++) {
416 for (var i = 0; i < options.words.length; i++) {
356 var word = options.words[i];
417 var word = options.words[i];
357 if (word.slice(0, token.string.length) == token.string)
418 if (word.slice(0, term.length) == term)
358 found.push(word);
419 found.push(word);
359 }
420 }
360
421
361 if (found.length) return {
422 if (found.length) return {list: found, from: from, to: to};
362 list: found,
363 from: CodeMirror.Pos(cur.line, token.start),
364 to: CodeMirror.Pos(cur.line, token.end)
365 };
366 });
423 });
367
424
368 CodeMirror.commands.autocomplete = CodeMirror.showHint;
425 CodeMirror.commands.autocomplete = CodeMirror.showHint;
@@ -373,7 +430,7 b''
373 alignWithWord: true,
430 alignWithWord: true,
374 closeCharacters: /[\s()\[\]{};:>,]/,
431 closeCharacters: /[\s()\[\]{};:>,]/,
375 closeOnUnfocus: true,
432 closeOnUnfocus: true,
376 completeOnSingleClick: false,
433 completeOnSingleClick: true,
377 container: null,
434 container: null,
378 customKeys: null,
435 customKeys: null,
379 extraKeys: null
436 extraKeys: null
@@ -37,7 +37,9 b''
37 var elt = cm.state.placeholder = document.createElement("pre");
37 var elt = cm.state.placeholder = document.createElement("pre");
38 elt.style.cssText = "height: 0; overflow: visible";
38 elt.style.cssText = "height: 0; overflow: visible";
39 elt.className = "CodeMirror-placeholder";
39 elt.className = "CodeMirror-placeholder";
40 elt.appendChild(document.createTextNode(cm.getOption("placeholder")));
40 var placeHolder = cm.getOption("placeholder")
41 if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder)
42 elt.appendChild(placeHolder)
41 cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
43 cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
42 }
44 }
43
45
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now