openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

groovy.js (7904B)


      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("groovy", function(config) {
     15   function words(str) {
     16     var obj = {}, words = str.split(" ");
     17     for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
     18     return obj;
     19   }
     20   var keywords = words(
     21     "abstract as assert boolean break byte case catch char class const continue def default " +
     22     "do double else enum extends final finally float for goto if implements import in " +
     23     "instanceof int interface long native new package private protected public return " +
     24     "short static strictfp super switch synchronized threadsafe throw throws trait transient " +
     25     "try void volatile while");
     26   var blockKeywords = words("catch class def do else enum finally for if interface switch trait try while");
     27   var standaloneKeywords = words("return break continue");
     28   var atoms = words("null true false this");
     29 
     30   var curPunc;
     31   function tokenBase(stream, state) {
     32     var ch = stream.next();
     33     if (ch == '"' || ch == "'") {
     34       return startString(ch, stream, state);
     35     }
     36     if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
     37       curPunc = ch;
     38       return null;
     39     }
     40     if (/\d/.test(ch)) {
     41       stream.eatWhile(/[\w\.]/);
     42       if (stream.eat(/eE/)) { stream.eat(/\+\-/); stream.eatWhile(/\d/); }
     43       return "number";
     44     }
     45     if (ch == "/") {
     46       if (stream.eat("*")) {
     47         state.tokenize.push(tokenComment);
     48         return tokenComment(stream, state);
     49       }
     50       if (stream.eat("/")) {
     51         stream.skipToEnd();
     52         return "comment";
     53       }
     54       if (expectExpression(state.lastToken, false)) {
     55         return startString(ch, stream, state);
     56       }
     57     }
     58     if (ch == "-" && stream.eat(">")) {
     59       curPunc = "->";
     60       return null;
     61     }
     62     if (/[+\-*&%=<>!?|\/~]/.test(ch)) {
     63       stream.eatWhile(/[+\-*&%=<>|~]/);
     64       return "operator";
     65     }
     66     stream.eatWhile(/[\w\$_]/);
     67     if (ch == "@") { stream.eatWhile(/[\w\$_\.]/); return "meta"; }
     68     if (state.lastToken == ".") return "property";
     69     if (stream.eat(":")) { curPunc = "proplabel"; return "property"; }
     70     var cur = stream.current();
     71     if (atoms.propertyIsEnumerable(cur)) { return "atom"; }
     72     if (keywords.propertyIsEnumerable(cur)) {
     73       if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
     74       else if (standaloneKeywords.propertyIsEnumerable(cur)) curPunc = "standalone";
     75       return "keyword";
     76     }
     77     return "variable";
     78   }
     79   tokenBase.isBase = true;
     80 
     81   function startString(quote, stream, state) {
     82     var tripleQuoted = false;
     83     if (quote != "/" && stream.eat(quote)) {
     84       if (stream.eat(quote)) tripleQuoted = true;
     85       else return "string";
     86     }
     87     function t(stream, state) {
     88       var escaped = false, next, end = !tripleQuoted;
     89       while ((next = stream.next()) != null) {
     90         if (next == quote && !escaped) {
     91           if (!tripleQuoted) { break; }
     92           if (stream.match(quote + quote)) { end = true; break; }
     93         }
     94         if (quote == '"' && next == "$" && !escaped && stream.eat("{")) {
     95           state.tokenize.push(tokenBaseUntilBrace());
     96           return "string";
     97         }
     98         escaped = !escaped && next == "\\";
     99       }
    100       if (end) state.tokenize.pop();
    101       return "string";
    102     }
    103     state.tokenize.push(t);
    104     return t(stream, state);
    105   }
    106 
    107   function tokenBaseUntilBrace() {
    108     var depth = 1;
    109     function t(stream, state) {
    110       if (stream.peek() == "}") {
    111         depth--;
    112         if (depth == 0) {
    113           state.tokenize.pop();
    114           return state.tokenize[state.tokenize.length-1](stream, state);
    115         }
    116       } else if (stream.peek() == "{") {
    117         depth++;
    118       }
    119       return tokenBase(stream, state);
    120     }
    121     t.isBase = true;
    122     return t;
    123   }
    124 
    125   function tokenComment(stream, state) {
    126     var maybeEnd = false, ch;
    127     while (ch = stream.next()) {
    128       if (ch == "/" && maybeEnd) {
    129         state.tokenize.pop();
    130         break;
    131       }
    132       maybeEnd = (ch == "*");
    133     }
    134     return "comment";
    135   }
    136 
    137   function expectExpression(last, newline) {
    138     return !last || last == "operator" || last == "->" || /[\.\[\{\(,;:]/.test(last) ||
    139       last == "newstatement" || last == "keyword" || last == "proplabel" ||
    140       (last == "standalone" && !newline);
    141   }
    142 
    143   function Context(indented, column, type, align, prev) {
    144     this.indented = indented;
    145     this.column = column;
    146     this.type = type;
    147     this.align = align;
    148     this.prev = prev;
    149   }
    150   function pushContext(state, col, type) {
    151     return state.context = new Context(state.indented, col, type, null, state.context);
    152   }
    153   function popContext(state) {
    154     var t = state.context.type;
    155     if (t == ")" || t == "]" || t == "}")
    156       state.indented = state.context.indented;
    157     return state.context = state.context.prev;
    158   }
    159 
    160   // Interface
    161 
    162   return {
    163     startState: function(basecolumn) {
    164       return {
    165         tokenize: [tokenBase],
    166         context: new Context((basecolumn || 0) - config.indentUnit, 0, "top", false),
    167         indented: 0,
    168         startOfLine: true,
    169         lastToken: null
    170       };
    171     },
    172 
    173     token: function(stream, state) {
    174       var ctx = state.context;
    175       if (stream.sol()) {
    176         if (ctx.align == null) ctx.align = false;
    177         state.indented = stream.indentation();
    178         state.startOfLine = true;
    179         // Automatic semicolon insertion
    180         if (ctx.type == "statement" && !expectExpression(state.lastToken, true)) {
    181           popContext(state); ctx = state.context;
    182         }
    183       }
    184       if (stream.eatSpace()) return null;
    185       curPunc = null;
    186       var style = state.tokenize[state.tokenize.length-1](stream, state);
    187       if (style == "comment") return style;
    188       if (ctx.align == null) ctx.align = true;
    189 
    190       if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
    191       // Handle indentation for {x -> \n ... }
    192       else if (curPunc == "->" && ctx.type == "statement" && ctx.prev.type == "}") {
    193         popContext(state);
    194         state.context.align = false;
    195       }
    196       else if (curPunc == "{") pushContext(state, stream.column(), "}");
    197       else if (curPunc == "[") pushContext(state, stream.column(), "]");
    198       else if (curPunc == "(") pushContext(state, stream.column(), ")");
    199       else if (curPunc == "}") {
    200         while (ctx.type == "statement") ctx = popContext(state);
    201         if (ctx.type == "}") ctx = popContext(state);
    202         while (ctx.type == "statement") ctx = popContext(state);
    203       }
    204       else if (curPunc == ctx.type) popContext(state);
    205       else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
    206         pushContext(state, stream.column(), "statement");
    207       state.startOfLine = false;
    208       state.lastToken = curPunc || style;
    209       return style;
    210     },
    211 
    212     indent: function(state, textAfter) {
    213       if (!state.tokenize[state.tokenize.length-1].isBase) return CodeMirror.Pass;
    214       var firstChar = textAfter && textAfter.charAt(0), ctx = state.context;
    215       if (ctx.type == "statement" && !expectExpression(state.lastToken, true)) ctx = ctx.prev;
    216       var closing = firstChar == ctx.type;
    217       if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : config.indentUnit);
    218       else if (ctx.align) return ctx.column + (closing ? 0 : 1);
    219       else return ctx.indented + (closing ? 0 : config.indentUnit);
    220     },
    221 
    222     electricChars: "{}",
    223     closeBrackets: {triples: "'\""},
    224     fold: "brace"
    225   };
    226 });
    227 
    228 CodeMirror.defineMIME("text/x-groovy", "groovy");
    229 
    230 });