1414CodeMirror . defineMode ( "julia" , function ( _conf , parserConf ) {
1515 var ERRORCLASS = 'error' ;
1616
17- function wordRegexp ( words ) {
18- return new RegExp ( "^((" + words . join ( ")|(" ) + "))\\b" ) ;
17+ function wordRegexp ( words , end ) {
18+ if ( typeof end === 'undefined' ) { end = "\\b" ; }
19+ return new RegExp ( "^((" + words . join ( ")|(" ) + "))" + end ) ;
1920 }
2021
22+ var octChar = "\\\\[0-7]{1,3}" ;
23+ var hexChar = "\\\\x[A-Fa-f0-9]{1,2}" ;
24+ var specialChar = "\\\\[abfnrtv0%?'\"\\\\]" ;
25+ var singleChar = "([^\\u0027\\u005C\\uD800-\\uDFFF]|[\\uD800-\\uDFFF][\\uDC00-\\uDFFF])" ;
2126 var operators = parserConf . operators || / ^ \. ? [ | & ^ \\ % * + \- < > ! = \/ ] = ? | \? | ~ | : | \$ | \. [ < > ] | < < = ? | > > > ? = ? | \. [ < > = ] = | - > ? | \/ \/ | \b i n \b (? ! \( ) | [ \u2208 \u2209 ] (? ! \( ) / ;
2227 var delimiters = parserConf . delimiters || / ^ [ ; , ( ) [ \] { } ] / ;
23- var identifiers = parserConf . identifiers || / ^ [ _ A - Z a - z \u00A1 - \uFFFF ] [ _ A - Z a - z 0 - 9 \u00A1 - \uFFFF ] * ! * / ;
28+ var identifiers = parserConf . identifiers || / ^ [ _ A - Z a - z \u00A1 - \uFFFF ] [ \w \u00A1 - \uFFFF ] * ! * / ;
29+ var charsList = [ octChar , hexChar , specialChar , singleChar ] ;
2430 var blockOpeners = [ "begin" , "function" , "type" , "immutable" , "let" , "macro" , "for" , "while" , "quote" , "if" , "else" , "elseif" , "try" , "finally" , "catch" , "do" ] ;
2531 var blockClosers = [ "end" , "else" , "elseif" , "catch" , "finally" ] ;
2632 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' ] ;
2733 var builtinList = [ 'true' , 'false' , 'nothing' , 'NaN' , 'Inf' ] ;
2834
2935 //var stringPrefixes = new RegExp("^[br]?('|\")")
30- var stringPrefixes = / ^ ( ` | ' | " { 3 } | ( [ b r v ] ? " ) ) / ;
36+ var stringPrefixes = / ^ ( ` | " { 3 } | ( [ b r v ] ? " ) ) / ;
37+ var chars = wordRegexp ( charsList , "'" ) ;
3138 var keywords = wordRegexp ( keywordList ) ;
3239 var builtins = wordRegexp ( builtinList ) ;
3340 var openers = wordRegexp ( blockOpeners ) ;
3441 var closers = wordRegexp ( blockClosers ) ;
35- var macro = / ^ @ [ _ A - Z a - z ] [ _ A - Z a - z 0 - 9 ] * / ;
36- var symbol = / ^ : [ _ A - Z a - z \u00A1 - \uFFFF ] [ _ A - Z a - z 0 - 9 \u00A1 - \uFFFF ] * ! * / ;
37- var typeAnnotation = / ^ : : [ ^ . , ; " { ( ) = $ \s ] + ( { [ ^ } ] * } + ) * / ;
42+ var macro = / ^ @ [ _ A - Z a - z ] [ \w ] * / ;
43+ var symbol = / ^ : [ _ A - Z a - z \u00A1 - \uFFFF ] [ \w \u00A1 - \uFFFF ] * ! * / ;
44+ var typeAnnotation = / ^ : : [ ^ , ; " { ( ) = $ \s ] + ( { [ ^ } ] * } + ) * / ;
3845
3946 function inArray ( state ) {
4047 var ch = currentScope ( state ) ;
@@ -53,19 +60,10 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
5360
5461 // tokenizers
5562 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' ;
63+ // Handle multiline comments
64+ if ( stream . match ( / ^ # = / , false ) ) {
65+ state . tokenize = tokenComment ;
66+ return state . tokenize ( stream , state ) ;
6967 }
7068
7169 // Handle scope changes
@@ -100,6 +98,10 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
10098 state . scopes . push ( '[' ) ;
10199 }
102100
101+ if ( ch === '(' ) {
102+ state . scopes . push ( '(' ) ;
103+ }
104+
103105 var scope = currentScope ( state ) ;
104106
105107 if ( scope == '[' && ch === ']' ) {
@@ -137,33 +139,20 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
137139 // Handle Number Literals
138140 if ( stream . match ( / ^ [ 0 - 9 \. ] / , false ) ) {
139141 var imMatcher = RegExp ( / ^ i m \b / ) ;
140- var floatLiteral = false ;
142+ var numberLiteral = false ;
141143 // Floats
142- if ( stream . match ( / ^ \d * \. (? ! \. ) \d + ( [ e f ] [ \+ \- ] ? \d + ) ? / i) ) { floatLiteral = true ; }
143- if ( stream . match ( / ^ \d + \. (? ! \. ) \d * / ) ) { floatLiteral = true ; }
144- if ( stream . match ( / ^ \. \d + / ) ) { floatLiteral = true ; }
145- if ( stream . match ( / ^ 0 x \. [ 0 - 9 a - f ] + p [ \+ \- ] ? \d + / i) ) { floatLiteral = true ; }
146- if ( floatLiteral ) {
147- // Float literals may be "imaginary"
148- stream . match ( imMatcher ) ;
149- state . leavingExpr = true ;
150- return 'number' ;
151- }
144+ if ( stream . match ( / ^ \d * \. (? ! \. ) \d * ( [ E e f ] [ \+ \- ] ? \d + ) ? / i) ) { numberLiteral = true ; }
145+ if ( stream . match ( / ^ \d + \. (? ! \. ) \d * / ) ) { numberLiteral = true ; }
146+ if ( stream . match ( / ^ \. \d + / ) ) { numberLiteral = true ; }
147+ if ( stream . match ( / ^ 0 x \. [ 0 - 9 a - f ] + p [ \+ \- ] ? \d + / i) ) { numberLiteral = true ; }
152148 // Integers
153- var intLiteral = false ;
154- // Hex
155- if ( stream . match ( / ^ 0 x [ 0 - 9 a - f ] + / i) ) { intLiteral = true ; }
156- // Binary
157- if ( stream . match ( / ^ 0 b [ 0 1 ] + / i) ) { intLiteral = true ; }
158- // Octal
159- if ( stream . match ( / ^ 0 o [ 0 - 7 ] + / i) ) { intLiteral = true ; }
160- // Decimal
161- if ( stream . match ( / ^ [ 1 - 9 ] \d * ( e [ \+ \- ] ? \d + ) ? / ) ) {
162- intLiteral = true ;
163- }
149+ if ( stream . match ( / ^ 0 x [ 0 - 9 a - f ] + / i) ) { numberLiteral = true ; } // Hex
150+ if ( stream . match ( / ^ 0 b [ 0 1 ] + / i) ) { numberLiteral = true ; } // Binary
151+ if ( stream . match ( / ^ 0 o [ 0 - 7 ] + / i) ) { numberLiteral = true ; } // Octal
152+ if ( stream . match ( / ^ [ 1 - 9 ] \d * ( e [ \+ \- ] ? \d + ) ? / ) ) { numberLiteral = true ; } // Decimal
164153 // Zero by itself with no other piece of number.
165- if ( stream . match ( / ^ 0 (? ! [ \d x ] ) / i) ) { intLiteral = true ; }
166- if ( intLiteral ) {
154+ if ( stream . match ( / ^ 0 (? ! [ \d x ] ) / i) ) { numberLiteral = true ; }
155+ if ( numberLiteral ) {
167156 // Integer literals may be "long"
168157 stream . match ( imMatcher ) ;
169158 state . leavingExpr = true ;
@@ -194,6 +183,12 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
194183 return 'operator' ;
195184 }
196185
186+ // Handle Chars
187+ if ( stream . match ( / ^ ' / ) ) {
188+ state . tokenize = tokenChar ;
189+ return state . tokenize ( stream , state ) ;
190+ }
191+
197192 // Handle Strings
198193 if ( stream . match ( stringPrefixes ) ) {
199194 state . tokenize = tokenStringFactory ( stream . current ( ) ) ;
@@ -269,7 +264,7 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
269264 // over two or more lines.
270265 if ( stream . match ( / ^ $ / g, false ) ) {
271266 stream . backUp ( state . charsAdvanced ) ;
272- while ( state . scopes . length > state . firstParenPos + 1 )
267+ while ( state . scopes . length > state . firstParenPos )
273268 state . scopes . pop ( ) ;
274269 state . firstParenPos = - 1 ;
275270 state . charsAdvanced = 0 ;
@@ -279,33 +274,65 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
279274 return callOrDef ( stream , state ) ;
280275 }
281276
277+ function tokenComment ( stream , state ) {
278+ if ( stream . match ( / ^ # = / ) ) {
279+ state . weakScopes ++ ;
280+ }
281+ if ( ! stream . match ( / .* ?(? = ( # = | = # ) ) / ) ) {
282+ stream . skipToEnd ( ) ;
283+ }
284+ if ( stream . match ( / ^ = # / ) ) {
285+ state . weakScopes -- ;
286+ if ( state . weakScopes == 0 )
287+ state . tokenize = tokenBase ;
288+ }
289+ return 'comment' ;
290+ }
291+
292+ function tokenChar ( stream , state ) {
293+ var isChar = false , match ;
294+ if ( stream . match ( chars ) ) {
295+ isChar = true ;
296+ } else if ( match = stream . match ( / \\ u ( [ a - f 0 - 9 ] { 1 , 4 } ) (? = ' ) / i) ) {
297+ var value = parseInt ( match [ 1 ] , 16 ) ;
298+ if ( value <= 55295 || value >= 57344 ) { // (U+0,U+D7FF), (U+E000,U+FFFF)
299+ isChar = true ;
300+ stream . next ( ) ;
301+ }
302+ } else if ( match = stream . match ( / \\ U ( [ A - F a - f 0 - 9 ] { 5 , 8 } ) (? = ' ) / ) ) {
303+ var value = parseInt ( match [ 1 ] , 16 ) ;
304+ if ( value <= 1114111 ) { // U+10FFFF
305+ isChar = true ;
306+ stream . next ( ) ;
307+ }
308+ }
309+ if ( isChar ) {
310+ state . leavingExpr = true ;
311+ state . tokenize = tokenBase ;
312+ return 'string' ;
313+ }
314+ if ( ! stream . match ( / ^ [ ^ ' ] + (? = ' ) / ) ) { stream . skipToEnd ( ) ; }
315+ if ( stream . match ( / ^ ' / ) ) { state . tokenize = tokenBase ; }
316+ return ERRORCLASS ;
317+ }
318+
282319 function tokenStringFactory ( delimiter ) {
283320 while ( 'bruv' . indexOf ( delimiter . charAt ( 0 ) . toLowerCase ( ) ) >= 0 ) {
284321 delimiter = delimiter . substr ( 1 ) ;
285322 }
286- var singleline = delimiter == "'" ;
287323 var OUTCLASS = 'string' ;
288324
289325 function tokenString ( stream , state ) {
290326 while ( ! stream . eol ( ) ) {
291- stream . eatWhile ( / [ ^ ' " \\ ] / ) ;
327+ stream . eatWhile ( / [ ^ " \\ ] / ) ;
292328 if ( stream . eat ( '\\' ) ) {
293329 stream . next ( ) ;
294- if ( singleline && stream . eol ( ) ) {
295- return OUTCLASS ;
296- }
297330 } else if ( stream . match ( delimiter ) ) {
298331 state . tokenize = tokenBase ;
332+ state . leavingExpr = true ;
299333 return OUTCLASS ;
300334 } else {
301- stream . eat ( / [ ' " ] / ) ;
302- }
303- }
304- if ( singleline ) {
305- if ( parserConf . singleLineStringErrors ) {
306- return ERRORCLASS ;
307- } else {
308- state . tokenize = tokenBase ;
335+ stream . eat ( / [ " ] / ) ;
309336 }
310337 }
311338 return OUTCLASS ;
@@ -319,6 +346,7 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
319346 return {
320347 tokenize : tokenBase ,
321348 scopes : [ ] ,
349+ weakScopes : 0 ,
322350 lastToken : null ,
323351 leavingExpr : false ,
324352 isDefinition : false ,
@@ -345,15 +373,15 @@ CodeMirror.defineMode("julia", function(_conf, parserConf) {
345373
346374 indent : function ( state , textAfter ) {
347375 var delta = 0 ;
348- if ( textAfter == "end " || textAfter == "] " || textAfter == "} " || textAfter == "else" || textAfter == "elseif" || textAfter == "catch" || textAfter == "finally" ) {
376+ if ( textAfter == "] " || textAfter == ") " || textAfter == "end " || textAfter == "else" || textAfter == "elseif" || textAfter == "catch" || textAfter == "finally" ) {
349377 delta = - 1 ;
350378 }
351379 return ( state . scopes . length + delta ) * _conf . indentUnit ;
352380 } ,
353381
382+ electricInput : / ( e n d | e l s e ( i f ) ? | c a t c h | f i n a l l y ) $ / ,
354383 lineComment : "#" ,
355- fold : "indent" ,
356- electricChars : "edlsifyh]}"
384+ fold : "indent"
357385 } ;
358386 return external ;
359387} ) ;
0 commit comments