move a few things away in to-be-integrated/
[myslice.git] / to-be-integrated / third-party / codemirror-3.15 / mode / sieve / sieve.js
1 /*
2  * See LICENSE in this directory for the license under which this code
3  * is released.
4  */
5
6 CodeMirror.defineMode("sieve", function(config) {
7   function words(str) {
8     var obj = {}, words = str.split(" ");
9     for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
10     return obj;
11   }
12
13   var keywords = words("if elsif else stop require");
14   var atoms = words("true false not");
15   var indentUnit = config.indentUnit;
16
17   function tokenBase(stream, state) {
18
19     var ch = stream.next();
20     if (ch == "/" && stream.eat("*")) {
21       state.tokenize = tokenCComment;
22       return tokenCComment(stream, state);
23     }
24
25     if (ch === '#') {
26       stream.skipToEnd();
27       return "comment";
28     }
29
30     if (ch == "\"") {
31       state.tokenize = tokenString(ch);
32       return state.tokenize(stream, state);
33     }
34
35     if (ch == "(") {
36       state._indent.push("(");
37       // add virtual angel wings so that editor behaves...
38       // ...more sane incase of broken brackets
39       state._indent.push("{");
40       return null;
41     }
42
43     if (ch === "{") {
44       state._indent.push("{");
45       return null;
46     }
47
48     if (ch == ")")  {
49       state._indent.pop();
50       state._indent.pop();
51     }
52
53     if (ch === "}") {
54       state._indent.pop();
55       return null;
56     }
57
58     if (ch == ",")
59       return null;
60
61     if (ch == ";")
62       return null;
63
64
65     if (/[{}\(\),;]/.test(ch))
66       return null;
67
68     // 1*DIGIT "K" / "M" / "G"
69     if (/\d/.test(ch)) {
70       stream.eatWhile(/[\d]/);
71       stream.eat(/[KkMmGg]/);
72       return "number";
73     }
74
75     // ":" (ALPHA / "_") *(ALPHA / DIGIT / "_")
76     if (ch == ":") {
77       stream.eatWhile(/[a-zA-Z_]/);
78       stream.eatWhile(/[a-zA-Z0-9_]/);
79
80       return "operator";
81     }
82
83     stream.eatWhile(/\w/);
84     var cur = stream.current();
85
86     // "text:" *(SP / HTAB) (hash-comment / CRLF)
87     // *(multiline-literal / multiline-dotstart)
88     // "." CRLF
89     if ((cur == "text") && stream.eat(":"))
90     {
91       state.tokenize = tokenMultiLineString;
92       return "string";
93     }
94
95     if (keywords.propertyIsEnumerable(cur))
96       return "keyword";
97
98     if (atoms.propertyIsEnumerable(cur))
99       return "atom";
100
101     return null;
102   }
103
104   function tokenMultiLineString(stream, state)
105   {
106     state._multiLineString = true;
107     // the first line is special it may contain a comment
108     if (!stream.sol()) {
109       stream.eatSpace();
110
111       if (stream.peek() == "#") {
112         stream.skipToEnd();
113         return "comment";
114       }
115
116       stream.skipToEnd();
117       return "string";
118     }
119
120     if ((stream.next() == ".")  && (stream.eol()))
121     {
122       state._multiLineString = false;
123       state.tokenize = tokenBase;
124     }
125
126     return "string";
127   }
128
129   function tokenCComment(stream, state) {
130     var maybeEnd = false, ch;
131     while ((ch = stream.next()) != null) {
132       if (maybeEnd && ch == "/") {
133         state.tokenize = tokenBase;
134         break;
135       }
136       maybeEnd = (ch == "*");
137     }
138     return "comment";
139   }
140
141   function tokenString(quote) {
142     return function(stream, state) {
143       var escaped = false, ch;
144       while ((ch = stream.next()) != null) {
145         if (ch == quote && !escaped)
146           break;
147         escaped = !escaped && ch == "\\";
148       }
149       if (!escaped) state.tokenize = tokenBase;
150       return "string";
151     };
152   }
153
154   return {
155     startState: function(base) {
156       return {tokenize: tokenBase,
157               baseIndent: base || 0,
158               _indent: []};
159     },
160
161     token: function(stream, state) {
162       if (stream.eatSpace())
163         return null;
164
165       return (state.tokenize || tokenBase)(stream, state);;
166     },
167
168     indent: function(state, _textAfter) {
169       var length = state._indent.length;
170       if (_textAfter && (_textAfter[0] == "}"))
171         length--;
172
173       if (length <0)
174         length = 0;
175
176       return length * indentUnit;
177     },
178
179     electricChars: "}"
180   };
181 });
182
183 CodeMirror.defineMIME("application/sieve", "sieve");