Added setup files.
[nit.git] / contrib / online_ide / setup / mode-nit.js
1 define('ace/mode/nit', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/matching_brace_outdent', 'ace/mode/behaviour/cstyle', 'ace/mode/nit_highlight_rules'], function(require, exports, module) {
2
3
4 var oop = require("../lib/oop");
5 var TextMode = require("./text").Mode;
6 var Tokenizer = require("../tokenizer").Tokenizer;
7 var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
8 var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
9 var NitHighlightRules = require("./nit_highlight_rules").NitHighlightRules;
10
11 var Mode = function() {
12 this.HighlightRules = NitHighlightRules;
13 this.$outdent = new MatchingBraceOutdent();
14 this.$behaviour = new CstyleBehaviour();
15 };
16 oop.inherits(Mode, TextMode);
17
18 (function() {
19 this.lineCommentStart = "#";
20 this.getNextLineIndent = function(state, line, tab) {
21 var indent = this.$getIndent(line);
22
23 var tokenizedLine = this.getTokenizer().getLineTokens(line, state);
24 var tokens = tokenizedLine.tokens;
25
26 if (tokens.length && tokens[tokens.length-1].type == "comment") {
27 return indent;
28 }
29
30 if (state == "start") {
31 var match = line.match(/(^class| class | if | else | else|do$)/);
32 if (match) {
33 indent += tab + tab;
34 }
35 }
36 return indent;
37 };
38 this.checkOutdent = function(state, line, input) {
39 return this.$outdent.checkOutdent(line, input);
40 };
41 this.autoOutdent = function(state, doc, row) {
42 this.$outdent.autoOutdent(doc, row);
43 };
44 this.createWorker = function(session) {
45 return null;
46 };
47
48 this.$id = "ace/mode/nit";
49 }).call(Mode.prototype);
50
51 exports.Mode = Mode;
52 });
53
54 define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
55
56
57 var Range = require("../range").Range;
58
59 var MatchingBraceOutdent = function() {};
60
61 (function() {
62
63 this.checkOutdent = function(line, input) {
64 if (! /^\s+$/.test(line))
65 return false;
66
67 return /^\s*\}/.test(input);
68 };
69
70 this.autoOutdent = function(doc, row) {
71 var line = doc.getLine(row);
72 var match = line.match(/^(\s*\})/);
73
74 if (!match) return 0;
75
76 var column = match[1].length;
77 var openBracePos = doc.findMatchingBracket({row: row, column: column});
78
79 if (!openBracePos || openBracePos.row == row) return 0;
80
81 var indent = this.$getIndent(doc.getLine(openBracePos.row));
82 doc.replace(new Range(row, 0, row, column-1), indent);
83 };
84
85 this.$getIndent = function(line) {
86 return line.match(/^\s*/)[0];
87 };
88
89 }).call(MatchingBraceOutdent.prototype);
90
91 exports.MatchingBraceOutdent = MatchingBraceOutdent;
92 });
93
94 define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator', 'ace/lib/lang'], function(require, exports, module) {
95
96
97 var oop = require("../../lib/oop");
98 var Behaviour = require("../behaviour").Behaviour;
99 var TokenIterator = require("../../token_iterator").TokenIterator;
100 var lang = require("../../lib/lang");
101
102 var SAFE_INSERT_IN_TOKENS =
103 ["text", "paren.rparen", "punctuation.operator"];
104 var SAFE_INSERT_BEFORE_TOKENS =
105 ["text", "paren.rparen", "punctuation.operator", "comment"];
106
107
108 var autoInsertedBrackets = 0;
109 var autoInsertedRow = -1;
110 var autoInsertedLineEnd = "";
111 var maybeInsertedBrackets = 0;
112 var maybeInsertedRow = -1;
113 var maybeInsertedLineStart = "";
114 var maybeInsertedLineEnd = "";
115
116 var CstyleBehaviour = function () {
117
118 CstyleBehaviour.isSaneInsertion = function(editor, session) {
119 var cursor = editor.getCursorPosition();
120 var iterator = new TokenIterator(session, cursor.row, cursor.column);
121 if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
122 var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
123 if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
124 return false;
125 }
126 iterator.stepForward();
127 return iterator.getCurrentTokenRow() !== cursor.row ||
128 this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
129 };
130
131 CstyleBehaviour.$matchTokenType = function(token, types) {
132 return types.indexOf(token.type || token) > -1;
133 };
134
135 CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) {
136 var cursor = editor.getCursorPosition();
137 var line = session.doc.getLine(cursor.row);
138 if (!this.isAutoInsertedClosing(cursor, line, autoInsertedLineEnd[0]))
139 autoInsertedBrackets = 0;
140 autoInsertedRow = cursor.row;
141 autoInsertedLineEnd = bracket + line.substr(cursor.column);
142 autoInsertedBrackets++;
143 };
144
145 CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
146 var cursor = editor.getCursorPosition();
147 var line = session.doc.getLine(cursor.row);
148 if (!this.isMaybeInsertedClosing(cursor, line))
149 maybeInsertedBrackets = 0;
150 maybeInsertedRow = cursor.row;
151 maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
152 maybeInsertedLineEnd = line.substr(cursor.column);
153 maybeInsertedBrackets++;
154 };
155
156 CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
157 return autoInsertedBrackets > 0 &&
158 cursor.row === autoInsertedRow &&
159 bracket === autoInsertedLineEnd[0] &&
160 line.substr(cursor.column) === autoInsertedLineEnd;
161 };
162
163 CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
164 return maybeInsertedBrackets > 0 &&
165 cursor.row === maybeInsertedRow &&
166 line.substr(cursor.column) === maybeInsertedLineEnd &&
167 line.substr(0, cursor.column) == maybeInsertedLineStart;
168 };
169
170 CstyleBehaviour.popAutoInsertedClosing = function() {
171 autoInsertedLineEnd = autoInsertedLineEnd.substr(1);
172 autoInsertedBrackets--;
173 };
174
175 CstyleBehaviour.clearMaybeInsertedClosing = function() {
176 maybeInsertedBrackets = 0;
177 maybeInsertedRow = -1;
178 };
179
180 this.add("braces", "insertion", function (state, action, editor, session, text) {
181 var cursor = editor.getCursorPosition();
182 var line = session.doc.getLine(cursor.row);
183 if (text == '{') {
184 var selection = editor.getSelectionRange();
185 var selected = session.doc.getTextRange(selection);
186 if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) {
187 return {
188 text: '{' + selected + '}',
189 selection: false
190 };
191 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
192 if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) {
193 CstyleBehaviour.recordAutoInsert(editor, session, "}");
194 return {
195 text: '{}',
196 selection: [1, 1]
197 };
198 } else {
199 CstyleBehaviour.recordMaybeInsert(editor, session, "{");
200 return {
201 text: '{',
202 selection: [1, 1]
203 };
204 }
205 }
206 } else if (text == '}') {
207 var rightChar = line.substring(cursor.column, cursor.column + 1);
208 if (rightChar == '}') {
209 var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
210 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
211 CstyleBehaviour.popAutoInsertedClosing();
212 return {
213 text: '',
214 selection: [1, 1]
215 };
216 }
217 }
218 } else if (text == "\n" || text == "\r\n") {
219 var closing = "";
220 if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
221 closing = lang.stringRepeat("}", maybeInsertedBrackets);
222 CstyleBehaviour.clearMaybeInsertedClosing();
223 }
224 var rightChar = line.substring(cursor.column, cursor.column + 1);
225 if (rightChar === '}') {
226 var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');
227 if (!openBracePos)
228 return null;
229 var next_indent = this.$getIndent(session.getLine(openBracePos.row));
230 } else if (closing) {
231 var next_indent = this.$getIndent(line);
232 } else {
233 return;
234 }
235 var indent = next_indent + session.getTabString();
236
237 return {
238 text: '\n' + indent + '\n' + next_indent + closing,
239 selection: [1, indent.length, 1, indent.length]
240 };
241 } else {
242 CstyleBehaviour.clearMaybeInsertedClosing();
243 }
244 });
245
246 this.add("braces", "deletion", function (state, action, editor, session, range) {
247 var selected = session.doc.getTextRange(range);
248 if (!range.isMultiLine() && selected == '{') {
249 var line = session.doc.getLine(range.start.row);
250 var rightChar = line.substring(range.end.column, range.end.column + 1);
251 if (rightChar == '}') {
252 range.end.column++;
253 return range;
254 } else {
255 maybeInsertedBrackets--;
256 }
257 }
258 });
259
260 this.add("parens", "insertion", function (state, action, editor, session, text) {
261 if (text == '(') {
262 var selection = editor.getSelectionRange();
263 var selected = session.doc.getTextRange(selection);
264 if (selected !== "" && editor.getWrapBehavioursEnabled()) {
265 return {
266 text: '(' + selected + ')',
267 selection: false
268 };
269 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
270 CstyleBehaviour.recordAutoInsert(editor, session, ")");
271 return {
272 text: '()',
273 selection: [1, 1]
274 };
275 }
276 } else if (text == ')') {
277 var cursor = editor.getCursorPosition();
278 var line = session.doc.getLine(cursor.row);
279 var rightChar = line.substring(cursor.column, cursor.column + 1);
280 if (rightChar == ')') {
281 var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
282 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
283 CstyleBehaviour.popAutoInsertedClosing();
284 return {
285 text: '',
286 selection: [1, 1]
287 };
288 }
289 }
290 }
291 });
292
293 this.add("parens", "deletion", function (state, action, editor, session, range) {
294 var selected = session.doc.getTextRange(range);
295 if (!range.isMultiLine() && selected == '(') {
296 var line = session.doc.getLine(range.start.row);
297 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
298 if (rightChar == ')') {
299 range.end.column++;
300 return range;
301 }
302 }
303 });
304
305 this.add("brackets", "insertion", function (state, action, editor, session, text) {
306 if (text == '[') {
307 var selection = editor.getSelectionRange();
308 var selected = session.doc.getTextRange(selection);
309 if (selected !== "" && editor.getWrapBehavioursEnabled()) {
310 return {
311 text: '[' + selected + ']',
312 selection: false
313 };
314 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
315 CstyleBehaviour.recordAutoInsert(editor, session, "]");
316 return {
317 text: '[]',
318 selection: [1, 1]
319 };
320 }
321 } else if (text == ']') {
322 var cursor = editor.getCursorPosition();
323 var line = session.doc.getLine(cursor.row);
324 var rightChar = line.substring(cursor.column, cursor.column + 1);
325 if (rightChar == ']') {
326 var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
327 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
328 CstyleBehaviour.popAutoInsertedClosing();
329 return {
330 text: '',
331 selection: [1, 1]
332 };
333 }
334 }
335 }
336 });
337
338 this.add("brackets", "deletion", function (state, action, editor, session, range) {
339 var selected = session.doc.getTextRange(range);
340 if (!range.isMultiLine() && selected == '[') {
341 var line = session.doc.getLine(range.start.row);
342 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
343 if (rightChar == ']') {
344 range.end.column++;
345 return range;
346 }
347 }
348 });
349
350 this.add("string_dquotes", "insertion", function (state, action, editor, session, text) {
351 if (text == '"' || text == "'") {
352 var quote = text;
353 var selection = editor.getSelectionRange();
354 var selected = session.doc.getTextRange(selection);
355 if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
356 return {
357 text: quote + selected + quote,
358 selection: false
359 };
360 } else {
361 var cursor = editor.getCursorPosition();
362 var line = session.doc.getLine(cursor.row);
363 var leftChar = line.substring(cursor.column-1, cursor.column);
364 if (leftChar == '\\') {
365 return null;
366 }
367 var tokens = session.getTokens(selection.start.row);
368 var col = 0, token;
369 var quotepos = -1; // Track whether we're inside an open quote.
370
371 for (var x = 0; x < tokens.length; x++) {
372 token = tokens[x];
373 if (token.type == "string") {
374 quotepos = -1;
375 } else if (quotepos < 0) {
376 quotepos = token.value.indexOf(quote);
377 }
378 if ((token.value.length + col) > selection.start.column) {
379 break;
380 }
381 col += tokens[x].value.length;
382 }
383 if (!token || (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length+col-1) && token.value.lastIndexOf(quote) === token.value.length-1)))) {
384 if (!CstyleBehaviour.isSaneInsertion(editor, session))
385 return;
386 return {
387 text: quote + quote,
388 selection: [1,1]
389 };
390 } else if (token && token.type === "string") {
391 var rightChar = line.substring(cursor.column, cursor.column + 1);
392 if (rightChar == quote) {
393 return {
394 text: '',
395 selection: [1, 1]
396 };
397 }
398 }
399 }
400 }
401 });
402
403 this.add("string_dquotes", "deletion", function (state, action, editor, session, range) {
404 var selected = session.doc.getTextRange(range);
405 if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
406 var line = session.doc.getLine(range.start.row);
407 var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
408 if (rightChar == selected) {
409 range.end.column++;
410 return range;
411 }
412 }
413 });
414
415 };
416
417 oop.inherits(CstyleBehaviour, Behaviour);
418
419 exports.CstyleBehaviour = CstyleBehaviour;
420 });
421 define('ace/mode/nit_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/doc_comment_highlight_rules', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
422
423
424 var oop = require("../lib/oop");
425 var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
426 var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
427
428 var NitHighlightRules = function() {
429
430 var keywords = (
431 "package|module|import|class|abstract|interface|universal|enum|end|fun|" +
432 "type|init|redef|is|do|readable|writable|var|intern|extern|protected|private|" +
433 "intrude|if|then|else|while|loop|for|in|and|or|not|implies|return|continue|" +
434 "break|abort|assert|new|isa|once|super|self|true|false|null|as|nullable|isset|label|__debug__"
435 );
436
437 var keywordMapper = this.createKeywordMapper({
438 "keyword": keywords,
439 "variable.language": "self",
440 "constant.language": "null|true|false"
441 }, "identifier");
442 this.$rules = {
443 "start" : [
444 {
445 token : "comment",
446 regex : "#.*$"
447 },
448 {
449 token : "support.class",
450 regex : /[A-Z]{1}[a-z]+/
451 },
452 DocCommentHighlightRules.getStartRule("doc-start"),
453 {
454 token : "string.regexp",
455 regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"
456 }, {
457 token : "string", // character
458 regex : /'(?:.|\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n]))'/
459 }, {
460 token : "string", start : '"', end : '"|$', next: [
461 {token: "constant.language.escape", regex: /\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n])/},
462 {token: "invalid", regex: /\\./}
463 ]
464 }, {
465 token : "string", start : '@"', end : '"', next:[
466 {token: "constant.language.escape", regex: '""'}
467 ]
468 }, {
469 token : "constant.numeric", // hex
470 regex : "0[xX][0-9a-fA-F]+\\b"
471 }, {
472 token : "constant.numeric", // float
473 regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
474 }, {
475 token : "constant.language.boolean",
476 regex : "(?:true|false)\\b"
477 }, {
478 token : keywordMapper,
479 regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
480 }, {
481 token : "keyword.operator",
482 regex : "@|!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\::|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"
483 }, {
484 token : "keyword",
485 regex : "^\\s*#(if|else|elif|endif|define|undef|warning|error|line|region|endregion|pragma)"
486 }, {
487 token : "punctuation.operator",
488 regex : "\\?|\\:|\\,|\\;|\\."
489 }, {
490 token : "paren.lparen",
491 regex : "[[({]"
492 }, {
493 token : "paren.rparen",
494 regex : "[\\])}]"
495 }, {
496 token : "text",
497 regex : "\\s+"
498 }
499 ]
500 };
501 this.embedRules(DocCommentHighlightRules, "doc-",
502 [ DocCommentHighlightRules.getEndRule("start") ]);
503 this.normalizeRules();
504 };
505
506 oop.inherits(NitHighlightRules, TextHighlightRules);
507
508 exports.NitHighlightRules = NitHighlightRules;
509
510 });
511
512 define('ace/mode/doc_comment_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
513
514
515 var oop = require("../lib/oop");
516 var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
517
518 var DocCommentHighlightRules = function() {
519
520 this.$rules = {
521 "start" : [ {
522 token : "comment.doc.tag",
523 regex : "@[\\w\\d_]+" // TODO: fix email addresses
524 }, {
525 token : "comment.doc.tag",
526 regex : "\\bTODO\\b"
527 }, {
528 defaultToken : "comment.doc"
529 }]
530 };
531 };
532
533 oop.inherits(DocCommentHighlightRules, TextHighlightRules);
534
535 DocCommentHighlightRules.getStartRule = function(start) {
536 return {
537 token : "comment.doc", // doc comment
538 regex : "\\/\\*(?=\\*)",
539 next : start
540 };
541 };
542
543 DocCommentHighlightRules.getEndRule = function (start) {
544 return {
545 token : "comment.doc", // closing comment
546 regex : "\\*\\/",
547 next : start
548 };
549 };
550
551
552 exports.DocCommentHighlightRules = DocCommentHighlightRules;
553
554 });