You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							205 lines
						
					
					
						
							5.4 KiB
						
					
					
				
			
		
		
	
	
							205 lines
						
					
					
						
							5.4 KiB
						
					
					
				| // CodeMirror, copyright (c) by Marijn Haverbeke and others
 | |
| // Distributed under an MIT license: http://codemirror.net/LICENSE
 | |
| 
 | |
| (function(mod) {
 | |
|   if (typeof exports == "object" && typeof module == "object") // CommonJS
 | |
|     mod(require("../../lib/codemirror"));
 | |
|   else if (typeof define == "function" && define.amd) // AMD
 | |
|     define(["../../lib/codemirror"], mod);
 | |
|   else // Plain browser env
 | |
|     mod(CodeMirror);
 | |
| })(function(CodeMirror) {
 | |
|   "use strict";
 | |
| 
 | |
|   CodeMirror.defineMode("elm", function() {
 | |
| 
 | |
|     function switchState(source, setState, f) {
 | |
|       setState(f);
 | |
|       return f(source, setState);
 | |
|     }
 | |
| 
 | |
|     // These should all be Unicode extended, as per the Haskell 2010 report
 | |
|     var smallRE = /[a-z_]/;
 | |
|     var largeRE = /[A-Z]/;
 | |
|     var digitRE = /[0-9]/;
 | |
|     var hexitRE = /[0-9A-Fa-f]/;
 | |
|     var octitRE = /[0-7]/;
 | |
|     var idRE = /[a-z_A-Z0-9\']/;
 | |
|     var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/;
 | |
|     var specialRE = /[(),;[\]`{}]/;
 | |
|     var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
 | |
| 
 | |
|     function normal() {
 | |
|       return function (source, setState) {
 | |
|         if (source.eatWhile(whiteCharRE)) {
 | |
|           return null;
 | |
|         }
 | |
| 
 | |
|         var ch = source.next();
 | |
|         if (specialRE.test(ch)) {
 | |
|           if (ch == '{' && source.eat('-')) {
 | |
|             var t = "comment";
 | |
|             if (source.eat('#')) t = "meta";
 | |
|             return switchState(source, setState, ncomment(t, 1));
 | |
|           }
 | |
|           return null;
 | |
|         }
 | |
| 
 | |
|         if (ch == '\'') {
 | |
|           if (source.eat('\\'))
 | |
|             source.next();  // should handle other escapes here
 | |
|           else
 | |
|             source.next();
 | |
| 
 | |
|           if (source.eat('\''))
 | |
|             return "string";
 | |
|           return "error";
 | |
|         }
 | |
| 
 | |
|         if (ch == '"') {
 | |
|           return switchState(source, setState, stringLiteral);
 | |
|         }
 | |
| 
 | |
|         if (largeRE.test(ch)) {
 | |
|           source.eatWhile(idRE);
 | |
|           if (source.eat('.'))
 | |
|             return "qualifier";
 | |
|           return "variable-2";
 | |
|         }
 | |
| 
 | |
|         if (smallRE.test(ch)) {
 | |
|           var isDef = source.pos === 1;
 | |
|           source.eatWhile(idRE);
 | |
|           return isDef ? "variable-3" : "variable";
 | |
|         }
 | |
| 
 | |
|         if (digitRE.test(ch)) {
 | |
|           if (ch == '0') {
 | |
|             if (source.eat(/[xX]/)) {
 | |
|               source.eatWhile(hexitRE); // should require at least 1
 | |
|               return "integer";
 | |
|             }
 | |
|             if (source.eat(/[oO]/)) {
 | |
|               source.eatWhile(octitRE); // should require at least 1
 | |
|               return "number";
 | |
|             }
 | |
|           }
 | |
|           source.eatWhile(digitRE);
 | |
|           var t = "number";
 | |
|           if (source.eat('.')) {
 | |
|             t = "number";
 | |
|             source.eatWhile(digitRE); // should require at least 1
 | |
|           }
 | |
|           if (source.eat(/[eE]/)) {
 | |
|             t = "number";
 | |
|             source.eat(/[-+]/);
 | |
|             source.eatWhile(digitRE); // should require at least 1
 | |
|           }
 | |
|           return t;
 | |
|         }
 | |
| 
 | |
|         if (symbolRE.test(ch)) {
 | |
|           if (ch == '-' && source.eat(/-/)) {
 | |
|             source.eatWhile(/-/);
 | |
|             if (!source.eat(symbolRE)) {
 | |
|               source.skipToEnd();
 | |
|               return "comment";
 | |
|             }
 | |
|           }
 | |
|           source.eatWhile(symbolRE);
 | |
|           return "builtin";
 | |
|         }
 | |
| 
 | |
|         return "error";
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     function ncomment(type, nest) {
 | |
|       if (nest == 0) {
 | |
|         return normal();
 | |
|       }
 | |
|       return function(source, setState) {
 | |
|         var currNest = nest;
 | |
|         while (!source.eol()) {
 | |
|           var ch = source.next();
 | |
|           if (ch == '{' && source.eat('-')) {
 | |
|             ++currNest;
 | |
|           } else if (ch == '-' && source.eat('}')) {
 | |
|             --currNest;
 | |
|             if (currNest == 0) {
 | |
|               setState(normal());
 | |
|               return type;
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|         setState(ncomment(type, currNest));
 | |
|         return type;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     function stringLiteral(source, setState) {
 | |
|       while (!source.eol()) {
 | |
|         var ch = source.next();
 | |
|         if (ch == '"') {
 | |
|           setState(normal());
 | |
|           return "string";
 | |
|         }
 | |
|         if (ch == '\\') {
 | |
|           if (source.eol() || source.eat(whiteCharRE)) {
 | |
|             setState(stringGap);
 | |
|             return "string";
 | |
|           }
 | |
|           if (!source.eat('&')) source.next(); // should handle other escapes here
 | |
|         }
 | |
|       }
 | |
|       setState(normal());
 | |
|       return "error";
 | |
|     }
 | |
| 
 | |
|     function stringGap(source, setState) {
 | |
|       if (source.eat('\\')) {
 | |
|         return switchState(source, setState, stringLiteral);
 | |
|       }
 | |
|       source.next();
 | |
|       setState(normal());
 | |
|       return "error";
 | |
|     }
 | |
| 
 | |
| 
 | |
|     var wellKnownWords = (function() {
 | |
|       var wkw = {};
 | |
| 
 | |
|       var keywords = [
 | |
|         "case", "of", "as",
 | |
|         "if", "then", "else",
 | |
|         "let", "in",
 | |
|         "infix", "infixl", "infixr",
 | |
|         "type", "alias",
 | |
|         "input", "output", "foreign", "loopback",
 | |
|         "module", "where", "import", "exposing",
 | |
|         "_", "..", "|", ":", "=", "\\", "\"", "->", "<-"
 | |
|       ];
 | |
| 
 | |
|       for (var i = keywords.length; i--;)
 | |
|         wkw[keywords[i]] = "keyword";
 | |
| 
 | |
|       return wkw;
 | |
|     })();
 | |
| 
 | |
| 
 | |
| 
 | |
|     return {
 | |
|       startState: function ()  { return { f: normal() }; },
 | |
|       copyState:  function (s) { return { f: s.f }; },
 | |
| 
 | |
|       token: function(stream, state) {
 | |
|         var t = state.f(stream, function(s) { state.f = s; });
 | |
|         var w = stream.current();
 | |
|         return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t;
 | |
|       }
 | |
|     };
 | |
| 
 | |
|   });
 | |
| 
 | |
|   CodeMirror.defineMIME("text/x-elm", "elm");
 | |
| });
 | |
| 
 |