github.com/elliott5/community@v0.14.1-0.20160709191136-823126fb026a/app/public/codemirror/mode/elm/elm.js (about)

     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("elm", function() {
    15  
    16      function switchState(source, setState, f) {
    17        setState(f);
    18        return f(source, setState);
    19      }
    20  
    21      // These should all be Unicode extended, as per the Haskell 2010 report
    22      var smallRE = /[a-z_]/;
    23      var largeRE = /[A-Z]/;
    24      var digitRE = /[0-9]/;
    25      var hexitRE = /[0-9A-Fa-f]/;
    26      var octitRE = /[0-7]/;
    27      var idRE = /[a-z_A-Z0-9\']/;
    28      var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/;
    29      var specialRE = /[(),;[\]`{}]/;
    30      var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
    31  
    32      function normal() {
    33        return function (source, setState) {
    34          if (source.eatWhile(whiteCharRE)) {
    35            return null;
    36          }
    37  
    38          var ch = source.next();
    39          if (specialRE.test(ch)) {
    40            if (ch == '{' && source.eat('-')) {
    41              var t = "comment";
    42              if (source.eat('#')) t = "meta";
    43              return switchState(source, setState, ncomment(t, 1));
    44            }
    45            return null;
    46          }
    47  
    48          if (ch == '\'') {
    49            if (source.eat('\\'))
    50              source.next();  // should handle other escapes here
    51            else
    52              source.next();
    53  
    54            if (source.eat('\''))
    55              return "string";
    56            return "error";
    57          }
    58  
    59          if (ch == '"') {
    60            return switchState(source, setState, stringLiteral);
    61          }
    62  
    63          if (largeRE.test(ch)) {
    64            source.eatWhile(idRE);
    65            if (source.eat('.'))
    66              return "qualifier";
    67            return "variable-2";
    68          }
    69  
    70          if (smallRE.test(ch)) {
    71            var isDef = source.pos === 1;
    72            source.eatWhile(idRE);
    73            return isDef ? "variable-3" : "variable";
    74          }
    75  
    76          if (digitRE.test(ch)) {
    77            if (ch == '0') {
    78              if (source.eat(/[xX]/)) {
    79                source.eatWhile(hexitRE); // should require at least 1
    80                return "integer";
    81              }
    82              if (source.eat(/[oO]/)) {
    83                source.eatWhile(octitRE); // should require at least 1
    84                return "number";
    85              }
    86            }
    87            source.eatWhile(digitRE);
    88            var t = "number";
    89            if (source.eat('.')) {
    90              t = "number";
    91              source.eatWhile(digitRE); // should require at least 1
    92            }
    93            if (source.eat(/[eE]/)) {
    94              t = "number";
    95              source.eat(/[-+]/);
    96              source.eatWhile(digitRE); // should require at least 1
    97            }
    98            return t;
    99          }
   100  
   101          if (symbolRE.test(ch)) {
   102            if (ch == '-' && source.eat(/-/)) {
   103              source.eatWhile(/-/);
   104              if (!source.eat(symbolRE)) {
   105                source.skipToEnd();
   106                return "comment";
   107              }
   108            }
   109            source.eatWhile(symbolRE);
   110            return "builtin";
   111          }
   112  
   113          return "error";
   114        }
   115      }
   116  
   117      function ncomment(type, nest) {
   118        if (nest == 0) {
   119          return normal();
   120        }
   121        return function(source, setState) {
   122          var currNest = nest;
   123          while (!source.eol()) {
   124            var ch = source.next();
   125            if (ch == '{' && source.eat('-')) {
   126              ++currNest;
   127            } else if (ch == '-' && source.eat('}')) {
   128              --currNest;
   129              if (currNest == 0) {
   130                setState(normal());
   131                return type;
   132              }
   133            }
   134          }
   135          setState(ncomment(type, currNest));
   136          return type;
   137        }
   138      }
   139  
   140      function stringLiteral(source, setState) {
   141        while (!source.eol()) {
   142          var ch = source.next();
   143          if (ch == '"') {
   144            setState(normal());
   145            return "string";
   146          }
   147          if (ch == '\\') {
   148            if (source.eol() || source.eat(whiteCharRE)) {
   149              setState(stringGap);
   150              return "string";
   151            }
   152            if (!source.eat('&')) source.next(); // should handle other escapes here
   153          }
   154        }
   155        setState(normal());
   156        return "error";
   157      }
   158  
   159      function stringGap(source, setState) {
   160        if (source.eat('\\')) {
   161          return switchState(source, setState, stringLiteral);
   162        }
   163        source.next();
   164        setState(normal());
   165        return "error";
   166      }
   167  
   168  
   169      var wellKnownWords = (function() {
   170        var wkw = {};
   171  
   172        var keywords = [
   173          "case", "of", "as",
   174          "if", "then", "else",
   175          "let", "in",
   176          "infix", "infixl", "infixr",
   177          "type", "alias",
   178          "input", "output", "foreign", "loopback",
   179          "module", "where", "import", "exposing",
   180          "_", "..", "|", ":", "=", "\\", "\"", "->", "<-"
   181        ];
   182  
   183        for (var i = keywords.length; i--;)
   184          wkw[keywords[i]] = "keyword";
   185  
   186        return wkw;
   187      })();
   188  
   189  
   190  
   191      return {
   192        startState: function ()  { return { f: normal() }; },
   193        copyState:  function (s) { return { f: s.f }; },
   194  
   195        token: function(stream, state) {
   196          var t = state.f(stream, function(s) { state.f = s; });
   197          var w = stream.current();
   198          return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t;
   199        }
   200      };
   201  
   202    });
   203  
   204    CodeMirror.defineMIME("text/x-elm", "elm");
   205  });