clike.js (35779B)
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 // Distributed under an MIT license: https://codemirror.net/LICENSE 3 4 (function(mod) { 5 if (typeof exports == "object" && typeof module == "object") // CommonJS 6 mod(require("resource://devtools/client/shared/sourceeditor/codemirror/lib/codemirror.js")); 7 else if (typeof define == "function" && define.amd) // AMD 8 define(["../../lib/codemirror"], mod); 9 else // Plain browser env 10 mod(CodeMirror); 11 })(function(CodeMirror) { 12 "use strict"; 13 14 function Context(indented, column, type, info, align, prev) { 15 this.indented = indented; 16 this.column = column; 17 this.type = type; 18 this.info = info; 19 this.align = align; 20 this.prev = prev; 21 } 22 function pushContext(state, col, type, info) { 23 var indent = state.indented; 24 if (state.context && state.context.type == "statement" && type != "statement") 25 indent = state.context.indented; 26 return state.context = new Context(indent, col, type, info, null, state.context); 27 } 28 function popContext(state) { 29 var t = state.context.type; 30 if (t == ")" || t == "]" || t == "}") 31 state.indented = state.context.indented; 32 return state.context = state.context.prev; 33 } 34 35 function typeBefore(stream, state, pos) { 36 if (state.prevToken == "variable" || state.prevToken == "type") return true; 37 if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, pos))) return true; 38 if (state.typeAtEndOfLine && stream.column() == stream.indentation()) return true; 39 } 40 41 function isTopScope(context) { 42 for (;;) { 43 if (!context || context.type == "top") return true; 44 if (context.type == "}" && context.prev.info != "namespace") return false; 45 context = context.prev; 46 } 47 } 48 49 CodeMirror.defineMode("clike", function(config, parserConfig) { 50 var indentUnit = config.indentUnit, 51 statementIndentUnit = parserConfig.statementIndentUnit || indentUnit, 52 dontAlignCalls = parserConfig.dontAlignCalls, 53 keywords = parserConfig.keywords || {}, 54 types = parserConfig.types || {}, 55 builtin = parserConfig.builtin || {}, 56 blockKeywords = parserConfig.blockKeywords || {}, 57 defKeywords = parserConfig.defKeywords || {}, 58 atoms = parserConfig.atoms || {}, 59 hooks = parserConfig.hooks || {}, 60 multiLineStrings = parserConfig.multiLineStrings, 61 indentStatements = parserConfig.indentStatements !== false, 62 indentSwitch = parserConfig.indentSwitch !== false, 63 namespaceSeparator = parserConfig.namespaceSeparator, 64 isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/, 65 numberStart = parserConfig.numberStart || /[\d\.]/, 66 number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i, 67 isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/, 68 isIdentifierChar = parserConfig.isIdentifierChar || /[\w\$_\xa1-\uffff]/, 69 // An optional function that takes a {string} token and returns true if it 70 // should be treated as a builtin. 71 isReservedIdentifier = parserConfig.isReservedIdentifier || false; 72 73 var curPunc, isDefKeyword; 74 75 function tokenBase(stream, state) { 76 var ch = stream.next(); 77 if (hooks[ch]) { 78 var result = hooks[ch](stream, state); 79 if (result !== false) return result; 80 } 81 if (ch == '"' || ch == "'") { 82 state.tokenize = tokenString(ch); 83 return state.tokenize(stream, state); 84 } 85 if (isPunctuationChar.test(ch)) { 86 curPunc = ch; 87 return null; 88 } 89 if (numberStart.test(ch)) { 90 stream.backUp(1) 91 if (stream.match(number)) return "number" 92 stream.next() 93 } 94 if (ch == "/") { 95 if (stream.eat("*")) { 96 state.tokenize = tokenComment; 97 return tokenComment(stream, state); 98 } 99 if (stream.eat("/")) { 100 stream.skipToEnd(); 101 return "comment"; 102 } 103 } 104 if (isOperatorChar.test(ch)) { 105 while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {} 106 return "operator"; 107 } 108 stream.eatWhile(isIdentifierChar); 109 if (namespaceSeparator) while (stream.match(namespaceSeparator)) 110 stream.eatWhile(isIdentifierChar); 111 112 var cur = stream.current(); 113 if (contains(keywords, cur)) { 114 if (contains(blockKeywords, cur)) curPunc = "newstatement"; 115 if (contains(defKeywords, cur)) isDefKeyword = true; 116 return "keyword"; 117 } 118 if (contains(types, cur)) return "type"; 119 if (contains(builtin, cur) 120 || (isReservedIdentifier && isReservedIdentifier(cur))) { 121 if (contains(blockKeywords, cur)) curPunc = "newstatement"; 122 return "builtin"; 123 } 124 if (contains(atoms, cur)) return "atom"; 125 return "variable"; 126 } 127 128 function tokenString(quote) { 129 return function(stream, state) { 130 var escaped = false, next, end = false; 131 while ((next = stream.next()) != null) { 132 if (next == quote && !escaped) {end = true; break;} 133 escaped = !escaped && next == "\\"; 134 } 135 if (end || !(escaped || multiLineStrings)) 136 state.tokenize = null; 137 return "string"; 138 }; 139 } 140 141 function tokenComment(stream, state) { 142 var maybeEnd = false, ch; 143 while (ch = stream.next()) { 144 if (ch == "/" && maybeEnd) { 145 state.tokenize = null; 146 break; 147 } 148 maybeEnd = (ch == "*"); 149 } 150 return "comment"; 151 } 152 153 function maybeEOL(stream, state) { 154 if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context)) 155 state.typeAtEndOfLine = typeBefore(stream, state, stream.pos) 156 } 157 158 // Interface 159 160 return { 161 startState: function(basecolumn) { 162 return { 163 tokenize: null, 164 context: new Context((basecolumn || 0) - indentUnit, 0, "top", null, false), 165 indented: 0, 166 startOfLine: true, 167 prevToken: null 168 }; 169 }, 170 171 token: function(stream, state) { 172 var ctx = state.context; 173 if (stream.sol()) { 174 if (ctx.align == null) ctx.align = false; 175 state.indented = stream.indentation(); 176 state.startOfLine = true; 177 } 178 if (stream.eatSpace()) { maybeEOL(stream, state); return null; } 179 curPunc = isDefKeyword = null; 180 var style = (state.tokenize || tokenBase)(stream, state); 181 if (style == "comment" || style == "meta") return style; 182 if (ctx.align == null) ctx.align = true; 183 184 if (curPunc == ";" || curPunc == ":" || (curPunc == "," && stream.match(/^\s*(?:\/\/.*)?$/, false))) 185 while (state.context.type == "statement") popContext(state); 186 else if (curPunc == "{") pushContext(state, stream.column(), "}"); 187 else if (curPunc == "[") pushContext(state, stream.column(), "]"); 188 else if (curPunc == "(") pushContext(state, stream.column(), ")"); 189 else if (curPunc == "}") { 190 while (ctx.type == "statement") ctx = popContext(state); 191 if (ctx.type == "}") ctx = popContext(state); 192 while (ctx.type == "statement") ctx = popContext(state); 193 } 194 else if (curPunc == ctx.type) popContext(state); 195 else if (indentStatements && 196 (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") || 197 (ctx.type == "statement" && curPunc == "newstatement"))) { 198 pushContext(state, stream.column(), "statement", stream.current()); 199 } 200 201 if (style == "variable" && 202 ((state.prevToken == "def" || 203 (parserConfig.typeFirstDefinitions && typeBefore(stream, state, stream.start) && 204 isTopScope(state.context) && stream.match(/^\s*\(/, false))))) 205 style = "def"; 206 207 if (hooks.token) { 208 var result = hooks.token(stream, state, style); 209 if (result !== undefined) style = result; 210 } 211 212 if (style == "def" && parserConfig.styleDefs === false) style = "variable"; 213 214 state.startOfLine = false; 215 state.prevToken = isDefKeyword ? "def" : style || curPunc; 216 maybeEOL(stream, state); 217 return style; 218 }, 219 220 indent: function(state, textAfter) { 221 if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass; 222 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); 223 var closing = firstChar == ctx.type; 224 if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev; 225 if (parserConfig.dontIndentStatements) 226 while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info)) 227 ctx = ctx.prev 228 if (hooks.indent) { 229 var hook = hooks.indent(state, ctx, textAfter, indentUnit); 230 if (typeof hook == "number") return hook 231 } 232 var switchBlock = ctx.prev && ctx.prev.info == "switch"; 233 if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) { 234 while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev 235 return ctx.indented 236 } 237 if (ctx.type == "statement") 238 return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit); 239 if (ctx.align && (!dontAlignCalls || ctx.type != ")")) 240 return ctx.column + (closing ? 0 : 1); 241 if (ctx.type == ")" && !closing) 242 return ctx.indented + statementIndentUnit; 243 244 return ctx.indented + (closing ? 0 : indentUnit) + 245 (!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0); 246 }, 247 248 electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/, 249 blockCommentStart: "/*", 250 blockCommentEnd: "*/", 251 blockCommentContinue: " * ", 252 lineComment: "//", 253 fold: "brace" 254 }; 255 }); 256 257 function words(str) { 258 var obj = {}, words = str.split(" "); 259 for (var i = 0; i < words.length; ++i) obj[words[i]] = true; 260 return obj; 261 } 262 function contains(words, word) { 263 if (typeof words === "function") { 264 return words(word); 265 } else { 266 return words.propertyIsEnumerable(word); 267 } 268 } 269 var cKeywords = "auto if break case register continue return default do sizeof " + 270 "static else struct switch extern typedef union for goto while enum const " + 271 "volatile inline restrict asm fortran"; 272 273 // Do not use this. Use the cTypes function below. This is global just to avoid 274 // excessive calls when cTypes is being called multiple times during a parse. 275 var basicCTypes = words("int long char short double float unsigned signed " + 276 "void bool"); 277 278 // Do not use this. Use the objCTypes function below. This is global just to avoid 279 // excessive calls when objCTypes is being called multiple times during a parse. 280 var basicObjCTypes = words("SEL instancetype id Class Protocol BOOL"); 281 282 // Returns true if identifier is a "C" type. 283 // C type is defined as those that are reserved by the compiler (basicTypes), 284 // and those that end in _t (Reserved by POSIX for types) 285 // http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html 286 function cTypes(identifier) { 287 return contains(basicCTypes, identifier) || /.+_t$/.test(identifier); 288 } 289 290 // Returns true if identifier is a "Objective C" type. 291 function objCTypes(identifier) { 292 return cTypes(identifier) || contains(basicObjCTypes, identifier); 293 } 294 295 var cBlockKeywords = "case do else for if switch while struct enum union"; 296 var cDefKeywords = "struct enum union"; 297 298 function cppHook(stream, state) { 299 if (!state.startOfLine) return false 300 for (var ch, next = null; ch = stream.peek();) { 301 if (ch == "\\" && stream.match(/^.$/)) { 302 next = cppHook 303 break 304 } else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) { 305 break 306 } 307 stream.next() 308 } 309 state.tokenize = next 310 return "meta" 311 } 312 313 function pointerHook(_stream, state) { 314 if (state.prevToken == "type") return "type"; 315 return false; 316 } 317 318 // For C and C++ (and ObjC): identifiers starting with __ 319 // or _ followed by a capital letter are reserved for the compiler. 320 function cIsReservedIdentifier(token) { 321 if (!token || token.length < 2) return false; 322 if (token[0] != '_') return false; 323 return (token[1] == '_') || (token[1] !== token[1].toLowerCase()); 324 } 325 326 function cpp14Literal(stream) { 327 stream.eatWhile(/[\w\.']/); 328 return "number"; 329 } 330 331 function cpp11StringHook(stream, state) { 332 stream.backUp(1); 333 // Raw strings. 334 if (stream.match(/(R|u8R|uR|UR|LR)/)) { 335 var match = stream.match(/"([^\s\\()]{0,16})\(/); 336 if (!match) { 337 return false; 338 } 339 state.cpp11RawStringDelim = match[1]; 340 state.tokenize = tokenRawString; 341 return tokenRawString(stream, state); 342 } 343 // Unicode strings/chars. 344 if (stream.match(/(u8|u|U|L)/)) { 345 if (stream.match(/["']/, /* eat */ false)) { 346 return "string"; 347 } 348 return false; 349 } 350 // Ignore this hook. 351 stream.next(); 352 return false; 353 } 354 355 function cppLooksLikeConstructor(word) { 356 var lastTwo = /(\w+)::~?(\w+)$/.exec(word); 357 return lastTwo && lastTwo[1] == lastTwo[2]; 358 } 359 360 // C#-style strings where "" escapes a quote. 361 function tokenAtString(stream, state) { 362 var next; 363 while ((next = stream.next()) != null) { 364 if (next == '"' && !stream.eat('"')) { 365 state.tokenize = null; 366 break; 367 } 368 } 369 return "string"; 370 } 371 372 // C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where 373 // <delim> can be a string up to 16 characters long. 374 function tokenRawString(stream, state) { 375 // Escape characters that have special regex meanings. 376 var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&'); 377 var match = stream.match(new RegExp(".*?\\)" + delim + '"')); 378 if (match) 379 state.tokenize = null; 380 else 381 stream.skipToEnd(); 382 return "string"; 383 } 384 385 function def(mimes, mode) { 386 if (typeof mimes == "string") mimes = [mimes]; 387 var words = []; 388 function add(obj) { 389 if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop)) 390 words.push(prop); 391 } 392 add(mode.keywords); 393 add(mode.types); 394 add(mode.builtin); 395 add(mode.atoms); 396 if (words.length) { 397 mode.helperType = mimes[0]; 398 CodeMirror.registerHelper("hintWords", mimes[0], words); 399 } 400 401 for (var i = 0; i < mimes.length; ++i) 402 CodeMirror.defineMIME(mimes[i], mode); 403 } 404 405 def(["text/x-csrc", "text/x-c", "text/x-chdr"], { 406 name: "clike", 407 keywords: words(cKeywords), 408 types: cTypes, 409 blockKeywords: words(cBlockKeywords), 410 defKeywords: words(cDefKeywords), 411 typeFirstDefinitions: true, 412 atoms: words("NULL true false"), 413 isReservedIdentifier: cIsReservedIdentifier, 414 hooks: { 415 "#": cppHook, 416 "*": pointerHook, 417 }, 418 modeProps: {fold: ["brace", "include"]} 419 }); 420 421 def(["text/x-c++src", "text/x-c++hdr"], { 422 name: "clike", 423 // Keywords from https://en.cppreference.com/w/cpp/keyword includes C++20. 424 keywords: words(cKeywords + "alignas alignof and and_eq audit axiom bitand bitor catch " + 425 "class compl concept constexpr const_cast decltype delete dynamic_cast " + 426 "explicit export final friend import module mutable namespace new noexcept " + 427 "not not_eq operator or or_eq override private protected public " + 428 "reinterpret_cast requires static_assert static_cast template this " + 429 "thread_local throw try typeid typename using virtual xor xor_eq"), 430 types: cTypes, 431 blockKeywords: words(cBlockKeywords + " class try catch"), 432 defKeywords: words(cDefKeywords + " class namespace"), 433 typeFirstDefinitions: true, 434 atoms: words("true false NULL nullptr"), 435 dontIndentStatements: /^template$/, 436 isIdentifierChar: /[\w\$_~\xa1-\uffff]/, 437 isReservedIdentifier: cIsReservedIdentifier, 438 hooks: { 439 "#": cppHook, 440 "*": pointerHook, 441 "u": cpp11StringHook, 442 "U": cpp11StringHook, 443 "L": cpp11StringHook, 444 "R": cpp11StringHook, 445 "0": cpp14Literal, 446 "1": cpp14Literal, 447 "2": cpp14Literal, 448 "3": cpp14Literal, 449 "4": cpp14Literal, 450 "5": cpp14Literal, 451 "6": cpp14Literal, 452 "7": cpp14Literal, 453 "8": cpp14Literal, 454 "9": cpp14Literal, 455 token: function(stream, state, style) { 456 if (style == "variable" && stream.peek() == "(" && 457 (state.prevToken == ";" || state.prevToken == null || 458 state.prevToken == "}") && 459 cppLooksLikeConstructor(stream.current())) 460 return "def"; 461 } 462 }, 463 namespaceSeparator: "::", 464 modeProps: {fold: ["brace", "include"]} 465 }); 466 467 def("text/x-java", { 468 name: "clike", 469 keywords: words("abstract assert break case catch class const continue default " + 470 "do else enum extends final finally for goto if implements import " + 471 "instanceof interface native new package private protected public " + 472 "return static strictfp super switch synchronized this throw throws transient " + 473 "try volatile while @interface"), 474 types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " + 475 "Integer Long Number Object Short String StringBuffer StringBuilder Void"), 476 blockKeywords: words("catch class do else finally for if switch try while"), 477 defKeywords: words("class interface enum @interface"), 478 typeFirstDefinitions: true, 479 atoms: words("true false null"), 480 number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i, 481 hooks: { 482 "@": function(stream) { 483 // Don't match the @interface keyword. 484 if (stream.match('interface', false)) return false; 485 486 stream.eatWhile(/[\w\$_]/); 487 return "meta"; 488 } 489 }, 490 modeProps: {fold: ["brace", "import"]} 491 }); 492 493 def("text/x-csharp", { 494 name: "clike", 495 keywords: words("abstract as async await base break case catch checked class const continue" + 496 " default delegate do else enum event explicit extern finally fixed for" + 497 " foreach goto if implicit in interface internal is lock namespace new" + 498 " operator out override params private protected public readonly ref return sealed" + 499 " sizeof stackalloc static struct switch this throw try typeof unchecked" + 500 " unsafe using virtual void volatile while add alias ascending descending dynamic from get" + 501 " global group into join let orderby partial remove select set value var yield"), 502 types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" + 503 " Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" + 504 " UInt64 bool byte char decimal double short int long object" + 505 " sbyte float string ushort uint ulong"), 506 blockKeywords: words("catch class do else finally for foreach if struct switch try while"), 507 defKeywords: words("class interface namespace struct var"), 508 typeFirstDefinitions: true, 509 atoms: words("true false null"), 510 hooks: { 511 "@": function(stream, state) { 512 if (stream.eat('"')) { 513 state.tokenize = tokenAtString; 514 return tokenAtString(stream, state); 515 } 516 stream.eatWhile(/[\w\$_]/); 517 return "meta"; 518 } 519 } 520 }); 521 522 function tokenTripleString(stream, state) { 523 var escaped = false; 524 while (!stream.eol()) { 525 if (!escaped && stream.match('"""')) { 526 state.tokenize = null; 527 break; 528 } 529 escaped = stream.next() == "\\" && !escaped; 530 } 531 return "string"; 532 } 533 534 function tokenNestedComment(depth) { 535 return function (stream, state) { 536 var ch 537 while (ch = stream.next()) { 538 if (ch == "*" && stream.eat("/")) { 539 if (depth == 1) { 540 state.tokenize = null 541 break 542 } else { 543 state.tokenize = tokenNestedComment(depth - 1) 544 return state.tokenize(stream, state) 545 } 546 } else if (ch == "/" && stream.eat("*")) { 547 state.tokenize = tokenNestedComment(depth + 1) 548 return state.tokenize(stream, state) 549 } 550 } 551 return "comment" 552 } 553 } 554 555 def("text/x-scala", { 556 name: "clike", 557 keywords: words( 558 /* scala */ 559 "abstract case catch class def do else extends final finally for forSome if " + 560 "implicit import lazy match new null object override package private protected return " + 561 "sealed super this throw trait try type val var while with yield _ " + 562 563 /* package scala */ 564 "assert assume require print println printf readLine readBoolean readByte readShort " + 565 "readChar readInt readLong readFloat readDouble" 566 ), 567 types: words( 568 "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " + 569 "Enumeration Equiv Error Exception Fractional Function IndexedSeq Int Integral Iterable " + 570 "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " + 571 "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " + 572 "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " + 573 574 /* package java.lang */ 575 "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + 576 "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + 577 "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + 578 "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void" 579 ), 580 multiLineStrings: true, 581 blockKeywords: words("catch class enum do else finally for forSome if match switch try while"), 582 defKeywords: words("class enum def object package trait type val var"), 583 atoms: words("true false null"), 584 indentStatements: false, 585 indentSwitch: false, 586 isOperatorChar: /[+\-*&%=<>!?|\/#:@]/, 587 hooks: { 588 "@": function(stream) { 589 stream.eatWhile(/[\w\$_]/); 590 return "meta"; 591 }, 592 '"': function(stream, state) { 593 if (!stream.match('""')) return false; 594 state.tokenize = tokenTripleString; 595 return state.tokenize(stream, state); 596 }, 597 "'": function(stream) { 598 stream.eatWhile(/[\w\$_\xa1-\uffff]/); 599 return "atom"; 600 }, 601 "=": function(stream, state) { 602 var cx = state.context 603 if (cx.type == "}" && cx.align && stream.eat(">")) { 604 state.context = new Context(cx.indented, cx.column, cx.type, cx.info, null, cx.prev) 605 return "operator" 606 } else { 607 return false 608 } 609 }, 610 611 "/": function(stream, state) { 612 if (!stream.eat("*")) return false 613 state.tokenize = tokenNestedComment(1) 614 return state.tokenize(stream, state) 615 } 616 }, 617 modeProps: {closeBrackets: {pairs: '()[]{}""', triples: '"'}} 618 }); 619 620 function tokenKotlinString(tripleString){ 621 return function (stream, state) { 622 var escaped = false, next, end = false; 623 while (!stream.eol()) { 624 if (!tripleString && !escaped && stream.match('"') ) {end = true; break;} 625 if (tripleString && stream.match('"""')) {end = true; break;} 626 next = stream.next(); 627 if(!escaped && next == "$" && stream.match('{')) 628 stream.skipTo("}"); 629 escaped = !escaped && next == "\\" && !tripleString; 630 } 631 if (end || !tripleString) 632 state.tokenize = null; 633 return "string"; 634 } 635 } 636 637 def("text/x-kotlin", { 638 name: "clike", 639 keywords: words( 640 /*keywords*/ 641 "package as typealias class interface this super val operator " + 642 "var fun for is in This throw return annotation " + 643 "break continue object if else while do try when !in !is as? " + 644 645 /*soft keywords*/ 646 "file import where by get set abstract enum open inner override private public internal " + 647 "protected catch finally out final vararg reified dynamic companion constructor init " + 648 "sealed field property receiver param sparam lateinit data inline noinline tailrec " + 649 "external annotation crossinline const operator infix suspend actual expect setparam" 650 ), 651 types: words( 652 /* package java.lang */ 653 "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + 654 "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + 655 "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + 656 "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void Annotation Any BooleanArray " + 657 "ByteArray Char CharArray DeprecationLevel DoubleArray Enum FloatArray Function Int IntArray Lazy " + 658 "LazyThreadSafetyMode LongArray Nothing ShortArray Unit" 659 ), 660 intendSwitch: false, 661 indentStatements: false, 662 multiLineStrings: true, 663 number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i, 664 blockKeywords: words("catch class do else finally for if where try while enum"), 665 defKeywords: words("class val var object interface fun"), 666 atoms: words("true false null this"), 667 hooks: { 668 "@": function(stream) { 669 stream.eatWhile(/[\w\$_]/); 670 return "meta"; 671 }, 672 '*': function(_stream, state) { 673 return state.prevToken == '.' ? 'variable' : 'operator'; 674 }, 675 '"': function(stream, state) { 676 state.tokenize = tokenKotlinString(stream.match('""')); 677 return state.tokenize(stream, state); 678 }, 679 "/": function(stream, state) { 680 if (!stream.eat("*")) return false; 681 state.tokenize = tokenNestedComment(1); 682 return state.tokenize(stream, state) 683 }, 684 indent: function(state, ctx, textAfter, indentUnit) { 685 var firstChar = textAfter && textAfter.charAt(0); 686 if ((state.prevToken == "}" || state.prevToken == ")") && textAfter == "") 687 return state.indented; 688 if ((state.prevToken == "operator" && textAfter != "}" && state.context.type != "}") || 689 state.prevToken == "variable" && firstChar == "." || 690 (state.prevToken == "}" || state.prevToken == ")") && firstChar == ".") 691 return indentUnit * 2 + ctx.indented; 692 if (ctx.align && ctx.type == "}") 693 return ctx.indented + (state.context.type == (textAfter || "").charAt(0) ? 0 : indentUnit); 694 } 695 }, 696 modeProps: {closeBrackets: {triples: '"'}} 697 }); 698 699 def(["x-shader/x-vertex", "x-shader/x-fragment"], { 700 name: "clike", 701 keywords: words("sampler1D sampler2D sampler3D samplerCube " + 702 "sampler1DShadow sampler2DShadow " + 703 "const attribute uniform varying " + 704 "break continue discard return " + 705 "for while do if else struct " + 706 "in out inout"), 707 types: words("float int bool void " + 708 "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " + 709 "mat2 mat3 mat4"), 710 blockKeywords: words("for while do if else struct"), 711 builtin: words("radians degrees sin cos tan asin acos atan " + 712 "pow exp log exp2 sqrt inversesqrt " + 713 "abs sign floor ceil fract mod min max clamp mix step smoothstep " + 714 "length distance dot cross normalize ftransform faceforward " + 715 "reflect refract matrixCompMult " + 716 "lessThan lessThanEqual greaterThan greaterThanEqual " + 717 "equal notEqual any all not " + 718 "texture1D texture1DProj texture1DLod texture1DProjLod " + 719 "texture2D texture2DProj texture2DLod texture2DProjLod " + 720 "texture3D texture3DProj texture3DLod texture3DProjLod " + 721 "textureCube textureCubeLod " + 722 "shadow1D shadow2D shadow1DProj shadow2DProj " + 723 "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " + 724 "dFdx dFdy fwidth " + 725 "noise1 noise2 noise3 noise4"), 726 atoms: words("true false " + 727 "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " + 728 "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " + 729 "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " + 730 "gl_FogCoord gl_PointCoord " + 731 "gl_Position gl_PointSize gl_ClipVertex " + 732 "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " + 733 "gl_TexCoord gl_FogFragCoord " + 734 "gl_FragCoord gl_FrontFacing " + 735 "gl_FragData gl_FragDepth " + 736 "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " + 737 "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " + 738 "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " + 739 "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " + 740 "gl_ProjectionMatrixInverseTranspose " + 741 "gl_ModelViewProjectionMatrixInverseTranspose " + 742 "gl_TextureMatrixInverseTranspose " + 743 "gl_NormalScale gl_DepthRange gl_ClipPlane " + 744 "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " + 745 "gl_FrontLightModelProduct gl_BackLightModelProduct " + 746 "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " + 747 "gl_FogParameters " + 748 "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " + 749 "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " + 750 "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " + 751 "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " + 752 "gl_MaxDrawBuffers"), 753 indentSwitch: false, 754 hooks: {"#": cppHook}, 755 modeProps: {fold: ["brace", "include"]} 756 }); 757 758 def("text/x-nesc", { 759 name: "clike", 760 keywords: words(cKeywords + " as atomic async call command component components configuration event generic " + 761 "implementation includes interface module new norace nx_struct nx_union post provides " + 762 "signal task uses abstract extends"), 763 types: cTypes, 764 blockKeywords: words(cBlockKeywords), 765 atoms: words("null true false"), 766 hooks: {"#": cppHook}, 767 modeProps: {fold: ["brace", "include"]} 768 }); 769 770 def("text/x-objectivec", { 771 name: "clike", 772 keywords: words(cKeywords + " bycopy byref in inout oneway out self super atomic nonatomic retain copy " + 773 "readwrite readonly strong weak assign typeof nullable nonnull null_resettable _cmd " + 774 "@interface @implementation @end @protocol @encode @property @synthesize @dynamic @class " + 775 "@public @package @private @protected @required @optional @try @catch @finally @import " + 776 "@selector @encode @defs @synchronized @autoreleasepool @compatibility_alias @available"), 777 types: objCTypes, 778 builtin: words("FOUNDATION_EXPORT FOUNDATION_EXTERN NS_INLINE NS_FORMAT_FUNCTION NS_RETURNS_RETAINED " + 779 "NS_ERROR_ENUM NS_RETURNS_NOT_RETAINED NS_RETURNS_INNER_POINTER NS_DESIGNATED_INITIALIZER " + 780 "NS_ENUM NS_OPTIONS NS_REQUIRES_NIL_TERMINATION NS_ASSUME_NONNULL_BEGIN " + 781 "NS_ASSUME_NONNULL_END NS_SWIFT_NAME NS_REFINED_FOR_SWIFT"), 782 blockKeywords: words(cBlockKeywords + " @synthesize @try @catch @finally @autoreleasepool @synchronized"), 783 defKeywords: words(cDefKeywords + " @interface @implementation @protocol @class"), 784 dontIndentStatements: /^@.*$/, 785 typeFirstDefinitions: true, 786 atoms: words("YES NO NULL Nil nil true false nullptr"), 787 isReservedIdentifier: cIsReservedIdentifier, 788 hooks: { 789 "#": cppHook, 790 "*": pointerHook, 791 }, 792 modeProps: {fold: ["brace", "include"]} 793 }); 794 795 def("text/x-squirrel", { 796 name: "clike", 797 keywords: words("base break clone continue const default delete enum extends function in class" + 798 " foreach local resume return this throw typeof yield constructor instanceof static"), 799 types: cTypes, 800 blockKeywords: words("case catch class else for foreach if switch try while"), 801 defKeywords: words("function local class"), 802 typeFirstDefinitions: true, 803 atoms: words("true false null"), 804 hooks: {"#": cppHook}, 805 modeProps: {fold: ["brace", "include"]} 806 }); 807 808 // Ceylon Strings need to deal with interpolation 809 var stringTokenizer = null; 810 function tokenCeylonString(type) { 811 return function(stream, state) { 812 var escaped = false, next, end = false; 813 while (!stream.eol()) { 814 if (!escaped && stream.match('"') && 815 (type == "single" || stream.match('""'))) { 816 end = true; 817 break; 818 } 819 if (!escaped && stream.match('``')) { 820 stringTokenizer = tokenCeylonString(type); 821 end = true; 822 break; 823 } 824 next = stream.next(); 825 escaped = type == "single" && !escaped && next == "\\"; 826 } 827 if (end) 828 state.tokenize = null; 829 return "string"; 830 } 831 } 832 833 def("text/x-ceylon", { 834 name: "clike", 835 keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" + 836 " exists extends finally for function given if import in interface is let module new" + 837 " nonempty object of out outer package return satisfies super switch then this throw" + 838 " try value void while"), 839 types: function(word) { 840 // In Ceylon all identifiers that start with an uppercase are types 841 var first = word.charAt(0); 842 return (first === first.toUpperCase() && first !== first.toLowerCase()); 843 }, 844 blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"), 845 defKeywords: words("class dynamic function interface module object package value"), 846 builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" + 847 " native optional sealed see serializable shared suppressWarnings tagged throws variable"), 848 isPunctuationChar: /[\[\]{}\(\),;\:\.`]/, 849 isOperatorChar: /[+\-*&%=<>!?|^~:\/]/, 850 numberStart: /[\d#$]/, 851 number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i, 852 multiLineStrings: true, 853 typeFirstDefinitions: true, 854 atoms: words("true false null larger smaller equal empty finished"), 855 indentSwitch: false, 856 styleDefs: false, 857 hooks: { 858 "@": function(stream) { 859 stream.eatWhile(/[\w\$_]/); 860 return "meta"; 861 }, 862 '"': function(stream, state) { 863 state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single"); 864 return state.tokenize(stream, state); 865 }, 866 '`': function(stream, state) { 867 if (!stringTokenizer || !stream.match('`')) return false; 868 state.tokenize = stringTokenizer; 869 stringTokenizer = null; 870 return state.tokenize(stream, state); 871 }, 872 "'": function(stream) { 873 stream.eatWhile(/[\w\$_\xa1-\uffff]/); 874 return "atom"; 875 }, 876 token: function(_stream, state, style) { 877 if ((style == "variable" || style == "type") && 878 state.prevToken == ".") { 879 return "variable-2"; 880 } 881 } 882 }, 883 modeProps: { 884 fold: ["brace", "import"], 885 closeBrackets: {triples: '"'} 886 } 887 }); 888 889 });