blob: 3c510a0b874d5e60df3e7ac751d686e91729a30f [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001CodeMirror.defineMode("clike", function(config, parserConfig) {
2 var indentUnit = config.indentUnit,
3 keywords = parserConfig.keywords || {},
4 blockKeywords = parserConfig.blockKeywords || {},
5 atoms = parserConfig.atoms || {},
6 hooks = parserConfig.hooks || {},
7 multiLineStrings = parserConfig.multiLineStrings;
8 var isOperatorChar = /[+\-*&%=<>!?|\/]/;
9
10 var curPunc;
11
12 function tokenBase(stream, state) {
13 var ch = stream.next();
14
15 if (hooks[ch]) {
16 var result = hooks[ch](stream, state);
17 if (result !== false) return result;
18 }
19 if (ch == '"' || ch == "'") {
20 state.tokenize = tokenString(ch);
21 return state.tokenize(stream, state);
22 }
23 if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
24 curPunc = ch;
25 return null;
26 }
27 //if (/\d/.test(ch)) {
28 // stream.eatWhile(/[\w\.]/);
29 // return "number";
30 // }
31 if (ch == "/") {
32 if (stream.eat("*")) {
33 state.tokenize = tokenComment;
34 return tokenComment(stream, state);
35 }
36 if (stream.eat("/")) {
37 stream.skipToEnd();
38 return "comment";
39 }
40 }
41
42
43
44
45/* if (ch == "!") {
46 if (stream.eat("!")) {
47 if (stream.eat("!")) {
48 if (stream.eat(" ")) {
49
50 stream.skipToEnd();
51 return "log";
52 }
53 }
54 }
55 }
56*/
57
58
59
60
61if (ch == "S") {
62 if (stream.eat("T")) {
63 if (stream.eat("A")) {
64 if (stream.eat("R")) {
65 stream.skipToEnd();
66 return "log_start_end_case";
67 }
68 } else if (stream.eat("E")) {
69 if (stream.eat("P")) {
70 stream.skipToEnd();
71 return "log_step";
72 }
73 }
74 }
75}
76
77
78
79
80
81
82
83
84if (ch == "S") {
85 if (stream.eat("T")) {
86 if (stream.eat("E")) {
87 if (stream.eat("P")) {
88
89 stream.skipToEnd();
90 return "log_step";
91 }
92 }
93 }
94 }
95
96
97
98if (ch == "P" && stream.eat("A") && stream.eat("S") && stream.eat("S") && stream.eat("E") && stream.eat("D") ) {
99 return "log_pass";
100 }
101
102
103
104
105
106
107 if (ch == "I") {
108 if (stream.eat("N")) {
109 if (stream.eat("F")) {
110 if (stream.eat("O")) {
111
112 stream.skipToEnd();
113 return "log_info";
114 }
115 }
116 }
117 }
118
119
120
121
122
123
124
125
126 if (ch == "D") {
127 if (stream.eat("E")) {
128 if (stream.eat("S")) {
129 if (stream.eat("C")) {
130 stream.skipToEnd();
131 return "log_description";
132 }
133 } else if(stream.eat("B")) {
134 if(stream.eat("U")) {
135 if(stream.eat("G")) {
136 stream.skipToEnd();
137 return "log_debug";
138 }
139 }
140 }
141 }
142 }
143
144
145
146
147
148
149 if (ch == "-") {
150
151 if (stream.eat("-")) {
152 if (stream.eat("-")) {
153 if (stream.eat(" ")) {
154
155 stream.skipToEnd();
156 return "log_error_warn";
157 }
158 }
159 }
160 }
161
162
163
164
165
166 if (ch == "+") {
167 if (stream.eat("+")) {
168 if (stream.eat("+")) {
169 if (stream.eat(" ")) {
170
171 stream.skipToEnd();
172 return "log_pass";
173 }
174 }
175 }
176 }
177
178
179
180
181
182
183
184
185if (ch == "E") {
186
187 if (stream.eat("N")) {
188 if (stream.eat("D")) {
189 if (stream.eat("C")) {
190 if (stream.eat("A")) {
191 if (stream.eat("S")) {
192
193 stream.skipToEnd();
194 return "log_start_end_case";
195 }
196 }
197 }
198 }
199 }
200 }
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232 if (isOperatorChar.test(ch)) {
233 stream.eatWhile(isOperatorChar);
234 return "operator";
235 }
236 stream.eatWhile(/[\w\$_]/);
237 var cur = stream.current();
238 if (keywords.propertyIsEnumerable(cur)) {
239 if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
240 return "keyword";
241 }
242 if (atoms.propertyIsEnumerable(cur)) return "atom";
243 return "word";
244 }
245
246 function tokenString(quote) {
247 return function(stream, state) {
248 var escaped = false, next, end = false;
249 while ((next = stream.next()) != null) {
250 if (next == quote && !escaped) {end = true; break;}
251 escaped = !escaped && next == "\\";
252 }
253 if (end || !(escaped || multiLineStrings))
254 state.tokenize = null;
255 return "string";
256 };
257 }
258
259 function tokenComment(stream, state) {
260 var maybeEnd = false, ch;
261 while (ch = stream.next()) {
262 if (ch == "/" && maybeEnd) {
263 state.tokenize = null;
264 break;
265 }
266 maybeEnd = (ch == "*");
267 }
268 return "comment";
269 }
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289 function Context(indented, column, type, align, prev) {
290 this.indented = indented;
291 this.column = column;
292 this.type = type;
293 this.align = align;
294 this.prev = prev;
295 }
296 function pushContext(state, col, type) {
297 return state.context = new Context(state.indented, col, type, null, state.context);
298 }
299 function popContext(state) {
300 var t = state.context.type;
301 if (t == ")" || t == "]" || t == "}")
302 state.indented = state.context.indented;
303 return state.context = state.context.prev;
304 }
305
306 // Interface
307
308 return {
309 startState: function(basecolumn) {
310 return {
311 tokenize: null,
312 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
313 indented: 0,
314 startOfLine: true
315 };
316 },
317
318 token: function(stream, state) {
319 var ctx = state.context;
320 if (stream.sol()) {
321 if (ctx.align == null) ctx.align = false;
322 state.indented = stream.indentation();
323 state.startOfLine = true;
324 }
325 if (stream.eatSpace()) return null;
326 curPunc = null;
327 var style = (state.tokenize || tokenBase)(stream, state);
328 if (style == "comment" || style == "meta") return style;
329 if (ctx.align == null) ctx.align = true;
330
331 if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
332 else if (curPunc == "{") pushContext(state, stream.column(), "}");
333 else if (curPunc == "[") pushContext(state, stream.column(), "]");
334 else if (curPunc == "(") pushContext(state, stream.column(), ")");
335 else if (curPunc == "}") {
336 while (ctx.type == "statement") ctx = popContext(state);
337 if (ctx.type == "}") ctx = popContext(state);
338 while (ctx.type == "statement") ctx = popContext(state);
339 }
340 else if (curPunc == ctx.type) popContext(state);
341 else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
342 pushContext(state, stream.column(), "statement");
343 state.startOfLine = false;
344 return style;
345 },
346
347 indent: function(state, textAfter) {
348 if (state.tokenize != tokenBase && state.tokenize != null) return 0;
349 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
350 if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
351 var closing = firstChar == ctx.type;
352 if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
353 else if (ctx.align) return ctx.column + (closing ? 0 : 1);
354 else return ctx.indented + (closing ? 0 : indentUnit);
355 },
356
357 electricChars: "{}"
358 };
359});
360
361(function() {
362 function words(str) {
363 var obj = {}, words = str.split(" ");
364 for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
365 return obj;
366 }
367 var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
368 "double static else struct entry switch extern typedef float union for unsigned " +
369 "goto while enum void const signed volatile";
370
371 function cppHook(stream, state) {
372 if (!state.startOfLine) return false;
373 stream.skipToEnd();
374 return "meta";
375 }
376
377 // C#-style strings where "" escapes a quote.
378 function tokenAtString(stream, state) {
379 var next;
380 while ((next = stream.next()) != null) {
381 if (next == '"' && !stream.eat('"')) {
382 state.tokenize = null;
383 break;
384 }
385 }
386 return "string";
387 }
388
389 CodeMirror.defineMIME("text/x-csrc", {
390 name: "clike",
391 keywords: words(cKeywords),
392 blockKeywords: words("case do else for if switch while struct"),
393 atoms: words("null"),
394 hooks: {"#": cppHook}
395 });
396 CodeMirror.defineMIME("text/x-c++src", {
397 name: "clike",
398 keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
399 "static_cast typeid catch operator template typename class friend private " +
400 "this using const_cast inline public throw virtual delete mutable protected " +
401 "wchar_t"),
402 blockKeywords: words("catch class do else finally for if struct switch try while"),
403 atoms: words("true false null"),
404 hooks: {"#": cppHook}
405 });
406 CodeMirror.defineMIME("text/x-java", {
407 name: "clike",
408 keywords: words("abstract assert boolean break byte case catch char class const continue default " +
409 "do double else enum extends final finally float for goto if implements import " +
410 "instanceof int interface long native new package private protected public " +
411 "return short static strictfp super switch synchronized this throw throws transient " +
412 "try void volatile while"),
413 blockKeywords: words("catch class do else finally for if switch try while"),
414 atoms: words("true false null"),
415 hooks: {
416 "@": function(stream, state) {
417 stream.eatWhile(/[\w\$_]/);
418 return "meta";
419 }
420 }
421 });
422 CodeMirror.defineMIME("text/x-csharp", {
423 name: "clike",
424 keywords: words(" abstract as base bool break byte case catch char checked class const continue decimal" +
425 " default delegate do double else enum event explicit extern finally fixed float for" +
426 " foreach goto if implicit in int interface internal is lock long namespace new object" +
427 " operator out override params private protected public readonly ref return sbyte sealed short" +
428 " sizeof stackalloc static string struct switch this throw try typeof uint ulong unchecked" +
429 " unsafe ushort using virtual void volatile while add alias ascending descending dynamic from get" +
430 " global group into join let orderby partial remove select set value var yield"),
431 blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
432 atoms: words("true false null"),
433 hooks: {
434 "@": function(stream, state) {
435 if (stream.eat('"')) {
436 state.tokenize = tokenAtString;
437 return tokenAtString(stream, state);
438 }
439 stream.eatWhile(/[\w\$_]/);
440 return "meta";
441 }
442 }
443 });
444}());
445