codemirror-rails 5.10 → 5.11

Sign up to get free protection for your applications and to get access to all the features.
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;