/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk

« back to all changes in this revision

Viewing changes to js/ace/mode-scad.js

  • Committer: Gustav Hatvigsson
  • Date: 2013-05-31 06:15:46 UTC
  • mfrom: (90.1.20 lenasys2)
  • Revision ID: gustav.hartvigsson@gmail.com-20130531061546-vj8z28sq375kvghq
Merged Jonsson:s changes:
Fixed the layout on cms index so the arrows and dots marks expanded objects.
Fixed so the course content is sorted by course occasion and not by name

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Distributed under the BSD license:
 
3
 *
 
4
 * Copyright (c) 2010, Ajax.org B.V.
 
5
 * All rights reserved.
 
6
 * 
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted provided that the following conditions are met:
 
9
 *     * Redistributions of source code must retain the above copyright
 
10
 *       notice, this list of conditions and the following disclaimer.
 
11
 *     * Redistributions in binary form must reproduce the above copyright
 
12
 *       notice, this list of conditions and the following disclaimer in the
 
13
 *       documentation and/or other materials provided with the distribution.
 
14
 *     * Neither the name of Ajax.org B.V. nor the
 
15
 *       names of its contributors may be used to endorse or promote products
 
16
 *       derived from this software without specific prior written permission.
 
17
 * 
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
20
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
21
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 
22
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
23
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
25
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
28
 *
 
29
 * ***** END LICENSE BLOCK ***** */
 
30
 
 
31
define('ace/mode/scad', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/scad_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/range', 'ace/mode/behaviour/cstyle', 'ace/mode/folding/cstyle'], function(require, exports, module) {
 
32
 
 
33
 
 
34
var oop = require("../lib/oop");
 
35
var TextMode = require("./text").Mode;
 
36
var Tokenizer = require("../tokenizer").Tokenizer;
 
37
var scadHighlightRules = require("./scad_highlight_rules").scadHighlightRules;
 
38
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
 
39
var Range = require("../range").Range;
 
40
var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
 
41
var CStyleFoldMode = require("./folding/cstyle").FoldMode;
 
42
 
 
43
var Mode = function() {
 
44
    this.$tokenizer = new Tokenizer(new scadHighlightRules().getRules());
 
45
    this.$outdent = new MatchingBraceOutdent();
 
46
    this.$behaviour = new CstyleBehaviour();
 
47
    this.foldingRules = new CStyleFoldMode();
 
48
};
 
49
oop.inherits(Mode, TextMode);
 
50
 
 
51
(function() {
 
52
 
 
53
    this.lineCommentStart = "//";
 
54
    this.blockComment = {start: "/*", end: "*/"};
 
55
 
 
56
    this.getNextLineIndent = function(state, line, tab) {
 
57
        var indent = this.$getIndent(line);
 
58
 
 
59
        var tokenizedLine = this.$tokenizer.getLineTokens(line, state);
 
60
        var tokens = tokenizedLine.tokens;
 
61
        var endState = tokenizedLine.state;
 
62
 
 
63
        if (tokens.length && tokens[tokens.length-1].type == "comment") {
 
64
            return indent;
 
65
        }
 
66
 
 
67
        if (state == "start") {
 
68
            var match = line.match(/^.*[\{\(\[]\s*$/);
 
69
            if (match) {
 
70
                indent += tab;
 
71
            }
 
72
        } else if (state == "doc-start") {
 
73
            if (endState == "start") {
 
74
                return "";
 
75
            }
 
76
            var match = line.match(/^\s*(\/?)\*/);
 
77
            if (match) {
 
78
                if (match[1]) {
 
79
                    indent += " ";
 
80
                }
 
81
                indent += "* ";
 
82
            }
 
83
        }
 
84
 
 
85
        return indent;
 
86
    };
 
87
 
 
88
    this.checkOutdent = function(state, line, input) {
 
89
        return this.$outdent.checkOutdent(line, input);
 
90
    };
 
91
 
 
92
    this.autoOutdent = function(state, doc, row) {
 
93
        this.$outdent.autoOutdent(doc, row);
 
94
    };
 
95
 
 
96
}).call(Mode.prototype);
 
97
 
 
98
exports.Mode = Mode;
 
99
});
 
100
 
 
101
define('ace/mode/scad_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/mode/doc_comment_highlight_rules', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
 
102
 
 
103
 
 
104
var oop = require("../lib/oop");
 
105
var lang = require("../lib/lang");
 
106
var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
 
107
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
 
108
 
 
109
var scadHighlightRules = function() {
 
110
    var keywordMapper = this.createKeywordMapper({
 
111
        "variable.language": "this",
 
112
        "keyword": "module|if|else|for",
 
113
        "constant.language": "NULL"
 
114
    }, "identifier");
 
115
 
 
116
    this.$rules = {
 
117
        "start" : [
 
118
            {
 
119
                token : "comment",
 
120
                regex : "\\/\\/.*$"
 
121
            },
 
122
            DocCommentHighlightRules.getStartRule("start"),
 
123
            {
 
124
                token : "comment", // multi line comment
 
125
                regex : "\\/\\*",
 
126
                next : "comment"
 
127
            }, {
 
128
                token : "string", // single line
 
129
                regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
 
130
            }, {
 
131
                token : "string", // multi line string start
 
132
                regex : '["].*\\\\$',
 
133
                next : "qqstring"
 
134
            }, {
 
135
                token : "string", // single line
 
136
                regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
 
137
            }, {
 
138
                token : "string", // multi line string start
 
139
                regex : "['].*\\\\$",
 
140
                next : "qstring"
 
141
            }, {
 
142
                token : "constant.numeric", // hex
 
143
                regex : "0[xX][0-9a-fA-F]+\\b"
 
144
            }, {
 
145
                token : "constant.numeric", // float
 
146
                regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
 
147
            }, {
 
148
              token : "constant", // <CONSTANT>
 
149
              regex : "<[a-zA-Z0-9.]+>"
 
150
            }, {
 
151
              token : "keyword", // pre-compiler directivs
 
152
              regex : "(?:use|include)"
 
153
            }, {
 
154
                token : keywordMapper,
 
155
                regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
 
156
            }, {
 
157
                token : "keyword.operator",
 
158
                regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"
 
159
            }, {
 
160
                token : "paren.lparen",
 
161
                regex : "[[({]"
 
162
            }, {
 
163
                token : "paren.rparen",
 
164
                regex : "[\\])}]"
 
165
            }, {
 
166
                token : "text",
 
167
                regex : "\\s+"
 
168
            }
 
169
        ],
 
170
        "comment" : [
 
171
            {
 
172
                token : "comment", // closing comment
 
173
                regex : ".*?\\*\\/",
 
174
                next : "start"
 
175
            }, {
 
176
                token : "comment", // comment spanning whole line
 
177
                regex : ".+"
 
178
            }
 
179
        ],
 
180
        "qqstring" : [
 
181
            {
 
182
                token : "string",
 
183
                regex : '(?:(?:\\\\.)|(?:[^"\\\\]))*?"',
 
184
                next : "start"
 
185
            }, {
 
186
                token : "string",
 
187
                regex : '.+'
 
188
            }
 
189
        ],
 
190
        "qstring" : [
 
191
            {
 
192
                token : "string",
 
193
                regex : "(?:(?:\\\\.)|(?:[^'\\\\]))*?'",
 
194
                next : "start"
 
195
            }, {
 
196
                token : "string",
 
197
                regex : '.+'
 
198
            }
 
199
        ]
 
200
    };
 
201
    
 
202
    this.embedRules(DocCommentHighlightRules, "doc-",
 
203
        [ DocCommentHighlightRules.getEndRule("start") ]);
 
204
};
 
205
 
 
206
oop.inherits(scadHighlightRules, TextHighlightRules);
 
207
 
 
208
exports.scadHighlightRules = scadHighlightRules;
 
209
});
 
210
 
 
211
define('ace/mode/doc_comment_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
 
212
 
 
213
 
 
214
var oop = require("../lib/oop");
 
215
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
 
216
 
 
217
var DocCommentHighlightRules = function() {
 
218
 
 
219
    this.$rules = {
 
220
        "start" : [ {
 
221
            token : "comment.doc.tag",
 
222
            regex : "@[\\w\\d_]+" // TODO: fix email addresses
 
223
        }, {
 
224
            token : "comment.doc.tag",
 
225
            regex : "\\bTODO\\b"
 
226
        }, {
 
227
            defaultToken : "comment.doc"
 
228
        }]
 
229
    };
 
230
};
 
231
 
 
232
oop.inherits(DocCommentHighlightRules, TextHighlightRules);
 
233
 
 
234
DocCommentHighlightRules.getStartRule = function(start) {
 
235
    return {
 
236
        token : "comment.doc", // doc comment
 
237
        regex : "\\/\\*(?=\\*)",
 
238
        next  : start
 
239
    };
 
240
};
 
241
 
 
242
DocCommentHighlightRules.getEndRule = function (start) {
 
243
    return {
 
244
        token : "comment.doc", // closing comment
 
245
        regex : "\\*\\/",
 
246
        next  : start
 
247
    };
 
248
};
 
249
 
 
250
 
 
251
exports.DocCommentHighlightRules = DocCommentHighlightRules;
 
252
 
 
253
});
 
254
 
 
255
define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
 
256
 
 
257
 
 
258
var Range = require("../range").Range;
 
259
 
 
260
var MatchingBraceOutdent = function() {};
 
261
 
 
262
(function() {
 
263
 
 
264
    this.checkOutdent = function(line, input) {
 
265
        if (! /^\s+$/.test(line))
 
266
            return false;
 
267
 
 
268
        return /^\s*\}/.test(input);
 
269
    };
 
270
 
 
271
    this.autoOutdent = function(doc, row) {
 
272
        var line = doc.getLine(row);
 
273
        var match = line.match(/^(\s*\})/);
 
274
 
 
275
        if (!match) return 0;
 
276
 
 
277
        var column = match[1].length;
 
278
        var openBracePos = doc.findMatchingBracket({row: row, column: column});
 
279
 
 
280
        if (!openBracePos || openBracePos.row == row) return 0;
 
281
 
 
282
        var indent = this.$getIndent(doc.getLine(openBracePos.row));
 
283
        doc.replace(new Range(row, 0, row, column-1), indent);
 
284
    };
 
285
 
 
286
    this.$getIndent = function(line) {
 
287
        return line.match(/^\s*/)[0];
 
288
    };
 
289
 
 
290
}).call(MatchingBraceOutdent.prototype);
 
291
 
 
292
exports.MatchingBraceOutdent = MatchingBraceOutdent;
 
293
});
 
294
 
 
295
define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator', 'ace/lib/lang'], function(require, exports, module) {
 
296
 
 
297
 
 
298
var oop = require("../../lib/oop");
 
299
var Behaviour = require("../behaviour").Behaviour;
 
300
var TokenIterator = require("../../token_iterator").TokenIterator;
 
301
var lang = require("../../lib/lang");
 
302
 
 
303
var SAFE_INSERT_IN_TOKENS =
 
304
    ["text", "paren.rparen", "punctuation.operator"];
 
305
var SAFE_INSERT_BEFORE_TOKENS =
 
306
    ["text", "paren.rparen", "punctuation.operator", "comment"];
 
307
 
 
308
 
 
309
var autoInsertedBrackets = 0;
 
310
var autoInsertedRow = -1;
 
311
var autoInsertedLineEnd = "";
 
312
var maybeInsertedBrackets = 0;
 
313
var maybeInsertedRow = -1;
 
314
var maybeInsertedLineStart = "";
 
315
var maybeInsertedLineEnd = "";
 
316
 
 
317
var CstyleBehaviour = function () {
 
318
    
 
319
    CstyleBehaviour.isSaneInsertion = function(editor, session) {
 
320
        var cursor = editor.getCursorPosition();
 
321
        var iterator = new TokenIterator(session, cursor.row, cursor.column);
 
322
        if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
 
323
            var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
 
324
            if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
 
325
                return false;
 
326
        }
 
327
        iterator.stepForward();
 
328
        return iterator.getCurrentTokenRow() !== cursor.row ||
 
329
            this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
 
330
    };
 
331
    
 
332
    CstyleBehaviour.$matchTokenType = function(token, types) {
 
333
        return types.indexOf(token.type || token) > -1;
 
334
    };
 
335
    
 
336
    CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) {
 
337
        var cursor = editor.getCursorPosition();
 
338
        var line = session.doc.getLine(cursor.row);
 
339
        if (!this.isAutoInsertedClosing(cursor, line, autoInsertedLineEnd[0]))
 
340
            autoInsertedBrackets = 0;
 
341
        autoInsertedRow = cursor.row;
 
342
        autoInsertedLineEnd = bracket + line.substr(cursor.column);
 
343
        autoInsertedBrackets++;
 
344
    };
 
345
    
 
346
    CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
 
347
        var cursor = editor.getCursorPosition();
 
348
        var line = session.doc.getLine(cursor.row);
 
349
        if (!this.isMaybeInsertedClosing(cursor, line))
 
350
            maybeInsertedBrackets = 0;
 
351
        maybeInsertedRow = cursor.row;
 
352
        maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
 
353
        maybeInsertedLineEnd = line.substr(cursor.column);
 
354
        maybeInsertedBrackets++;
 
355
    };
 
356
    
 
357
    CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
 
358
        return autoInsertedBrackets > 0 &&
 
359
            cursor.row === autoInsertedRow &&
 
360
            bracket === autoInsertedLineEnd[0] &&
 
361
            line.substr(cursor.column) === autoInsertedLineEnd;
 
362
    };
 
363
    
 
364
    CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
 
365
        return maybeInsertedBrackets > 0 &&
 
366
            cursor.row === maybeInsertedRow &&
 
367
            line.substr(cursor.column) === maybeInsertedLineEnd &&
 
368
            line.substr(0, cursor.column) == maybeInsertedLineStart;
 
369
    };
 
370
    
 
371
    CstyleBehaviour.popAutoInsertedClosing = function() {
 
372
        autoInsertedLineEnd = autoInsertedLineEnd.substr(1);
 
373
        autoInsertedBrackets--;
 
374
    };
 
375
    
 
376
    CstyleBehaviour.clearMaybeInsertedClosing = function() {
 
377
        maybeInsertedBrackets = 0;
 
378
        maybeInsertedRow = -1;
 
379
    };
 
380
 
 
381
    this.add("braces", "insertion", function (state, action, editor, session, text) {
 
382
        var cursor = editor.getCursorPosition();
 
383
        var line = session.doc.getLine(cursor.row);
 
384
        if (text == '{') {
 
385
            var selection = editor.getSelectionRange();
 
386
            var selected = session.doc.getTextRange(selection);
 
387
            if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) {
 
388
                return {
 
389
                    text: '{' + selected + '}',
 
390
                    selection: false
 
391
                };
 
392
            } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
 
393
                if (/[\]\}\)]/.test(line[cursor.column])) {
 
394
                    CstyleBehaviour.recordAutoInsert(editor, session, "}");
 
395
                    return {
 
396
                        text: '{}',
 
397
                        selection: [1, 1]
 
398
                    };
 
399
                } else {
 
400
                    CstyleBehaviour.recordMaybeInsert(editor, session, "{");
 
401
                    return {
 
402
                        text: '{',
 
403
                        selection: [1, 1]
 
404
                    };
 
405
                }
 
406
            }
 
407
        } else if (text == '}') {
 
408
            var rightChar = line.substring(cursor.column, cursor.column + 1);
 
409
            if (rightChar == '}') {
 
410
                var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
 
411
                if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
 
412
                    CstyleBehaviour.popAutoInsertedClosing();
 
413
                    return {
 
414
                        text: '',
 
415
                        selection: [1, 1]
 
416
                    };
 
417
                }
 
418
            }
 
419
        } else if (text == "\n" || text == "\r\n") {
 
420
            var closing = "";
 
421
            if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
 
422
                closing = lang.stringRepeat("}", maybeInsertedBrackets);
 
423
                CstyleBehaviour.clearMaybeInsertedClosing();
 
424
            }
 
425
            var rightChar = line.substring(cursor.column, cursor.column + 1);
 
426
            if (rightChar == '}' || closing !== "") {
 
427
                var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column}, '}');
 
428
                if (!openBracePos)
 
429
                     return null;
 
430
 
 
431
                var indent = this.getNextLineIndent(state, line.substring(0, cursor.column), session.getTabString());
 
432
                var next_indent = this.$getIndent(line);
 
433
 
 
434
                return {
 
435
                    text: '\n' + indent + '\n' + next_indent + closing,
 
436
                    selection: [1, indent.length, 1, indent.length]
 
437
                };
 
438
            }
 
439
        }
 
440
    });
 
441
 
 
442
    this.add("braces", "deletion", function (state, action, editor, session, range) {
 
443
        var selected = session.doc.getTextRange(range);
 
444
        if (!range.isMultiLine() && selected == '{') {
 
445
            var line = session.doc.getLine(range.start.row);
 
446
            var rightChar = line.substring(range.end.column, range.end.column + 1);
 
447
            if (rightChar == '}') {
 
448
                range.end.column++;
 
449
                return range;
 
450
            } else {
 
451
                maybeInsertedBrackets--;
 
452
            }
 
453
        }
 
454
    });
 
455
 
 
456
    this.add("parens", "insertion", function (state, action, editor, session, text) {
 
457
        if (text == '(') {
 
458
            var selection = editor.getSelectionRange();
 
459
            var selected = session.doc.getTextRange(selection);
 
460
            if (selected !== "" && editor.getWrapBehavioursEnabled()) {
 
461
                return {
 
462
                    text: '(' + selected + ')',
 
463
                    selection: false
 
464
                };
 
465
            } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
 
466
                CstyleBehaviour.recordAutoInsert(editor, session, ")");
 
467
                return {
 
468
                    text: '()',
 
469
                    selection: [1, 1]
 
470
                };
 
471
            }
 
472
        } else if (text == ')') {
 
473
            var cursor = editor.getCursorPosition();
 
474
            var line = session.doc.getLine(cursor.row);
 
475
            var rightChar = line.substring(cursor.column, cursor.column + 1);
 
476
            if (rightChar == ')') {
 
477
                var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
 
478
                if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
 
479
                    CstyleBehaviour.popAutoInsertedClosing();
 
480
                    return {
 
481
                        text: '',
 
482
                        selection: [1, 1]
 
483
                    };
 
484
                }
 
485
            }
 
486
        }
 
487
    });
 
488
 
 
489
    this.add("parens", "deletion", function (state, action, editor, session, range) {
 
490
        var selected = session.doc.getTextRange(range);
 
491
        if (!range.isMultiLine() && selected == '(') {
 
492
            var line = session.doc.getLine(range.start.row);
 
493
            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
 
494
            if (rightChar == ')') {
 
495
                range.end.column++;
 
496
                return range;
 
497
            }
 
498
        }
 
499
    });
 
500
 
 
501
    this.add("brackets", "insertion", function (state, action, editor, session, text) {
 
502
        if (text == '[') {
 
503
            var selection = editor.getSelectionRange();
 
504
            var selected = session.doc.getTextRange(selection);
 
505
            if (selected !== "" && editor.getWrapBehavioursEnabled()) {
 
506
                return {
 
507
                    text: '[' + selected + ']',
 
508
                    selection: false
 
509
                };
 
510
            } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
 
511
                CstyleBehaviour.recordAutoInsert(editor, session, "]");
 
512
                return {
 
513
                    text: '[]',
 
514
                    selection: [1, 1]
 
515
                };
 
516
            }
 
517
        } else if (text == ']') {
 
518
            var cursor = editor.getCursorPosition();
 
519
            var line = session.doc.getLine(cursor.row);
 
520
            var rightChar = line.substring(cursor.column, cursor.column + 1);
 
521
            if (rightChar == ']') {
 
522
                var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
 
523
                if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
 
524
                    CstyleBehaviour.popAutoInsertedClosing();
 
525
                    return {
 
526
                        text: '',
 
527
                        selection: [1, 1]
 
528
                    };
 
529
                }
 
530
            }
 
531
        }
 
532
    });
 
533
 
 
534
    this.add("brackets", "deletion", function (state, action, editor, session, range) {
 
535
        var selected = session.doc.getTextRange(range);
 
536
        if (!range.isMultiLine() && selected == '[') {
 
537
            var line = session.doc.getLine(range.start.row);
 
538
            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
 
539
            if (rightChar == ']') {
 
540
                range.end.column++;
 
541
                return range;
 
542
            }
 
543
        }
 
544
    });
 
545
 
 
546
    this.add("string_dquotes", "insertion", function (state, action, editor, session, text) {
 
547
        if (text == '"' || text == "'") {
 
548
            var quote = text;
 
549
            var selection = editor.getSelectionRange();
 
550
            var selected = session.doc.getTextRange(selection);
 
551
            if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
 
552
                return {
 
553
                    text: quote + selected + quote,
 
554
                    selection: false
 
555
                };
 
556
            } else {
 
557
                var cursor = editor.getCursorPosition();
 
558
                var line = session.doc.getLine(cursor.row);
 
559
                var leftChar = line.substring(cursor.column-1, cursor.column);
 
560
                if (leftChar == '\\') {
 
561
                    return null;
 
562
                }
 
563
                var tokens = session.getTokens(selection.start.row);
 
564
                var col = 0, token;
 
565
                var quotepos = -1; // Track whether we're inside an open quote.
 
566
 
 
567
                for (var x = 0; x < tokens.length; x++) {
 
568
                    token = tokens[x];
 
569
                    if (token.type == "string") {
 
570
                      quotepos = -1;
 
571
                    } else if (quotepos < 0) {
 
572
                      quotepos = token.value.indexOf(quote);
 
573
                    }
 
574
                    if ((token.value.length + col) > selection.start.column) {
 
575
                        break;
 
576
                    }
 
577
                    col += tokens[x].value.length;
 
578
                }
 
579
                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)))) {
 
580
                    if (!CstyleBehaviour.isSaneInsertion(editor, session))
 
581
                        return;
 
582
                    return {
 
583
                        text: quote + quote,
 
584
                        selection: [1,1]
 
585
                    };
 
586
                } else if (token && token.type === "string") {
 
587
                    var rightChar = line.substring(cursor.column, cursor.column + 1);
 
588
                    if (rightChar == quote) {
 
589
                        return {
 
590
                            text: '',
 
591
                            selection: [1, 1]
 
592
                        };
 
593
                    }
 
594
                }
 
595
            }
 
596
        }
 
597
    });
 
598
 
 
599
    this.add("string_dquotes", "deletion", function (state, action, editor, session, range) {
 
600
        var selected = session.doc.getTextRange(range);
 
601
        if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
 
602
            var line = session.doc.getLine(range.start.row);
 
603
            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
 
604
            if (rightChar == selected) {
 
605
                range.end.column++;
 
606
                return range;
 
607
            }
 
608
        }
 
609
    });
 
610
 
 
611
};
 
612
 
 
613
oop.inherits(CstyleBehaviour, Behaviour);
 
614
 
 
615
exports.CstyleBehaviour = CstyleBehaviour;
 
616
});
 
617
 
 
618
define('ace/mode/folding/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/range', 'ace/mode/folding/fold_mode'], function(require, exports, module) {
 
619
 
 
620
 
 
621
var oop = require("../../lib/oop");
 
622
var Range = require("../../range").Range;
 
623
var BaseFoldMode = require("./fold_mode").FoldMode;
 
624
 
 
625
var FoldMode = exports.FoldMode = function(commentRegex) {
 
626
    if (commentRegex) {
 
627
        this.foldingStartMarker = new RegExp(
 
628
            this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start)
 
629
        );
 
630
        this.foldingStopMarker = new RegExp(
 
631
            this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end)
 
632
        );
 
633
    }
 
634
};
 
635
oop.inherits(FoldMode, BaseFoldMode);
 
636
 
 
637
(function() {
 
638
 
 
639
    this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/;
 
640
    this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/;
 
641
 
 
642
    this.getFoldWidgetRange = function(session, foldStyle, row) {
 
643
        var line = session.getLine(row);
 
644
        var match = line.match(this.foldingStartMarker);
 
645
        if (match) {
 
646
            var i = match.index;
 
647
 
 
648
            if (match[1])
 
649
                return this.openingBracketBlock(session, match[1], row, i);
 
650
 
 
651
            return session.getCommentFoldRange(row, i + match[0].length, 1);
 
652
        }
 
653
 
 
654
        if (foldStyle !== "markbeginend")
 
655
            return;
 
656
 
 
657
        var match = line.match(this.foldingStopMarker);
 
658
        if (match) {
 
659
            var i = match.index + match[0].length;
 
660
 
 
661
            if (match[1])
 
662
                return this.closingBracketBlock(session, match[1], row, i);
 
663
 
 
664
            return session.getCommentFoldRange(row, i, -1);
 
665
        }
 
666
    };
 
667
 
 
668
}).call(FoldMode.prototype);
 
669
 
 
670
});