File modules/editor/codemirror/mode/verilog/verilog.js
Last commit: Sun Dec 17 01:14:09 2017 +0100 Jan Dankert Integration eines weiteren Code-Editors: Codemirror. Demnächst müssen wir hier mal aufräumen und andere Editoren rauswerfen.
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")); 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 CodeMirror.defineMode("verilog", function(config, parserConfig) { 15 16 var indentUnit = config.indentUnit, 17 statementIndentUnit = parserConfig.statementIndentUnit || indentUnit, 18 dontAlignCalls = parserConfig.dontAlignCalls, 19 noIndentKeywords = parserConfig.noIndentKeywords || [], 20 multiLineStrings = parserConfig.multiLineStrings, 21 hooks = parserConfig.hooks || {}; 22 23 function words(str) { 24 var obj = {}, words = str.split(" "); 25 for (var i = 0; i < words.length; ++i) obj[words[i]] = true; 26 return obj; 27 } 28 29 /** 30 * Keywords from IEEE 1800-2012 31 */ 32 var keywords = words( 33 "accept_on alias always always_comb always_ff always_latch and assert assign assume automatic before begin bind " + 34 "bins binsof bit break buf bufif0 bufif1 byte case casex casez cell chandle checker class clocking cmos config " + 35 "const constraint context continue cover covergroup coverpoint cross deassign default defparam design disable " + 36 "dist do edge else end endcase endchecker endclass endclocking endconfig endfunction endgenerate endgroup " + 37 "endinterface endmodule endpackage endprimitive endprogram endproperty endspecify endsequence endtable endtask " + 38 "enum event eventually expect export extends extern final first_match for force foreach forever fork forkjoin " + 39 "function generate genvar global highz0 highz1 if iff ifnone ignore_bins illegal_bins implements implies import " + 40 "incdir include initial inout input inside instance int integer interconnect interface intersect join join_any " + 41 "join_none large let liblist library local localparam logic longint macromodule matches medium modport module " + 42 "nand negedge nettype new nexttime nmos nor noshowcancelled not notif0 notif1 null or output package packed " + 43 "parameter pmos posedge primitive priority program property protected pull0 pull1 pulldown pullup " + 44 "pulsestyle_ondetect pulsestyle_onevent pure rand randc randcase randsequence rcmos real realtime ref reg " + 45 "reject_on release repeat restrict return rnmos rpmos rtran rtranif0 rtranif1 s_always s_eventually s_nexttime " + 46 "s_until s_until_with scalared sequence shortint shortreal showcancelled signed small soft solve specify " + 47 "specparam static string strong strong0 strong1 struct super supply0 supply1 sync_accept_on sync_reject_on " + 48 "table tagged task this throughout time timeprecision timeunit tran tranif0 tranif1 tri tri0 tri1 triand trior " + 49 "trireg type typedef union unique unique0 unsigned until until_with untyped use uwire var vectored virtual void " + 50 "wait wait_order wand weak weak0 weak1 while wildcard wire with within wor xnor xor"); 51 52 /** Operators from IEEE 1800-2012 53 unary_operator ::= 54 + | - | ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~ 55 binary_operator ::= 56 + | - | * | / | % | == | != | === | !== | ==? | !=? | && | || | ** 57 | < | <= | > | >= | & | | | ^ | ^~ | ~^ | >> | << | >>> | <<< 58 | -> | <-> 59 inc_or_dec_operator ::= ++ | -- 60 unary_module_path_operator ::= 61 ! | ~ | & | ~& | | | ~| | ^ | ~^ | ^~ 62 binary_module_path_operator ::= 63 == | != | && | || | & | | | ^ | ^~ | ~^ 64 */ 65 var isOperatorChar = /[\+\-\*\/!~&|^%=?:]/; 66 var isBracketChar = /[\[\]{}()]/; 67 68 var unsignedNumber = /\d[0-9_]*/; 69 var decimalLiteral = /\d*\s*'s?d\s*\d[0-9_]*/i; 70 var binaryLiteral = /\d*\s*'s?b\s*[xz01][xz01_]*/i; 71 var octLiteral = /\d*\s*'s?o\s*[xz0-7][xz0-7_]*/i; 72 var hexLiteral = /\d*\s*'s?h\s*[0-9a-fxz?][0-9a-fxz?_]*/i; 73 var realLiteral = /(\d[\d_]*(\.\d[\d_]*)?E-?[\d_]+)|(\d[\d_]*\.\d[\d_]*)/i; 74 75 var closingBracketOrWord = /^((\w+)|[)}\]])/; 76 var closingBracket = /[)}\]]/; 77 78 var curPunc; 79 var curKeyword; 80 81 // Block openings which are closed by a matching keyword in the form of ("end" + keyword) 82 // E.g. "task" => "endtask" 83 var blockKeywords = words( 84 "case checker class clocking config function generate interface module package " + 85 "primitive program property specify sequence table task" 86 ); 87 88 // Opening/closing pairs 89 var openClose = {}; 90 for (var keyword in blockKeywords) { 91 openClose[keyword] = "end" + keyword; 92 } 93 openClose["begin"] = "end"; 94 openClose["casex"] = "endcase"; 95 openClose["casez"] = "endcase"; 96 openClose["do" ] = "while"; 97 openClose["fork" ] = "join;join_any;join_none"; 98 openClose["covergroup"] = "endgroup"; 99 100 for (var i in noIndentKeywords) { 101 var keyword = noIndentKeywords[i]; 102 if (openClose[keyword]) { 103 openClose[keyword] = undefined; 104 } 105 } 106 107 // Keywords which open statements that are ended with a semi-colon 108 var statementKeywords = words("always always_comb always_ff always_latch assert assign assume else export for foreach forever if import initial repeat while"); 109 110 function tokenBase(stream, state) { 111 var ch = stream.peek(), style; 112 if (hooks[ch] && (style = hooks[ch](stream, state)) != false) return style; 113 if (hooks.tokenBase && (style = hooks.tokenBase(stream, state)) != false) 114 return style; 115 116 if (/[,;:\.]/.test(ch)) { 117 curPunc = stream.next(); 118 return null; 119 } 120 if (isBracketChar.test(ch)) { 121 curPunc = stream.next(); 122 return "bracket"; 123 } 124 // Macros (tick-defines) 125 if (ch == '`') { 126 stream.next(); 127 if (stream.eatWhile(/[\w\$_]/)) { 128 return "def"; 129 } else { 130 return null; 131 } 132 } 133 // System calls 134 if (ch == '$') { 135 stream.next(); 136 if (stream.eatWhile(/[\w\$_]/)) { 137 return "meta"; 138 } else { 139 return null; 140 } 141 } 142 // Time literals 143 if (ch == '#') { 144 stream.next(); 145 stream.eatWhile(/[\d_.]/); 146 return "def"; 147 } 148 // Strings 149 if (ch == '"') { 150 stream.next(); 151 state.tokenize = tokenString(ch); 152 return state.tokenize(stream, state); 153 } 154 // Comments 155 if (ch == "/") { 156 stream.next(); 157 if (stream.eat("*")) { 158 state.tokenize = tokenComment; 159 return tokenComment(stream, state); 160 } 161 if (stream.eat("/")) { 162 stream.skipToEnd(); 163 return "comment"; 164 } 165 stream.backUp(1); 166 } 167 168 // Numeric literals 169 if (stream.match(realLiteral) || 170 stream.match(decimalLiteral) || 171 stream.match(binaryLiteral) || 172 stream.match(octLiteral) || 173 stream.match(hexLiteral) || 174 stream.match(unsignedNumber) || 175 stream.match(realLiteral)) { 176 return "number"; 177 } 178 179 // Operators 180 if (stream.eatWhile(isOperatorChar)) { 181 return "meta"; 182 } 183 184 // Keywords / plain variables 185 if (stream.eatWhile(/[\w\$_]/)) { 186 var cur = stream.current(); 187 if (keywords[cur]) { 188 if (openClose[cur]) { 189 curPunc = "newblock"; 190 } 191 if (statementKeywords[cur]) { 192 curPunc = "newstatement"; 193 } 194 curKeyword = cur; 195 return "keyword"; 196 } 197 return "variable"; 198 } 199 200 stream.next(); 201 return null; 202 } 203 204 function tokenString(quote) { 205 return function(stream, state) { 206 var escaped = false, next, end = false; 207 while ((next = stream.next()) != null) { 208 if (next == quote && !escaped) {end = true; break;} 209 escaped = !escaped && next == "\\"; 210 } 211 if (end || !(escaped || multiLineStrings)) 212 state.tokenize = tokenBase; 213 return "string"; 214 }; 215 } 216 217 function tokenComment(stream, state) { 218 var maybeEnd = false, ch; 219 while (ch = stream.next()) { 220 if (ch == "/" && maybeEnd) { 221 state.tokenize = tokenBase; 222 break; 223 } 224 maybeEnd = (ch == "*"); 225 } 226 return "comment"; 227 } 228 229 function Context(indented, column, type, align, prev) { 230 this.indented = indented; 231 this.column = column; 232 this.type = type; 233 this.align = align; 234 this.prev = prev; 235 } 236 function pushContext(state, col, type) { 237 var indent = state.indented; 238 var c = new Context(indent, col, type, null, state.context); 239 return state.context = c; 240 } 241 function popContext(state) { 242 var t = state.context.type; 243 if (t == ")" || t == "]" || t == "}") { 244 state.indented = state.context.indented; 245 } 246 return state.context = state.context.prev; 247 } 248 249 function isClosing(text, contextClosing) { 250 if (text == contextClosing) { 251 return true; 252 } else { 253 // contextClosing may be multiple keywords separated by ; 254 var closingKeywords = contextClosing.split(";"); 255 for (var i in closingKeywords) { 256 if (text == closingKeywords[i]) { 257 return true; 258 } 259 } 260 return false; 261 } 262 } 263 264 function buildElectricInputRegEx() { 265 // Reindentation should occur on any bracket char: {}()[] 266 // or on a match of any of the block closing keywords, at 267 // the end of a line 268 var allClosings = []; 269 for (var i in openClose) { 270 if (openClose[i]) { 271 var closings = openClose[i].split(";"); 272 for (var j in closings) { 273 allClosings.push(closings[j]); 274 } 275 } 276 } 277 var re = new RegExp("[{}()\\[\\]]|(" + allClosings.join("|") + ")$"); 278 return re; 279 } 280 281 // Interface 282 return { 283 284 // Regex to force current line to reindent 285 electricInput: buildElectricInputRegEx(), 286 287 startState: function(basecolumn) { 288 var state = { 289 tokenize: null, 290 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), 291 indented: 0, 292 startOfLine: true 293 }; 294 if (hooks.startState) hooks.startState(state); 295 return state; 296 }, 297 298 token: function(stream, state) { 299 var ctx = state.context; 300 if (stream.sol()) { 301 if (ctx.align == null) ctx.align = false; 302 state.indented = stream.indentation(); 303 state.startOfLine = true; 304 } 305 if (hooks.token) { 306 // Call hook, with an optional return value of a style to override verilog styling. 307 var style = hooks.token(stream, state); 308 if (style !== undefined) { 309 return style; 310 } 311 } 312 if (stream.eatSpace()) return null; 313 curPunc = null; 314 curKeyword = null; 315 var style = (state.tokenize || tokenBase)(stream, state); 316 if (style == "comment" || style == "meta" || style == "variable") return style; 317 if (ctx.align == null) ctx.align = true; 318 319 if (curPunc == ctx.type) { 320 popContext(state); 321 } else if ((curPunc == ";" && ctx.type == "statement") || 322 (ctx.type && isClosing(curKeyword, ctx.type))) { 323 ctx = popContext(state); 324 while (ctx && ctx.type == "statement") ctx = popContext(state); 325 } else if (curPunc == "{") { 326 pushContext(state, stream.column(), "}"); 327 } else if (curPunc == "[") { 328 pushContext(state, stream.column(), "]"); 329 } else if (curPunc == "(") { 330 pushContext(state, stream.column(), ")"); 331 } else if (ctx && ctx.type == "endcase" && curPunc == ":") { 332 pushContext(state, stream.column(), "statement"); 333 } else if (curPunc == "newstatement") { 334 pushContext(state, stream.column(), "statement"); 335 } else if (curPunc == "newblock") { 336 if (curKeyword == "function" && ctx && (ctx.type == "statement" || ctx.type == "endgroup")) { 337 // The 'function' keyword can appear in some other contexts where it actually does not 338 // indicate a function (import/export DPI and covergroup definitions). 339 // Do nothing in this case 340 } else if (curKeyword == "task" && ctx && ctx.type == "statement") { 341 // Same thing for task 342 } else { 343 var close = openClose[curKeyword]; 344 pushContext(state, stream.column(), close); 345 } 346 } 347 348 state.startOfLine = false; 349 return style; 350 }, 351 352 indent: function(state, textAfter) { 353 if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass; 354 if (hooks.indent) { 355 var fromHook = hooks.indent(state); 356 if (fromHook >= 0) return fromHook; 357 } 358 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); 359 if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev; 360 var closing = false; 361 var possibleClosing = textAfter.match(closingBracketOrWord); 362 if (possibleClosing) 363 closing = isClosing(possibleClosing[0], ctx.type); 364 if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit); 365 else if (closingBracket.test(ctx.type) && ctx.align && !dontAlignCalls) return ctx.column + (closing ? 0 : 1); 366 else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit; 367 else return ctx.indented + (closing ? 0 : indentUnit); 368 }, 369 370 blockCommentStart: "/*", 371 blockCommentEnd: "*/", 372 lineComment: "//" 373 }; 374 }); 375 376 CodeMirror.defineMIME("text/x-verilog", { 377 name: "verilog" 378 }); 379 380 CodeMirror.defineMIME("text/x-systemverilog", { 381 name: "verilog" 382 }); 383 384 385 386 // TL-Verilog mode. 387 // See tl-x.org for language spec. 388 // See the mode in action at makerchip.com. 389 // Contact: steve.hoover@redwoodeda.com 390 391 // TLV Identifier prefixes. 392 // Note that sign is not treated separately, so "+/-" versions of numeric identifiers 393 // are included. 394 var tlvIdentifierStyle = { 395 "|": "link", 396 ">": "property", // Should condition this off for > TLV 1c. 397 "$": "variable", 398 "$$": "variable", 399 "?$": "qualifier", 400 "?*": "qualifier", 401 "-": "hr", 402 "/": "property", 403 "/-": "property", 404 "@": "variable-3", 405 "@-": "variable-3", 406 "@++": "variable-3", 407 "@+=": "variable-3", 408 "@+=-": "variable-3", 409 "@--": "variable-3", 410 "@-=": "variable-3", 411 "%+": "tag", 412 "%-": "tag", 413 "%": "tag", 414 ">>": "tag", 415 "<<": "tag", 416 "<>": "tag", 417 "#": "tag", // Need to choose a style for this. 418 "^": "attribute", 419 "^^": "attribute", 420 "^!": "attribute", 421 "*": "variable-2", 422 "**": "variable-2", 423 "\\": "keyword", 424 "\"": "comment" 425 }; 426 427 // Lines starting with these characters define scope (result in indentation). 428 var tlvScopePrefixChars = { 429 "/": "beh-hier", 430 ">": "beh-hier", 431 "-": "phys-hier", 432 "|": "pipe", 433 "?": "when", 434 "@": "stage", 435 "\\": "keyword" 436 }; 437 var tlvIndentUnit = 3; 438 var tlvTrackStatements = false; 439 var tlvIdentMatch = /^([~!@#\$%\^&\*-\+=\?\/\\\|'"<>]+)([\d\w_]*)/; // Matches an identifiere. 440 // Note that ':' is excluded, because of it's use in [:]. 441 var tlvFirstLevelIndentMatch = /^[! ] /; 442 var tlvLineIndentationMatch = /^[! ] */; 443 var tlvCommentMatch = /^\/[\/\*]/; 444 445 446 // Returns a style specific to the scope at the given indentation column. 447 // Type is one of: "indent", "scope-ident", "before-scope-ident". 448 function tlvScopeStyle(state, indentation, type) { 449 // Begin scope. 450 var depth = indentation / tlvIndentUnit; // TODO: Pass this in instead. 451 return "tlv-" + state.tlvIndentationStyle[depth] + "-" + type; 452 } 453 454 // Return true if the next thing in the stream is an identifier with a mnemonic. 455 function tlvIdentNext(stream) { 456 var match; 457 return (match = stream.match(tlvIdentMatch, false)) && match[2].length > 0; 458 } 459 460 CodeMirror.defineMIME("text/x-tlv", { 461 name: "verilog", 462 463 hooks: { 464 465 electricInput: false, 466 467 468 // Return undefined for verilog tokenizing, or style for TLV token (null not used). 469 // Standard CM styles are used for most formatting, but some TL-Verilog-specific highlighting 470 // can be enabled with the definition of cm-tlv-* styles, including highlighting for: 471 // - M4 tokens 472 // - TLV scope indentation 473 // - Statement delimitation (enabled by tlvTrackStatements) 474 token: function(stream, state) { 475 var style = undefined; 476 var match; // Return value of pattern matches. 477 478 // Set highlighting mode based on code region (TLV or SV). 479 if (stream.sol() && ! state.tlvInBlockComment) { 480 // Process region. 481 if (stream.peek() == '\\') { 482 style = "def"; 483 stream.skipToEnd(); 484 if (stream.string.match(/\\SV/)) { 485 state.tlvCodeActive = false; 486 } else if (stream.string.match(/\\TLV/)){ 487 state.tlvCodeActive = true; 488 } 489 } 490 // Correct indentation in the face of a line prefix char. 491 if (state.tlvCodeActive && stream.pos == 0 && 492 (state.indented == 0) && (match = stream.match(tlvLineIndentationMatch, false))) { 493 state.indented = match[0].length; 494 } 495 496 // Compute indentation state: 497 // o Auto indentation on next line 498 // o Indentation scope styles 499 var indented = state.indented; 500 var depth = indented / tlvIndentUnit; 501 if (depth <= state.tlvIndentationStyle.length) { 502 // not deeper than current scope 503 504 var blankline = stream.string.length == indented; 505 var chPos = depth * tlvIndentUnit; 506 if (chPos < stream.string.length) { 507 var bodyString = stream.string.slice(chPos); 508 var ch = bodyString[0]; 509 if (tlvScopePrefixChars[ch] && ((match = bodyString.match(tlvIdentMatch)) && 510 tlvIdentifierStyle[match[1]])) { 511 // This line begins scope. 512 // Next line gets indented one level. 513 indented += tlvIndentUnit; 514 // Style the next level of indentation (except non-region keyword identifiers, 515 // which are statements themselves) 516 if (!(ch == "\\" && chPos > 0)) { 517 state.tlvIndentationStyle[depth] = tlvScopePrefixChars[ch]; 518 if (tlvTrackStatements) {state.statementComment = false;} 519 depth++; 520 } 521 } 522 } 523 // Clear out deeper indentation levels unless line is blank. 524 if (!blankline) { 525 while (state.tlvIndentationStyle.length > depth) { 526 state.tlvIndentationStyle.pop(); 527 } 528 } 529 } 530 // Set next level of indentation. 531 state.tlvNextIndent = indented; 532 } 533 534 if (state.tlvCodeActive) { 535 // Highlight as TLV. 536 537 var beginStatement = false; 538 if (tlvTrackStatements) { 539 // This starts a statement if the position is at the scope level 540 // and we're not within a statement leading comment. 541 beginStatement = 542 (stream.peek() != " ") && // not a space 543 (style === undefined) && // not a region identifier 544 !state.tlvInBlockComment && // not in block comment 545 //!stream.match(tlvCommentMatch, false) && // not comment start 546 (stream.column() == state.tlvIndentationStyle.length * tlvIndentUnit); // at scope level 547 if (beginStatement) { 548 if (state.statementComment) { 549 // statement already started by comment 550 beginStatement = false; 551 } 552 state.statementComment = 553 stream.match(tlvCommentMatch, false); // comment start 554 } 555 } 556 557 var match; 558 if (style !== undefined) { 559 // Region line. 560 style += " " + tlvScopeStyle(state, 0, "scope-ident") 561 } else if (((stream.pos / tlvIndentUnit) < state.tlvIndentationStyle.length) && 562 (match = stream.match(stream.sol() ? tlvFirstLevelIndentMatch : /^ /))) { 563 // Indentation 564 style = // make this style distinct from the previous one to prevent 565 // codemirror from combining spans 566 "tlv-indent-" + (((stream.pos % 2) == 0) ? "even" : "odd") + 567 // and style it 568 " " + tlvScopeStyle(state, stream.pos - tlvIndentUnit, "indent"); 569 // Style the line prefix character. 570 if (match[0].charAt(0) == "!") { 571 style += " tlv-alert-line-prefix"; 572 } 573 // Place a class before a scope identifier. 574 if (tlvIdentNext(stream)) { 575 style += " " + tlvScopeStyle(state, stream.pos, "before-scope-ident"); 576 } 577 } else if (state.tlvInBlockComment) { 578 // In a block comment. 579 if (stream.match(/^.*?\*\//)) { 580 // Exit block comment. 581 state.tlvInBlockComment = false; 582 if (tlvTrackStatements && !stream.eol()) { 583 // Anything after comment is assumed to be real statement content. 584 state.statementComment = false; 585 } 586 } else { 587 stream.skipToEnd(); 588 } 589 style = "comment"; 590 } else if ((match = stream.match(tlvCommentMatch)) && !state.tlvInBlockComment) { 591 // Start comment. 592 if (match[0] == "//") { 593 // Line comment. 594 stream.skipToEnd(); 595 } else { 596 // Block comment. 597 state.tlvInBlockComment = true; 598 } 599 style = "comment"; 600 } else if (match = stream.match(tlvIdentMatch)) { 601 // looks like an identifier (or identifier prefix) 602 var prefix = match[1]; 603 var mnemonic = match[2]; 604 if (// is identifier prefix 605 tlvIdentifierStyle.hasOwnProperty(prefix) && 606 // has mnemonic or we're at the end of the line (maybe it hasn't been typed yet) 607 (mnemonic.length > 0 || stream.eol())) { 608 style = tlvIdentifierStyle[prefix]; 609 if (stream.column() == state.indented) { 610 // Begin scope. 611 style += " " + tlvScopeStyle(state, stream.column(), "scope-ident") 612 } 613 } else { 614 // Just swallow one character and try again. 615 // This enables subsequent identifier match with preceding symbol character, which 616 // is legal within a statement. (Eg, !$reset). It also enables detection of 617 // comment start with preceding symbols. 618 stream.backUp(stream.current().length - 1); 619 style = "tlv-default"; 620 } 621 } else if (stream.match(/^\t+/)) { 622 // Highlight tabs, which are illegal. 623 style = "tlv-tab"; 624 } else if (stream.match(/^[\[\]{}\(\);\:]+/)) { 625 // [:], (), {}, ;. 626 style = "meta"; 627 } else if (match = stream.match(/^[mM]4([\+_])?[\w\d_]*/)) { 628 // m4 pre proc 629 style = (match[1] == "+") ? "tlv-m4-plus" : "tlv-m4"; 630 } else if (stream.match(/^ +/)){ 631 // Skip over spaces. 632 if (stream.eol()) { 633 // Trailing spaces. 634 style = "error"; 635 } else { 636 // Non-trailing spaces. 637 style = "tlv-default"; 638 } 639 } else if (stream.match(/^[\w\d_]+/)) { 640 // alpha-numeric token. 641 style = "number"; 642 } else { 643 // Eat the next char w/ no formatting. 644 stream.next(); 645 style = "tlv-default"; 646 } 647 if (beginStatement) { 648 style += " tlv-statement"; 649 } 650 } else { 651 if (stream.match(/^[mM]4([\w\d_]*)/)) { 652 // m4 pre proc 653 style = "tlv-m4"; 654 } 655 } 656 return style; 657 }, 658 659 indent: function(state) { 660 return (state.tlvCodeActive == true) ? state.tlvNextIndent : -1; 661 }, 662 663 startState: function(state) { 664 state.tlvIndentationStyle = []; // Styles to use for each level of indentation. 665 state.tlvCodeActive = true; // True when we're in a TLV region (and at beginning of file). 666 state.tlvNextIndent = -1; // The number of spaces to autoindent the next line if tlvCodeActive. 667 state.tlvInBlockComment = false; // True inside /**/ comment. 668 if (tlvTrackStatements) { 669 state.statementComment = false; // True inside a statement's header comment. 670 } 671 } 672 673 } 674 }); 675 });
Downloadmodules/editor/codemirror/mode/verilog/verilog.js
History Sun, 17 Dec 2017 01:14:09 +0100 Jan Dankert Integration eines weiteren Code-Editors: Codemirror. Demnächst müssen wir hier mal aufräumen und andere Editoren rauswerfen.