|
- // CodeMirror, copyright (c) by Marijn Haverbeke and others
- // Distributed under an MIT license: https://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("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");
-
- });
|