codemirror-rails 5.10 → 5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +15 -12
  4. data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +1 -1
  5. data/vendor/assets/javascripts/codemirror/addons/fold/foldgutter.js +2 -2
  6. data/vendor/assets/javascripts/codemirror/addons/search/match-highlighter.js +32 -11
  7. data/vendor/assets/javascripts/codemirror/modes/clike.js +1 -3
  8. data/vendor/assets/javascripts/codemirror/modes/clojure.js +8 -3
  9. data/vendor/assets/javascripts/codemirror/modes/css.js +14 -13
  10. data/vendor/assets/javascripts/codemirror/modes/django.js +3 -4
  11. data/vendor/assets/javascripts/codemirror/modes/haskell-literate.js +43 -0
  12. data/vendor/assets/javascripts/codemirror/modes/jade.js +3 -3
  13. data/vendor/assets/javascripts/codemirror/modes/javascript.js +15 -4
  14. data/vendor/assets/javascripts/codemirror/modes/jsx.js +147 -0
  15. data/vendor/assets/javascripts/codemirror/modes/julia.js +143 -78
  16. data/vendor/assets/javascripts/codemirror/modes/markdown.js +1 -1
  17. data/vendor/assets/javascripts/codemirror/modes/nginx.js +1 -1
  18. data/vendor/assets/javascripts/codemirror/modes/ruby.js +1 -1
  19. data/vendor/assets/javascripts/codemirror/modes/swift.js +42 -3
  20. data/vendor/assets/javascripts/codemirror/modes/xml.js +78 -69
  21. data/vendor/assets/javascripts/codemirror/modes/yaml-frontmatter.js +1 -1
  22. data/vendor/assets/stylesheets/codemirror/modes/tiki.css +1 -1
  23. data/vendor/assets/stylesheets/codemirror/themes/mbo.css +1 -1
  24. data/vendor/assets/stylesheets/codemirror/themes/monokai.css +1 -0
  25. metadata +3 -1
@@ -13,6 +13,11 @@
13
13
  })(function(CodeMirror) {
14
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
21
  CodeMirror.defineMode("javascript", function(config, parserConfig) {
17
22
  var indentUnit = config.indentUnit;
18
23
  var statementIndent = parserConfig.statementIndent;
@@ -126,8 +131,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
126
131
  } else if (stream.eat("/")) {
127
132
  stream.skipToEnd();
128
133
  return ret("comment", "comment");
129
- } else if (/^(?:operator|sof|keyword c|case|new|[\[{}\(,;:])$/.test(state.lastType) ||
130
- (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - 1)))) {
134
+ } else if (expressionAllowed(stream, state, 1)) {
131
135
  readRegexp(stream);
132
136
  stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
133
137
  return ret("regexp", "string-2");
@@ -533,6 +537,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
533
537
  }
534
538
  if (type == "variable") cx.marked = "property";
535
539
  if (type == "spread") return cont(pattern);
540
+ if (type == "}") return pass();
536
541
  return cont(expect(":"), pattern, maybeAssign);
537
542
  }
538
543
  function maybeAssign(_type, value) {
@@ -655,7 +660,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
655
660
  lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
656
661
  localVars: parserConfig.localVars,
657
662
  context: parserConfig.localVars && {vars: parserConfig.localVars},
658
- indented: 0
663
+ indented: basecolumn || 0
659
664
  };
660
665
  if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
661
666
  state.globalVars = parserConfig.globalVars;
@@ -711,7 +716,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
711
716
 
712
717
  helperType: jsonMode ? "json" : "javascript",
713
718
  jsonldMode: jsonldMode,
714
- 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
+ }
715
726
  };
716
727
  });
717
728
 
@@ -0,0 +1,147 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"))
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod)
9
+ else // Plain browser env
10
+ mod(CodeMirror)
11
+ })(function(CodeMirror) {
12
+ "use strict"
13
+
14
+ // Depth means the amount of open braces in JS context, in XML
15
+ // context 0 means not in tag, 1 means in tag, and 2 means in tag
16
+ // and js block comment.
17
+ function Context(state, mode, depth, prev) {
18
+ this.state = state; this.mode = mode; this.depth = depth; this.prev = prev
19
+ }
20
+
21
+ function copyContext(context) {
22
+ return new Context(CodeMirror.copyState(context.mode, context.state),
23
+ context.mode,
24
+ context.depth,
25
+ context.prev && copyContext(context.prev))
26
+ }
27
+
28
+ CodeMirror.defineMode("jsx", function(config) {
29
+ var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
30
+ var jsMode = CodeMirror.getMode(config, "javascript")
31
+
32
+ function flatXMLIndent(state) {
33
+ var tagName = state.tagName
34
+ state.tagName = null
35
+ var result = xmlMode.indent(state, "")
36
+ state.tagName = tagName
37
+ return result
38
+ }
39
+
40
+ function token(stream, state) {
41
+ if (state.context.mode == xmlMode)
42
+ return xmlToken(stream, state, state.context)
43
+ else
44
+ return jsToken(stream, state, state.context)
45
+ }
46
+
47
+ function xmlToken(stream, state, cx) {
48
+ if (cx.depth == 2) { // Inside a JS /* */ comment
49
+ if (stream.match(/^.*?\*\//)) cx.depth = 1
50
+ else stream.skipToEnd()
51
+ return "comment"
52
+ }
53
+
54
+ if (stream.peek() == "{") {
55
+ xmlMode.skipAttribute(cx.state)
56
+
57
+ var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context
58
+ // If JS starts on same line as tag
59
+ if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) {
60
+ while (xmlContext.prev && !xmlContext.startOfLine)
61
+ xmlContext = xmlContext.prev
62
+ // If tag starts the line, use XML indentation level
63
+ if (xmlContext.startOfLine) indent -= config.indentUnit
64
+ // Else use JS indentation level
65
+ else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented
66
+ // Else if inside of tag
67
+ } else if (cx.depth == 1) {
68
+ indent += config.indentUnit
69
+ }
70
+
71
+ state.context = new Context(CodeMirror.startState(jsMode, indent),
72
+ jsMode, 0, state.context)
73
+ return null
74
+ }
75
+
76
+ if (cx.depth == 1) { // Inside of tag
77
+ if (stream.peek() == "<") { // Tag inside of tag
78
+ xmlMode.skipAttribute(cx.state)
79
+ state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)),
80
+ xmlMode, 0, state.context)
81
+ return null
82
+ } else if (stream.match("//")) {
83
+ stream.skipToEnd()
84
+ return "comment"
85
+ } else if (stream.match("/*")) {
86
+ cx.depth = 2
87
+ return token(stream, state)
88
+ }
89
+ }
90
+
91
+ var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop
92
+ if (/\btag\b/.test(style)) {
93
+ if (/>$/.test(cur)) {
94
+ if (cx.state.context) cx.depth = 0
95
+ else state.context = state.context.prev
96
+ } else if (/^</.test(cur)) {
97
+ cx.depth = 1
98
+ }
99
+ } else if (!style && (stop = cur.indexOf("{")) > -1) {
100
+ stream.backUp(cur.length - stop)
101
+ }
102
+ return style
103
+ }
104
+
105
+ function jsToken(stream, state, cx) {
106
+ if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
107
+ jsMode.skipExpression(cx.state)
108
+ state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
109
+ xmlMode, 0, state.context)
110
+ return null
111
+ }
112
+
113
+ var style = jsMode.token(stream, cx.state)
114
+ if (!style && cx.depth != null) {
115
+ var cur = stream.current()
116
+ if (cur == "{") {
117
+ cx.depth++
118
+ } else if (cur == "}") {
119
+ if (--cx.depth == 0) state.context = state.context.prev
120
+ }
121
+ }
122
+ return style
123
+ }
124
+
125
+ return {
126
+ startState: function() {
127
+ return {context: new Context(CodeMirror.startState(jsMode), jsMode)}
128
+ },
129
+
130
+ copyState: function(state) {
131
+ return {context: copyContext(state.context)}
132
+ },
133
+
134
+ token: token,
135
+
136
+ indent: function(state, textAfter, fullLine) {
137
+ return state.context.mode.indent(state.context.state, textAfter, fullLine)
138
+ },
139
+
140
+ innerMode: function(state) {
141
+ return state.context
142
+ }
143
+ }
144
+ }, "xml", "javascript")
145
+
146
+ CodeMirror.defineMIME("text/jsx", "jsx")
147
+ })
@@ -18,35 +18,34 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
18
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
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
24
  var blockOpeners = ["begin", "function", "type", "immutable", "let", "macro", "for", "while", "quote", "if", "else", "elseif", "try", "finally", "catch", "do"];
25
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'];
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'];
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', 'nothing', 'NaN', 'Inf'];
28
28
 
29
29
  //var stringPrefixes = new RegExp("^[br]?('|\")")
30
- var stringPrefixes = /^(`|'|"{3}|([br]?"))/;
30
+ var stringPrefixes = /^(`|'|"{3}|([brv]?"))/;
31
31
  var keywords = wordRegexp(keywordList);
32
32
  var builtins = wordRegexp(builtinList);
33
33
  var openers = wordRegexp(blockOpeners);
34
34
  var closers = wordRegexp(blockClosers);
35
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
- var ch = cur_scope(state);
40
- if(ch=="[" || ch=="{") {
39
+ function inArray(state) {
40
+ var ch = currentScope(state);
41
+ if (ch == '[') {
41
42
  return true;
42
43
  }
43
- else {
44
- return false;
45
- }
44
+ return false;
46
45
  }
47
46
 
48
- function cur_scope(state) {
49
- if(state.scopes.length==0) {
47
+ function currentScope(state) {
48
+ if (state.scopes.length == 0) {
50
49
  return null;
51
50
  }
52
51
  return state.scopes[state.scopes.length - 1];
@@ -54,20 +53,34 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
54
53
 
55
54
  // tokenizers
56
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
71
  // Handle scope changes
58
- var leaving_expr = state.leaving_expr;
59
- if(stream.sol()) {
60
- leaving_expr = false;
72
+ var leavingExpr = state.leavingExpr;
73
+ if (stream.sol()) {
74
+ leavingExpr = false;
61
75
  }
62
- state.leaving_expr = false;
63
- if(leaving_expr) {
64
- if(stream.match(/^'+/)) {
76
+ state.leavingExpr = false;
77
+ if (leavingExpr) {
78
+ if (stream.match(/^'+/)) {
65
79
  return 'operator';
66
80
  }
67
-
68
81
  }
69
82
 
70
- if(stream.match(/^\.{2,3}/)) {
83
+ if (stream.match(/^\.{2,3}/)) {
71
84
  return 'operator';
72
85
  }
73
86
 
@@ -76,56 +89,51 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
76
89
  }
77
90
 
78
91
  var ch = stream.peek();
79
- // Handle Comments
92
+
93
+ // Handle single line comments
80
94
  if (ch === '#') {
81
- stream.skipToEnd();
82
- return 'comment';
83
- }
84
- if(ch==='[') {
85
- state.scopes.push("[");
95
+ stream.skipToEnd();
96
+ return 'comment';
86
97
  }
87
98
 
88
- if(ch==='{') {
89
- state.scopes.push("{");
99
+ if (ch === '[') {
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
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
111
  state.scopes.pop();
101
- state.leaving_expr=true;
102
- }
103
-
104
- if(ch===')') {
105
- state.leaving_expr = true;
112
+ state.leavingExpr = true;
106
113
  }
107
114
 
108
115
  var match;
109
- if(!in_array(state) && (match=stream.match(openers, false))) {
116
+ if (!inArray(state) && (match=stream.match(openers, false))) {
110
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
121
  state.scopes.pop();
115
122
  }
116
123
 
117
- if(in_array(state)) {
118
- if(stream.match(/^end/)) {
124
+ if (inArray(state)) {
125
+ if (state.lastToken == 'end' && stream.match(/^:/)) {
126
+ return 'operator';
127
+ }
128
+ if (stream.match(/^end/)) {
119
129
  return 'number';
120
130
  }
121
-
122
131
  }
123
132
 
124
- if(stream.match(/^=>/)) {
133
+ if (stream.match(/^=>/)) {
125
134
  return 'operator';
126
135
  }
127
136
 
128
-
129
137
  // Handle Number Literals
130
138
  if (stream.match(/^[0-9\.]/, false)) {
131
139
  var imMatcher = RegExp(/^im\b/);
@@ -134,10 +142,11 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
134
142
  if (stream.match(/^\d*\.(?!\.)\d+([ef][\+\-]?\d+)?/i)) { floatLiteral = true; }
135
143
  if (stream.match(/^\d+\.(?!\.)\d*/)) { floatLiteral = true; }
136
144
  if (stream.match(/^\.\d+/)) { floatLiteral = true; }
145
+ if (stream.match(/^0x\.[0-9a-f]+p[\+\-]?\d+/i)) { floatLiteral = true; }
137
146
  if (floatLiteral) {
138
147
  // Float literals may be "imaginary"
139
148
  stream.match(imMatcher);
140
- state.leaving_expr = true;
149
+ state.leavingExpr = true;
141
150
  return 'number';
142
151
  }
143
152
  // Integers
@@ -157,18 +166,27 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
157
166
  if (intLiteral) {
158
167
  // Integer literals may be "long"
159
168
  stream.match(imMatcher);
160
- state.leaving_expr = true;
169
+ state.leavingExpr = true;
161
170
  return 'number';
162
171
  }
163
172
  }
164
173
 
165
- if(stream.match(/^(::)|(<:)/)) {
174
+ if (stream.match(/^<:/)) {
166
175
  return 'operator';
167
176
  }
168
177
 
178
+ if (stream.match(typeAnnotation)) {
179
+ return 'builtin';
180
+ }
181
+
169
182
  // Handle symbols
170
- if(!leaving_expr && stream.match(symbol)) {
171
- return 'string';
183
+ if (!leavingExpr && stream.match(symbol) || stream.match(/:\./)) {
184
+ return 'builtin';
185
+ }
186
+
187
+ // Handle parametric types
188
+ if (stream.match(/^{[^}]*}(?=\()/)) {
189
+ return 'builtin';
172
190
  }
173
191
 
174
192
  // Handle operators and Delimiters
@@ -176,7 +194,6 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
176
194
  return 'operator';
177
195
  }
178
196
 
179
-
180
197
  // Handle Strings
181
198
  if (stream.match(stringPrefixes)) {
182
199
  state.tokenize = tokenStringFactory(stream.current());
@@ -187,7 +204,6 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
187
204
  return 'meta';
188
205
  }
189
206
 
190
-
191
207
  if (stream.match(delimiters)) {
192
208
  return null;
193
209
  }
@@ -200,21 +216,74 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
200
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
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
238
  return 'variable';
207
239
  }
240
+
208
241
  // Handle non-detected items
209
242
  stream.next();
210
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
282
  function tokenStringFactory(delimiter) {
214
- while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
283
+ while ('bruv'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
215
284
  delimiter = delimiter.substr(1);
216
285
  }
217
- var singleline = delimiter.length == 1;
286
+ var singleline = delimiter == "'";
218
287
  var OUTCLASS = 'string';
219
288
 
220
289
  function tokenString(stream, state) {
@@ -245,42 +314,38 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
245
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
317
  var external = {
267
318
  startState: function() {
268
319
  return {
269
320
  tokenize: tokenBase,
270
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
330
  token: function(stream, state) {
276
- var style = tokenLexer(stream, state);
277
- state.lastStyle = style;
331
+ var style = state.tokenize(stream, state);
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
343
  return style;
279
344
  },
280
345
 
281
346
  indent: function(state, textAfter) {
282
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
349
  delta = -1;
285
350
  }
286
351
  return (state.scopes.length + delta) * _conf.indentUnit;