all repos — NoPaste @ 3e3c433f026c49e04d0efa0f0f39fc688ed32bb1

Resurrected - The PussTheCat.org fork of NoPaste

scripts/CodeMirror/mode/elm/elm.js (view raw)

  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    {
 18      setState(f);
 19      return f(source, setState);
 20    }
 21
 22    var lowerRE = /[a-z]/;
 23    var upperRE = /[A-Z]/;
 24    var innerRE = /[a-zA-Z0-9_]/;
 25
 26    var digitRE = /[0-9]/;
 27    var hexRE = /[0-9A-Fa-f]/;
 28    var symbolRE = /[-&*+.\\/<>=?^|:]/;
 29    var specialRE = /[(),[\]{}]/;
 30    var spacesRE = /[ \v\f]/; // newlines are handled in tokenizer
 31
 32    function normal()
 33    {
 34      return function(source, setState)
 35      {
 36        if (source.eatWhile(spacesRE))
 37        {
 38          return null;
 39        }
 40
 41        var char = source.next();
 42
 43        if (specialRE.test(char))
 44        {
 45          return (char === '{' && source.eat('-'))
 46            ? switchState(source, setState, chompMultiComment(1))
 47            : (char === '[' && source.match('glsl|'))
 48                ? switchState(source, setState, chompGlsl)
 49                : 'builtin';
 50        }
 51
 52        if (char === '\'')
 53        {
 54          return switchState(source, setState, chompChar);
 55        }
 56
 57        if (char === '"')
 58        {
 59          return source.eat('"')
 60            ? source.eat('"')
 61                ? switchState(source, setState, chompMultiString)
 62                : 'string'
 63            : switchState(source, setState, chompSingleString);
 64        }
 65
 66        if (upperRE.test(char))
 67        {
 68          source.eatWhile(innerRE);
 69          return 'variable-2';
 70        }
 71
 72        if (lowerRE.test(char))
 73        {
 74          var isDef = source.pos === 1;
 75          source.eatWhile(innerRE);
 76          return isDef ? "def" : "variable";
 77        }
 78
 79        if (digitRE.test(char))
 80        {
 81          if (char === '0')
 82          {
 83            if (source.eat(/[xX]/))
 84            {
 85              source.eatWhile(hexRE); // should require at least 1
 86              return "number";
 87            }
 88          }
 89          else
 90          {
 91            source.eatWhile(digitRE);
 92          }
 93          if (source.eat('.'))
 94          {
 95            source.eatWhile(digitRE); // should require at least 1
 96          }
 97          if (source.eat(/[eE]/))
 98          {
 99            source.eat(/[-+]/);
100            source.eatWhile(digitRE); // should require at least 1
101          }
102          return "number";
103        }
104
105        if (symbolRE.test(char))
106        {
107          if (char === '-' && source.eat('-'))
108          {
109            source.skipToEnd();
110            return "comment";
111          }
112          source.eatWhile(symbolRE);
113          return "keyword";
114        }
115
116        if (char === '_')
117        {
118          return "keyword";
119        }
120
121        return "error";
122      }
123    }
124
125    function chompMultiComment(nest)
126    {
127      if (nest == 0)
128      {
129        return normal();
130      }
131      return function(source, setState)
132      {
133        while (!source.eol())
134        {
135          var char = source.next();
136          if (char == '{' && source.eat('-'))
137          {
138            ++nest;
139          }
140          else if (char == '-' && source.eat('}'))
141          {
142            --nest;
143            if (nest === 0)
144            {
145              setState(normal());
146              return 'comment';
147            }
148          }
149        }
150        setState(chompMultiComment(nest));
151        return 'comment';
152      }
153    }
154
155    function chompMultiString(source, setState)
156    {
157      while (!source.eol())
158      {
159        var char = source.next();
160        if (char === '"' && source.eat('"') && source.eat('"'))
161        {
162          setState(normal());
163          return 'string';
164        }
165      }
166      return 'string';
167    }
168
169    function chompSingleString(source, setState)
170    {
171      while (source.skipTo('\\"')) { source.next(); source.next(); }
172      if (source.skipTo('"'))
173      {
174        source.next();
175        setState(normal());
176        return 'string';
177      }
178      source.skipToEnd();
179      setState(normal());
180      return 'error';
181    }
182
183    function chompChar(source, setState)
184    {
185      while (source.skipTo("\\'")) { source.next(); source.next(); }
186      if (source.skipTo("'"))
187      {
188        source.next();
189        setState(normal());
190        return 'string';
191      }
192      source.skipToEnd();
193      setState(normal());
194      return 'error';
195    }
196
197    function chompGlsl(source, setState)
198    {
199      while (!source.eol())
200      {
201        var char = source.next();
202        if (char === '|' && source.eat(']'))
203        {
204          setState(normal());
205          return 'string';
206        }
207      }
208      return 'string';
209    }
210
211    var wellKnownWords = {
212      case: 1,
213      of: 1,
214      as: 1,
215      if: 1,
216      then: 1,
217      else: 1,
218      let: 1,
219      in: 1,
220      type: 1,
221      alias: 1,
222      module: 1,
223      where: 1,
224      import: 1,
225      exposing: 1,
226      port: 1
227    };
228
229    return {
230      startState: function ()  { return { f: normal() }; },
231      copyState:  function (s) { return { f: s.f }; },
232
233      token: function(stream, state) {
234        var type = state.f(stream, function(s) { state.f = s; });
235        var word = stream.current();
236        return (wellKnownWords.hasOwnProperty(word)) ? 'keyword' : type;
237      }
238    };
239
240  });
241
242  CodeMirror.defineMIME("text/x-elm", "elm");
243});