mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-26 09:31:34 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			194 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			194 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // CodeMirror, copyright (c) by Marijn Haverbeke and others
 | |
| // Distributed under an MIT license: https://codemirror.net/5/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("sieve", function(config) {
 | |
|   function words(str) {
 | |
|     var obj = {}, words = str.split(" ");
 | |
|     for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
 | |
|     return obj;
 | |
|   }
 | |
| 
 | |
|   var keywords = words("if elsif else stop require");
 | |
|   var atoms = words("true false not");
 | |
|   var indentUnit = config.indentUnit;
 | |
| 
 | |
|   function tokenBase(stream, state) {
 | |
| 
 | |
|     var ch = stream.next();
 | |
|     if (ch == "/" && stream.eat("*")) {
 | |
|       state.tokenize = tokenCComment;
 | |
|       return tokenCComment(stream, state);
 | |
|     }
 | |
| 
 | |
|     if (ch === '#') {
 | |
|       stream.skipToEnd();
 | |
|       return "comment";
 | |
|     }
 | |
| 
 | |
|     if (ch == "\"") {
 | |
|       state.tokenize = tokenString(ch);
 | |
|       return state.tokenize(stream, state);
 | |
|     }
 | |
| 
 | |
|     if (ch == "(") {
 | |
|       state._indent.push("(");
 | |
|       // add virtual angel wings so that editor behaves...
 | |
|       // ...more sane in case of broken brackets
 | |
|       state._indent.push("{");
 | |
|       return null;
 | |
|     }
 | |
| 
 | |
|     if (ch === "{") {
 | |
|       state._indent.push("{");
 | |
|       return null;
 | |
|     }
 | |
| 
 | |
|     if (ch == ")")  {
 | |
|       state._indent.pop();
 | |
|       state._indent.pop();
 | |
|     }
 | |
| 
 | |
|     if (ch === "}") {
 | |
|       state._indent.pop();
 | |
|       return null;
 | |
|     }
 | |
| 
 | |
|     if (ch == ",")
 | |
|       return null;
 | |
| 
 | |
|     if (ch == ";")
 | |
|       return null;
 | |
| 
 | |
| 
 | |
|     if (/[{}\(\),;]/.test(ch))
 | |
|       return null;
 | |
| 
 | |
|     // 1*DIGIT "K" / "M" / "G"
 | |
|     if (/\d/.test(ch)) {
 | |
|       stream.eatWhile(/[\d]/);
 | |
|       stream.eat(/[KkMmGg]/);
 | |
|       return "number";
 | |
|     }
 | |
| 
 | |
|     // ":" (ALPHA / "_") *(ALPHA / DIGIT / "_")
 | |
|     if (ch == ":") {
 | |
|       stream.eatWhile(/[a-zA-Z_]/);
 | |
|       stream.eatWhile(/[a-zA-Z0-9_]/);
 | |
| 
 | |
|       return "operator";
 | |
|     }
 | |
| 
 | |
|     stream.eatWhile(/\w/);
 | |
|     var cur = stream.current();
 | |
| 
 | |
|     // "text:" *(SP / HTAB) (hash-comment / CRLF)
 | |
|     // *(multiline-literal / multiline-dotstart)
 | |
|     // "." CRLF
 | |
|     if ((cur == "text") && stream.eat(":"))
 | |
|     {
 | |
|       state.tokenize = tokenMultiLineString;
 | |
|       return "string";
 | |
|     }
 | |
| 
 | |
|     if (keywords.propertyIsEnumerable(cur))
 | |
|       return "keyword";
 | |
| 
 | |
|     if (atoms.propertyIsEnumerable(cur))
 | |
|       return "atom";
 | |
| 
 | |
|     return null;
 | |
|   }
 | |
| 
 | |
|   function tokenMultiLineString(stream, state)
 | |
|   {
 | |
|     state._multiLineString = true;
 | |
|     // the first line is special it may contain a comment
 | |
|     if (!stream.sol()) {
 | |
|       stream.eatSpace();
 | |
| 
 | |
|       if (stream.peek() == "#") {
 | |
|         stream.skipToEnd();
 | |
|         return "comment";
 | |
|       }
 | |
| 
 | |
|       stream.skipToEnd();
 | |
|       return "string";
 | |
|     }
 | |
| 
 | |
|     if ((stream.next() == ".")  && (stream.eol()))
 | |
|     {
 | |
|       state._multiLineString = false;
 | |
|       state.tokenize = tokenBase;
 | |
|     }
 | |
| 
 | |
|     return "string";
 | |
|   }
 | |
| 
 | |
|   function tokenCComment(stream, state) {
 | |
|     var maybeEnd = false, ch;
 | |
|     while ((ch = stream.next()) != null) {
 | |
|       if (maybeEnd && ch == "/") {
 | |
|         state.tokenize = tokenBase;
 | |
|         break;
 | |
|       }
 | |
|       maybeEnd = (ch == "*");
 | |
|     }
 | |
|     return "comment";
 | |
|   }
 | |
| 
 | |
|   function tokenString(quote) {
 | |
|     return function(stream, state) {
 | |
|       var escaped = false, ch;
 | |
|       while ((ch = stream.next()) != null) {
 | |
|         if (ch == quote && !escaped)
 | |
|           break;
 | |
|         escaped = !escaped && ch == "\\";
 | |
|       }
 | |
|       if (!escaped) state.tokenize = tokenBase;
 | |
|       return "string";
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   return {
 | |
|     startState: function(base) {
 | |
|       return {tokenize: tokenBase,
 | |
|               baseIndent: base || 0,
 | |
|               _indent: []};
 | |
|     },
 | |
| 
 | |
|     token: function(stream, state) {
 | |
|       if (stream.eatSpace())
 | |
|         return null;
 | |
| 
 | |
|       return (state.tokenize || tokenBase)(stream, state);
 | |
|     },
 | |
| 
 | |
|     indent: function(state, _textAfter) {
 | |
|       var length = state._indent.length;
 | |
|       if (_textAfter && (_textAfter[0] == "}"))
 | |
|         length--;
 | |
| 
 | |
|       if (length <0)
 | |
|         length = 0;
 | |
| 
 | |
|       return length * indentUnit;
 | |
|     },
 | |
| 
 | |
|     electricChars: "}"
 | |
|   };
 | |
| });
 | |
| 
 | |
| CodeMirror.defineMIME("application/sieve", "sieve");
 | |
| 
 | |
| });
 | 
