CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/codemirror/mode/coffeescript2.js
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
// Based on https://github.com/giovannicalo/brackets-coffeescript/blob/master/main.js
7
// modified by William Stein.
8
9
(function(mod) {
10
if (typeof exports == "object" && typeof module == "object") // CommonJS
11
mod(require("codemirror"));
12
else if (typeof define == "function" && define.amd) // AMD
13
define(["../../lib/codemirror"], mod);
14
else // Plain browser env
15
mod(CodeMirror);
16
})(function(CodeMirror) {
17
"use strict";
18
CodeMirror.defineMode("coffeescript2", function(config, parser_config) {
19
var constant_list = [
20
"false",
21
"no",
22
"null",
23
"off",
24
"on",
25
"true",
26
"undefined",
27
"Infinity",
28
"NaN"
29
];
30
var keyword_list = [
31
"and",
32
"break",
33
"by",
34
"catch",
35
"class",
36
"continue",
37
"debugger",
38
"delete",
39
"do",
40
"else",
41
"extends",
42
"finally",
43
"for",
44
"if",
45
"in",
46
"instanceof",
47
"is",
48
"isnt",
49
"loop",
50
"new",
51
"not",
52
"of",
53
"or",
54
"return",
55
"super",
56
"switch",
57
"then",
58
"this",
59
"throw",
60
"try",
61
"typeof",
62
"unless",
63
"until",
64
"when",
65
"while",
66
"yield"
67
];
68
var constant = constant_list.join("|");
69
var identifier = "[a-zA-Z\\$_][\\w\\$]*";
70
var keyword = keyword_list.join("|");
71
var number = "((?:0(?:(?:[bB][01]+)|(?:[oO][0-7]+)|(?:[xX][0-9a-fA-F]+)))|(?:[\\d]*\\.?[\\d]+(?:e[\\+\\-]\\d+)?))";
72
var regexp = "\\/((?![*+?\\s])(?:[^\\r\\n\\[/\\\\]|\\\\.|\\[(?:[^\\r\\n\\]\\\\]|\\\\.)*\\])+)\\/";
73
var regexp_flag = "\\b(([gimuy])(?![gimuy]*\\2))+\\b";
74
var not_identifier = "[^\\w\\$]";
75
var not_keyword = "[^a-z]";
76
var not_number = "([^0-9a-fA-FoxOX\\+\\-\\.]|\\.{2,})";
77
var whitespace = "[\\t ]*";
78
var xml_identifier = "[a-zA-Z:_][a-zA-Z0-9:_\\-\\.]*";
79
var xml_string = "(?:\"(?:(?:\\\")|[^\"])*\")|(?:'(?:(?:\\\')|[^'])*')";
80
var xml_value = "(?:\\{[\\s\\S]*?\\})";
81
var xml_element = "<\\/?(" + xml_identifier + ")(?: (?:" + xml_string + "|" + xml_value + "|[^<>\"'])*?)?(?:\\/)?" + whitespace + ">";
82
return {
83
token: function(stream, state) {
84
var highlight = "";
85
if (!state.isolated) {
86
if (stream.sol()) {
87
state.isolated = true;
88
} else {
89
stream.backUp(1);
90
if (stream.match(new RegExp("^" + not_identifier), false)) {
91
state.isolated = true;
92
}
93
stream.next();
94
}
95
} else if (!stream.sol()) {
96
stream.backUp(1);
97
if (!stream.match(new RegExp("^" + not_identifier), false)) {
98
state.isolated = false;
99
}
100
stream.next();
101
}
102
if (parser_config.cjsx) {
103
if (state.xml_element) {
104
if (stream.match(/^\/?>/)) {
105
state.xml_attribute = false;
106
state.xml_element = false;
107
state.xml_string = false;
108
state.xml_value = false;
109
highlight = "keyword";
110
}
111
} else if ((!state.string_interpolated) && (!state.string_literal) && (!state.regexp) && (!state.regexp_block) && (stream.match(new RegExp("^" + xml_element), false))) {
112
state.xml_element = true;
113
stream.match(new RegExp("<\\/?" + xml_identifier));
114
return "keyword";
115
}
116
if (state.xml_element) {
117
if (state.xml_attribute) {
118
if (stream.match(/^(?:\/>)|[\t=> ]/)) {
119
state.xml_attribute = false;
120
return highlight;
121
} else {
122
highlight = "number";
123
}
124
} else if ((state.isolated) && (!state.xml_string) && (!state.xml_value) && (stream.match(new RegExp("^" + identifier), false))) {
125
state.xml_attribute = true;
126
highlight = "number";
127
}
128
if (stream.match(new RegExp("^" + xml_string))) {
129
return "string";
130
}
131
if (state.xml_value) {
132
if (stream.match(/^\}/)) {
133
state.xml_value = false;
134
return "minus";
135
}
136
} else if (stream.match(new RegExp("^" + xml_value), false)) {
137
state.xml_value = true;
138
highlight = "minus";
139
}
140
if (!state.xml_value) {
141
stream.next();
142
return highlight;
143
}
144
}
145
}
146
if (state.parameter_list) {
147
if (stream.match(/^\)/, false)) {
148
state.parameter_list = false;
149
}
150
} else if (stream.match(/^\([^\n\r\(\)]*\)[\t ]*(->|=>)/, false)) {
151
state.parameter_list = true;
152
}
153
if (state.parameter) {
154
if ((stream.sol()) || (stream.match(new RegExp("^" + not_identifier), false))) {
155
state.parameter = false;
156
} else {
157
highlight = "def";
158
}
159
}
160
if ((state.parameter_list) && (stream.match(new RegExp("^" + identifier), false))) {
161
state.parameter = true;
162
highlight = "def";
163
}
164
if ((state.isolated) && (!state.string_interpolated) && (!state.string_literal) && (!state.comment_block) && (!state.comment_line) && (stream.match(new RegExp("^@")))) {
165
state.method = true;
166
return "keyword";
167
}
168
if (state.keyword) {
169
if ((stream.sol()) || (stream.match(new RegExp("^" + not_keyword), false))) {
170
state.keyword = false;
171
} else {
172
highlight = "keyword";
173
}
174
}
175
if ((state.isolated) && (stream.match(new RegExp("^(" + keyword + ")(" + not_identifier + "|$)"), false))) {
176
state.keyword = true;
177
highlight = "keyword";
178
}
179
if (state.constant) {
180
if ((stream.sol()) || (stream.match(new RegExp("^" + not_keyword), false))) {
181
state.constant = false;
182
} else {
183
highlight = "string";
184
}
185
}
186
if ((state.isolated) && (stream.match(new RegExp("^(" + constant + ")(" + not_identifier + "|$)"), false))) {
187
state.constant = true;
188
highlight = "string";
189
}
190
if (state.function) {
191
if ((stream.sol()) || (stream.match(/^(:|=)/, false))) {
192
state.function = false;
193
} else {
194
highlight = "def";
195
}
196
}
197
if (stream.match(new RegExp("^" + identifier + whitespace + "(:|=)" + whitespace + "(\\([^\\n\\r]+\\))?" + whitespace + "(->|=>)"), false)) {
198
state.function = true;
199
highlight = "def";
200
}
201
if (state.property) {
202
if ((stream.sol()) || (stream.match(/^:/, false))) {
203
state.property = false;
204
} else {
205
highlight = "def";
206
}
207
} else if ((!state.regexp) && (!state.regexp_block) && (!state.string_interpolated) && (!state.string_literal) && (stream.match(new RegExp("^(" + identifier + "|((\"|')?(?:(?:(?!\\3).)|\\\\\\3)*\\3))" + whitespace + ":"), false))) {
208
state.property = true;
209
highlight = "def";
210
}
211
if (state.variable) {
212
if ((stream.sol()) || (stream.match(/^[=\[]/, false))) {
213
state.variable = false;
214
} else {
215
highlight = "def";
216
}
217
}
218
if (stream.match(new RegExp("^" + identifier + "(\\[.*\\])*" + whitespace + "=([^=]|$)"), false)) {
219
state.variable = true;
220
highlight = "def";
221
}
222
if (state.method) {
223
if ((stream.sol()) || (stream.match(new RegExp("^" + not_identifier), false))) {
224
state.method = false;
225
} else {
226
highlight = "def";
227
}
228
}
229
if ((stream.match(new RegExp("^\\." + identifier), false))) {
230
state.method = true;
231
}
232
if (state.number) {
233
if ((stream.sol()) || (stream.match(new RegExp("^" + not_number), false))) {
234
state.number = false;
235
} else {
236
highlight = "number";
237
}
238
}
239
if ((state.isolated) && (stream.match(new RegExp("^" + number + "(" + not_identifier + "|$)"), false))) {
240
stream.backUp(1);
241
if (!stream.match(/^\.{2,}/, false)) {
242
state.number = true;
243
highlight = "number";
244
}
245
stream.next();
246
}
247
if (state.string_interpolated) {
248
if ((stream.match(/^\\{2}/, false)) || (stream.match(/^\\"/, false))) {
249
highlight = "string";
250
stream.next();
251
} else if (stream.match(/^"/, false)) {
252
state.string_interpolated = false;
253
highlight = "string";
254
} else {
255
highlight = "string";
256
}
257
} else if ((!state.comment_block) && (!state.comment_line) && (!state.regexp) && (!state.regexp_block) && (!state.property) && (!state.string_literal) && (stream.match(/^"/, false))) {
258
state.string_interpolated = true;
259
highlight = "string";
260
}
261
if (state.string_literal) {
262
if ((stream.match(/^\\{2}/, false)) || (stream.match(/^\\'/, false))) {
263
highlight = "string";
264
stream.next();
265
} else if (stream.match(/^'/, false)) {
266
state.string_literal = false;
267
highlight = "string";
268
} else {
269
highlight = "string";
270
}
271
} else if ((!state.comment_block) && (!state.comment_line) && (!state.regexp) && (!state.regexp_block) && (!state.property) && (!state.string_interpolated) && (stream.match(/^'/, false))) {
272
state.string_literal = true;
273
highlight = "string";
274
}
275
if (state.regexp_block) {
276
if (stream.match(/^\/{3}/, false)) {
277
state.regexp_block = false;
278
highlight = "string";
279
stream.next();
280
stream.next();
281
stream.next();
282
stream.match(new RegExp("^" + regexp_flag));
283
stream.backUp(1);
284
} else {
285
highlight = "string";
286
}
287
} else if ((!state.string_interpolated) && (!state.string_literal) && (stream.match(/^\/{3}/, false))) {
288
state.regexp_block = true;
289
highlight = "string";
290
}
291
if (state.regexp) {
292
if (stream.match(/^\\\\\//, false)) {
293
state.regexp = false;
294
highlight = "string";
295
stream.next();
296
stream.next();
297
stream.next();
298
stream.match(new RegExp("^" + regexp_flag));
299
stream.backUp(1);
300
} else if (stream.match(/^\\\//, false)) {
301
highlight = "string";
302
stream.next();
303
} else if ((stream.sol()) || (stream.match(/^\//, false))) {
304
state.regexp = false;
305
highlight = "string";
306
stream.next();
307
stream.match(new RegExp("^" + regexp_flag));
308
stream.backUp(1);
309
} else {
310
highlight = "string";
311
}
312
} else if ((!state.regexp_block) && (!state.string_interpolated) && (!state.string_literal) && (stream.match(new RegExp("^" + regexp), false))) {
313
state.regexp = true;
314
highlight = "string";
315
}
316
if (state.comment_block) {
317
if (stream.match(/^#{3}/, false)) {
318
state.comment_block = false;
319
highlight = "comment";
320
stream.next();
321
stream.next();
322
} else {
323
highlight = "comment";
324
}
325
} else if ((!state.regexp) && (!state.regexp_block) && (!state.string_interpolated) && (!state.string_literal) && (stream.match(/^#{3}/, false))) {
326
state.comment_block = true;
327
highlight = "comment";
328
stream.next();
329
stream.next();
330
}
331
if (stream.sol()) {
332
state.comment_line = false;
333
}
334
if (state.comment_line) {
335
highlight = "comment";
336
} else if ((!state.comment_block) && (!state.regexp) && (!state.regexp_block) && (!state.string_interpolated) && (!state.string_literal) && (stream.match(/^#/, false))) {
337
if (stream.column() > 1) {
338
stream.backUp(2);
339
if (!stream.match(/^#{3}/, false)) {
340
state.comment_line = true;
341
highlight = "comment";
342
}
343
stream.next();
344
stream.next();
345
} else {
346
state.comment_line = true;
347
highlight = "comment";
348
}
349
} else if ((state.regexp_block) && (stream.match(/^[\t ]+#/, false))) {
350
state.comment_line = true;
351
highlight = "comment";
352
}
353
if (state.string_interpolation) {
354
if ((!state.comment_block) && (!state.regexp) && (!state.regexp_block) && (!state.string_interpolated) && (!state.string_literal) && (stream.match(/^\}/, false))) {
355
state.string_interpolation = false;
356
state.string_interpolated = true;
357
highlight = "minus";
358
}
359
} else if ((state.string_interpolated) && (stream.match(/^#\{/, false))) {
360
state.string_interpolation = true;
361
state.string_interpolated = false;
362
highlight = "minus";
363
stream.next();
364
}
365
stream.next();
366
return highlight;
367
},
368
startState: function() {
369
return {
370
comment_block: false,
371
comment_line: false,
372
constant: false,
373
function: false,
374
isolated: false,
375
keyword: false,
376
method: false,
377
number: false,
378
parameter: false,
379
parameter_list: false,
380
property: false,
381
regexp: false,
382
regexp_block: false,
383
string_interpolated: false,
384
string_interpolation: false,
385
string_literal: false,
386
variable: false,
387
xml_attribute: false,
388
xml_element: false,
389
xml_string: false,
390
xml_value: false
391
};
392
},
393
lineComment: "#",
394
fold: "indent"
395
};
396
});
397
CodeMirror.defineMIME("text/cjsx", {
398
cjsx: true,
399
name: "coffeescript2"
400
});
401
CodeMirror.defineMIME("text/coffeescript2", {
402
cjsx: false,
403
name: "coffeescript2"
404
});
405
});
406
407