Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
malwaredllc
GitHub Repository: malwaredllc/byob
Path: blob/master/web-gui/buildyourownbotnet/assets/js/codemirror/mode/coffeescript/coffeescript.js
1293 views
1
/**
2
* Link to the project's GitHub page:
3
* https://github.com/pickhardt/coffeescript-codemirror-mode
4
*/
5
CodeMirror.defineMode("coffeescript", function(conf) {
6
var ERRORCLASS = "error";
7
8
function wordRegexp(words) {
9
return new RegExp("^((" + words.join(")|(") + "))\\b");
10
}
11
12
var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?)/;
13
var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
14
var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
15
var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
16
17
var wordOperators = wordRegexp(["and", "or", "not",
18
"is", "isnt", "in",
19
"instanceof", "typeof"]);
20
var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
21
"switch", "try", "catch", "finally", "class"];
22
var commonKeywords = ["break", "by", "continue", "debugger", "delete",
23
"do", "in", "of", "new", "return", "then",
24
"this", "throw", "when", "until"];
25
26
var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
27
28
indentKeywords = wordRegexp(indentKeywords);
29
30
31
var stringPrefixes = /^('{3}|\"{3}|['\"])/;
32
var regexPrefixes = /^(\/{3}|\/)/;
33
var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
34
var constants = wordRegexp(commonConstants);
35
36
// Tokenizers
37
function tokenBase(stream, state) {
38
// Handle scope changes
39
if (stream.sol()) {
40
if (state.scope.align === null) state.scope.align = false;
41
var scopeOffset = state.scope.offset;
42
if (stream.eatSpace()) {
43
var lineOffset = stream.indentation();
44
if (lineOffset > scopeOffset && state.scope.type == "coffee") {
45
return "indent";
46
} else if (lineOffset < scopeOffset) {
47
return "dedent";
48
}
49
return null;
50
} else {
51
if (scopeOffset > 0) {
52
dedent(stream, state);
53
}
54
}
55
}
56
if (stream.eatSpace()) {
57
return null;
58
}
59
60
var ch = stream.peek();
61
62
// Handle docco title comment (single line)
63
if (stream.match("####")) {
64
stream.skipToEnd();
65
return "comment";
66
}
67
68
// Handle multi line comments
69
if (stream.match("###")) {
70
state.tokenize = longComment;
71
return state.tokenize(stream, state);
72
}
73
74
// Single line comment
75
if (ch === "#") {
76
stream.skipToEnd();
77
return "comment";
78
}
79
80
// Handle number literals
81
if (stream.match(/^-?[0-9\.]/, false)) {
82
var floatLiteral = false;
83
// Floats
84
if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
85
floatLiteral = true;
86
}
87
if (stream.match(/^-?\d+\.\d*/)) {
88
floatLiteral = true;
89
}
90
if (stream.match(/^-?\.\d+/)) {
91
floatLiteral = true;
92
}
93
94
if (floatLiteral) {
95
// prevent from getting extra . on 1..
96
if (stream.peek() == "."){
97
stream.backUp(1);
98
}
99
return "number";
100
}
101
// Integers
102
var intLiteral = false;
103
// Hex
104
if (stream.match(/^-?0x[0-9a-f]+/i)) {
105
intLiteral = true;
106
}
107
// Decimal
108
if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
109
intLiteral = true;
110
}
111
// Zero by itself with no other piece of number.
112
if (stream.match(/^-?0(?![\dx])/i)) {
113
intLiteral = true;
114
}
115
if (intLiteral) {
116
return "number";
117
}
118
}
119
120
// Handle strings
121
if (stream.match(stringPrefixes)) {
122
state.tokenize = tokenFactory(stream.current(), false, "string");
123
return state.tokenize(stream, state);
124
}
125
// Handle regex literals
126
if (stream.match(regexPrefixes)) {
127
if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
128
state.tokenize = tokenFactory(stream.current(), true, "string-2");
129
return state.tokenize(stream, state);
130
} else {
131
stream.backUp(1);
132
}
133
}
134
135
// Handle operators and delimiters
136
if (stream.match(operators) || stream.match(wordOperators)) {
137
return "operator";
138
}
139
if (stream.match(delimiters)) {
140
return "punctuation";
141
}
142
143
if (stream.match(constants)) {
144
return "atom";
145
}
146
147
if (stream.match(keywords)) {
148
return "keyword";
149
}
150
151
if (stream.match(identifiers)) {
152
return "variable";
153
}
154
155
if (stream.match(properties)) {
156
return "property";
157
}
158
159
// Handle non-detected items
160
stream.next();
161
return ERRORCLASS;
162
}
163
164
function tokenFactory(delimiter, singleline, outclass) {
165
return function(stream, state) {
166
while (!stream.eol()) {
167
stream.eatWhile(/[^'"\/\\]/);
168
if (stream.eat("\\")) {
169
stream.next();
170
if (singleline && stream.eol()) {
171
return outclass;
172
}
173
} else if (stream.match(delimiter)) {
174
state.tokenize = tokenBase;
175
return outclass;
176
} else {
177
stream.eat(/['"\/]/);
178
}
179
}
180
if (singleline) {
181
if (conf.mode.singleLineStringErrors) {
182
outclass = ERRORCLASS;
183
} else {
184
state.tokenize = tokenBase;
185
}
186
}
187
return outclass;
188
};
189
}
190
191
function longComment(stream, state) {
192
while (!stream.eol()) {
193
stream.eatWhile(/[^#]/);
194
if (stream.match("###")) {
195
state.tokenize = tokenBase;
196
break;
197
}
198
stream.eatWhile("#");
199
}
200
return "comment";
201
}
202
203
function indent(stream, state, type) {
204
type = type || "coffee";
205
var offset = 0, align = false, alignOffset = null;
206
for (var scope = state.scope; scope; scope = scope.prev) {
207
if (scope.type === "coffee") {
208
offset = scope.offset + conf.indentUnit;
209
break;
210
}
211
}
212
if (type !== "coffee") {
213
align = null;
214
alignOffset = stream.column() + stream.current().length;
215
} else if (state.scope.align) {
216
state.scope.align = false;
217
}
218
state.scope = {
219
offset: offset,
220
type: type,
221
prev: state.scope,
222
align: align,
223
alignOffset: alignOffset
224
};
225
}
226
227
function dedent(stream, state) {
228
if (!state.scope.prev) return;
229
if (state.scope.type === "coffee") {
230
var _indent = stream.indentation();
231
var matched = false;
232
for (var scope = state.scope; scope; scope = scope.prev) {
233
if (_indent === scope.offset) {
234
matched = true;
235
break;
236
}
237
}
238
if (!matched) {
239
return true;
240
}
241
while (state.scope.prev && state.scope.offset !== _indent) {
242
state.scope = state.scope.prev;
243
}
244
return false;
245
} else {
246
state.scope = state.scope.prev;
247
return false;
248
}
249
}
250
251
function tokenLexer(stream, state) {
252
var style = state.tokenize(stream, state);
253
var current = stream.current();
254
255
// Handle "." connected identifiers
256
if (current === ".") {
257
style = state.tokenize(stream, state);
258
current = stream.current();
259
if (/^\.[\w$]+$/.test(current)) {
260
return "variable";
261
} else {
262
return ERRORCLASS;
263
}
264
}
265
266
// Handle scope changes.
267
if (current === "return") {
268
state.dedent += 1;
269
}
270
if (((current === "->" || current === "=>") &&
271
!state.lambda &&
272
!stream.peek())
273
|| style === "indent") {
274
indent(stream, state);
275
}
276
var delimiter_index = "[({".indexOf(current);
277
if (delimiter_index !== -1) {
278
indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
279
}
280
if (indentKeywords.exec(current)){
281
indent(stream, state);
282
}
283
if (current == "then"){
284
dedent(stream, state);
285
}
286
287
288
if (style === "dedent") {
289
if (dedent(stream, state)) {
290
return ERRORCLASS;
291
}
292
}
293
delimiter_index = "])}".indexOf(current);
294
if (delimiter_index !== -1) {
295
while (state.scope.type == "coffee" && state.scope.prev)
296
state.scope = state.scope.prev;
297
if (state.scope.type == current)
298
state.scope = state.scope.prev;
299
}
300
if (state.dedent > 0 && stream.eol() && state.scope.type == "coffee") {
301
if (state.scope.prev) state.scope = state.scope.prev;
302
state.dedent -= 1;
303
}
304
305
return style;
306
}
307
308
var external = {
309
startState: function(basecolumn) {
310
return {
311
tokenize: tokenBase,
312
scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
313
lastToken: null,
314
lambda: false,
315
dedent: 0
316
};
317
},
318
319
token: function(stream, state) {
320
var fillAlign = state.scope.align === null && state.scope;
321
if (fillAlign && stream.sol()) fillAlign.align = false;
322
323
var style = tokenLexer(stream, state);
324
if (fillAlign && style && style != "comment") fillAlign.align = true;
325
326
state.lastToken = {style:style, content: stream.current()};
327
328
if (stream.eol() && stream.lambda) {
329
state.lambda = false;
330
}
331
332
return style;
333
},
334
335
indent: function(state, text) {
336
if (state.tokenize != tokenBase) return 0;
337
var scope = state.scope;
338
var closer = text && "])}".indexOf(text.charAt(0)) > -1;
339
if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
340
var closes = closer && scope.type === text.charAt(0);
341
if (scope.align)
342
return scope.alignOffset - (closes ? 1 : 0);
343
else
344
return (closes ? scope.prev : scope).offset;
345
},
346
347
lineComment: "#",
348
fold: "indent"
349
};
350
return external;
351
});
352
353
CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
354
355