express_admin 1.4.8 → 1.4.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,843 @@
1
+ define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) {
2
+ "use strict";
3
+
4
+ var oop = require("../lib/oop");
5
+ var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
6
+ var constantOtherSymbol = exports.constantOtherSymbol = {
7
+ token : "constant.other.symbol.ruby", // symbol
8
+ regex : "[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"
9
+ };
10
+
11
+ var qString = exports.qString = {
12
+ token : "string", // single line
13
+ regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
14
+ };
15
+
16
+ var qqString = exports.qqString = {
17
+ token : "string", // single line
18
+ regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
19
+ };
20
+
21
+ var tString = exports.tString = {
22
+ token : "string", // backtick string
23
+ regex : "[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"
24
+ };
25
+
26
+ var constantNumericHex = exports.constantNumericHex = {
27
+ token : "constant.numeric", // hex
28
+ regex : "0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"
29
+ };
30
+
31
+ var constantNumericFloat = exports.constantNumericFloat = {
32
+ token : "constant.numeric", // float
33
+ regex : "[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"
34
+ };
35
+
36
+ var RubyHighlightRules = function() {
37
+
38
+ var builtinFunctions = (
39
+ "abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|" +
40
+ "assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|" +
41
+ "assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|" +
42
+ "assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|" +
43
+ "assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|" +
44
+ "assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|" +
45
+ "attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|" +
46
+ "caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|" +
47
+ "exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|" +
48
+ "gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|" +
49
+ "link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|" +
50
+ "p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|" +
51
+ "raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|" +
52
+ "set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|" +
53
+ "throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|" +
54
+ "render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|" +
55
+ "content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|" +
56
+ "fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|" +
57
+ "time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|" +
58
+ "select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|" +
59
+ "file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|" +
60
+ "protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|" +
61
+ "send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|" +
62
+ "validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|" +
63
+ "validates_inclusion_of|validates_numericality_of|validates_with|validates_each|" +
64
+ "authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|" +
65
+ "filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|" +
66
+ "translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|" +
67
+ "cache|expire_fragment|expire_cache_for|observe|cache_sweeper|" +
68
+ "has_many|has_one|belongs_to|has_and_belongs_to_many"
69
+ );
70
+
71
+ var keywords = (
72
+ "alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|" +
73
+ "__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|" +
74
+ "redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield"
75
+ );
76
+
77
+ var buildinConstants = (
78
+ "true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|" +
79
+ "RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING"
80
+ );
81
+
82
+ var builtinVariables = (
83
+ "\$DEBUG|\$defout|\$FILENAME|\$LOAD_PATH|\$SAFE|\$stdin|\$stdout|\$stderr|\$VERBOSE|" +
84
+ "$!|root_url|flash|session|cookies|params|request|response|logger|self"
85
+ );
86
+
87
+ var keywordMapper = this.$keywords = this.createKeywordMapper({
88
+ "keyword": keywords,
89
+ "constant.language": buildinConstants,
90
+ "variable.language": builtinVariables,
91
+ "support.function": builtinFunctions,
92
+ "invalid.deprecated": "debugger" // TODO is this a remnant from js mode?
93
+ }, "identifier");
94
+
95
+ this.$rules = {
96
+ "start" : [
97
+ {
98
+ token : "comment",
99
+ regex : "#.*$"
100
+ }, {
101
+ token : "comment", // multi line comment
102
+ regex : "^=begin(?:$|\\s.*$)",
103
+ next : "comment"
104
+ }, {
105
+ token : "string.regexp",
106
+ regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"
107
+ },
108
+
109
+ [{
110
+ regex: "[{}]", onMatch: function(val, state, stack) {
111
+ this.next = val == "{" ? this.nextState : "";
112
+ if (val == "{" && stack.length) {
113
+ stack.unshift("start", state);
114
+ return "paren.lparen";
115
+ }
116
+ if (val == "}" && stack.length) {
117
+ stack.shift();
118
+ this.next = stack.shift();
119
+ if (this.next.indexOf("string") != -1)
120
+ return "paren.end";
121
+ }
122
+ return val == "{" ? "paren.lparen" : "paren.rparen";
123
+ },
124
+ nextState: "start"
125
+ }, {
126
+ token : "string.start",
127
+ regex : /"/,
128
+ push : [{
129
+ token : "constant.language.escape",
130
+ regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/
131
+ }, {
132
+ token : "paren.start",
133
+ regex : /\#{/,
134
+ push : "start"
135
+ }, {
136
+ token : "string.end",
137
+ regex : /"/,
138
+ next : "pop"
139
+ }, {
140
+ defaultToken: "string"
141
+ }]
142
+ }, {
143
+ token : "string.start",
144
+ regex : /`/,
145
+ push : [{
146
+ token : "constant.language.escape",
147
+ regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/
148
+ }, {
149
+ token : "paren.start",
150
+ regex : /\#{/,
151
+ push : "start"
152
+ }, {
153
+ token : "string.end",
154
+ regex : /`/,
155
+ next : "pop"
156
+ }, {
157
+ defaultToken: "string"
158
+ }]
159
+ }, {
160
+ token : "string.start",
161
+ regex : /'/,
162
+ push : [{
163
+ token : "constant.language.escape",
164
+ regex : /\\['\\]/
165
+ }, {
166
+ token : "string.end",
167
+ regex : /'/,
168
+ next : "pop"
169
+ }, {
170
+ defaultToken: "string"
171
+ }]
172
+ }],
173
+
174
+ {
175
+ token : "text", // namespaces aren't symbols
176
+ regex : "::"
177
+ }, {
178
+ token : "variable.instance", // instance variable
179
+ regex : "@{1,2}[a-zA-Z_\\d]+"
180
+ }, {
181
+ token : "support.class", // class name
182
+ regex : "[A-Z][a-zA-Z_\\d]+"
183
+ },
184
+
185
+ constantOtherSymbol,
186
+ constantNumericHex,
187
+ constantNumericFloat,
188
+
189
+ {
190
+ token : "constant.language.boolean",
191
+ regex : "(?:true|false)\\b"
192
+ }, {
193
+ token : keywordMapper,
194
+ regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
195
+ }, {
196
+ token : "punctuation.separator.key-value",
197
+ regex : "=>"
198
+ }, {
199
+ stateName: "heredoc",
200
+ onMatch : function(value, currentState, stack) {
201
+ var next = value[2] == '-' ? "indentedHeredoc" : "heredoc";
202
+ var tokens = value.split(this.splitRegex);
203
+ stack.push(next, tokens[3]);
204
+ return [
205
+ {type:"constant", value: tokens[1]},
206
+ {type:"string", value: tokens[2]},
207
+ {type:"support.class", value: tokens[3]},
208
+ {type:"string", value: tokens[4]}
209
+ ];
210
+ },
211
+ regex : "(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",
212
+ rules: {
213
+ heredoc: [{
214
+ onMatch: function(value, currentState, stack) {
215
+ if (value === stack[1]) {
216
+ stack.shift();
217
+ stack.shift();
218
+ this.next = stack[0] || "start";
219
+ return "support.class";
220
+ }
221
+ this.next = "";
222
+ return "string";
223
+ },
224
+ regex: ".*$",
225
+ next: "start"
226
+ }],
227
+ indentedHeredoc: [{
228
+ token: "string",
229
+ regex: "^ +"
230
+ }, {
231
+ onMatch: function(value, currentState, stack) {
232
+ if (value === stack[1]) {
233
+ stack.shift();
234
+ stack.shift();
235
+ this.next = stack[0] || "start";
236
+ return "support.class";
237
+ }
238
+ this.next = "";
239
+ return "string";
240
+ },
241
+ regex: ".*$",
242
+ next: "start"
243
+ }]
244
+ }
245
+ }, {
246
+ regex : "$",
247
+ token : "empty",
248
+ next : function(currentState, stack) {
249
+ if (stack[0] === "heredoc" || stack[0] === "indentedHeredoc")
250
+ return stack[0];
251
+ return currentState;
252
+ }
253
+ }, {
254
+ token : "string.character",
255
+ regex : "\\B\\?."
256
+ }, {
257
+ token : "keyword.operator",
258
+ regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"
259
+ }, {
260
+ token : "paren.lparen",
261
+ regex : "[[({]"
262
+ }, {
263
+ token : "paren.rparen",
264
+ regex : "[\\])}]"
265
+ }, {
266
+ token : "text",
267
+ regex : "\\s+"
268
+ }
269
+ ],
270
+ "comment" : [
271
+ {
272
+ token : "comment", // closing comment
273
+ regex : "^=end(?:$|\\s.*$)",
274
+ next : "start"
275
+ }, {
276
+ token : "comment", // comment spanning whole line
277
+ regex : ".+"
278
+ }
279
+ ]
280
+ };
281
+
282
+ this.normalizeRules();
283
+ };
284
+
285
+ oop.inherits(RubyHighlightRules, TextHighlightRules);
286
+
287
+ exports.RubyHighlightRules = RubyHighlightRules;
288
+ });
289
+
290
+ define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) {
291
+ "use strict";
292
+
293
+ var Range = require("../range").Range;
294
+
295
+ var MatchingBraceOutdent = function() {};
296
+
297
+ (function() {
298
+
299
+ this.checkOutdent = function(line, input) {
300
+ if (! /^\s+$/.test(line))
301
+ return false;
302
+
303
+ return /^\s*\}/.test(input);
304
+ };
305
+
306
+ this.autoOutdent = function(doc, row) {
307
+ var line = doc.getLine(row);
308
+ var match = line.match(/^(\s*\})/);
309
+
310
+ if (!match) return 0;
311
+
312
+ var column = match[1].length;
313
+ var openBracePos = doc.findMatchingBracket({row: row, column: column});
314
+
315
+ if (!openBracePos || openBracePos.row == row) return 0;
316
+
317
+ var indent = this.$getIndent(doc.getLine(openBracePos.row));
318
+ doc.replace(new Range(row, 0, row, column-1), indent);
319
+ };
320
+
321
+ this.$getIndent = function(line) {
322
+ return line.match(/^\s*/)[0];
323
+ };
324
+
325
+ }).call(MatchingBraceOutdent.prototype);
326
+
327
+ exports.MatchingBraceOutdent = MatchingBraceOutdent;
328
+ });
329
+
330
+ define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) {
331
+ "use strict";
332
+
333
+ var oop = require("../../lib/oop");
334
+ var Behaviour = require("../behaviour").Behaviour;
335
+ var TokenIterator = require("../../token_iterator").TokenIterator;
336
+ var lang = require("../../lib/lang");
337
+
338
+ var SAFE_INSERT_IN_TOKENS =
339
+ ["text", "paren.rparen", "punctuation.operator"];
340
+ var SAFE_INSERT_BEFORE_TOKENS =
341
+ ["text", "paren.rparen", "punctuation.operator", "comment"];
342
+
343
+ var context;
344
+ var contextCache = {};
345
+ var initContext = function(editor) {
346
+ var id = -1;
347
+ if (editor.multiSelect) {
348
+ id = editor.selection.index;
349
+ if (contextCache.rangeCount != editor.multiSelect.rangeCount)
350
+ contextCache = {rangeCount: editor.multiSelect.rangeCount};
351
+ }
352
+ if (contextCache[id])
353
+ return context = contextCache[id];
354
+ context = contextCache[id] = {
355
+ autoInsertedBrackets: 0,
356
+ autoInsertedRow: -1,
357
+ autoInsertedLineEnd: "",
358
+ maybeInsertedBrackets: 0,
359
+ maybeInsertedRow: -1,
360
+ maybeInsertedLineStart: "",
361
+ maybeInsertedLineEnd: ""
362
+ };
363
+ };
364
+
365
+ var getWrapped = function(selection, selected, opening, closing) {
366
+ var rowDiff = selection.end.row - selection.start.row;
367
+ return {
368
+ text: opening + selected + closing,
369
+ selection: [
370
+ 0,
371
+ selection.start.column + 1,
372
+ rowDiff,
373
+ selection.end.column + (rowDiff ? 0 : 1)
374
+ ]
375
+ };
376
+ };
377
+
378
+ var CstyleBehaviour = function() {
379
+ this.add("braces", "insertion", function(state, action, editor, session, text) {
380
+ var cursor = editor.getCursorPosition();
381
+ var line = session.doc.getLine(cursor.row);
382
+ if (text == '{') {
383
+ initContext(editor);
384
+ var selection = editor.getSelectionRange();
385
+ var selected = session.doc.getTextRange(selection);
386
+ if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) {
387
+ return getWrapped(selection, selected, '{', '}');
388
+ } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
389
+ if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) {
390
+ CstyleBehaviour.recordAutoInsert(editor, session, "}");
391
+ return {
392
+ text: '{}',
393
+ selection: [1, 1]
394
+ };
395
+ } else {
396
+ CstyleBehaviour.recordMaybeInsert(editor, session, "{");
397
+ return {
398
+ text: '{',
399
+ selection: [1, 1]
400
+ };
401
+ }
402
+ }
403
+ } else if (text == '}') {
404
+ initContext(editor);
405
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
406
+ if (rightChar == '}') {
407
+ var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
408
+ if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
409
+ CstyleBehaviour.popAutoInsertedClosing();
410
+ return {
411
+ text: '',
412
+ selection: [1, 1]
413
+ };
414
+ }
415
+ }
416
+ } else if (text == "\n" || text == "\r\n") {
417
+ initContext(editor);
418
+ var closing = "";
419
+ if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
420
+ closing = lang.stringRepeat("}", context.maybeInsertedBrackets);
421
+ CstyleBehaviour.clearMaybeInsertedClosing();
422
+ }
423
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
424
+ if (rightChar === '}') {
425
+ var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');
426
+ if (!openBracePos)
427
+ return null;
428
+ var next_indent = this.$getIndent(session.getLine(openBracePos.row));
429
+ } else if (closing) {
430
+ var next_indent = this.$getIndent(line);
431
+ } else {
432
+ CstyleBehaviour.clearMaybeInsertedClosing();
433
+ return;
434
+ }
435
+ var indent = next_indent + session.getTabString();
436
+
437
+ return {
438
+ text: '\n' + indent + '\n' + next_indent + closing,
439
+ selection: [1, indent.length, 1, indent.length]
440
+ };
441
+ } else {
442
+ CstyleBehaviour.clearMaybeInsertedClosing();
443
+ }
444
+ });
445
+
446
+ this.add("braces", "deletion", function(state, action, editor, session, range) {
447
+ var selected = session.doc.getTextRange(range);
448
+ if (!range.isMultiLine() && selected == '{') {
449
+ initContext(editor);
450
+ var line = session.doc.getLine(range.start.row);
451
+ var rightChar = line.substring(range.end.column, range.end.column + 1);
452
+ if (rightChar == '}') {
453
+ range.end.column++;
454
+ return range;
455
+ } else {
456
+ context.maybeInsertedBrackets--;
457
+ }
458
+ }
459
+ });
460
+
461
+ this.add("parens", "insertion", function(state, action, editor, session, text) {
462
+ if (text == '(') {
463
+ initContext(editor);
464
+ var selection = editor.getSelectionRange();
465
+ var selected = session.doc.getTextRange(selection);
466
+ if (selected !== "" && editor.getWrapBehavioursEnabled()) {
467
+ return getWrapped(selection, selected, '(', ')');
468
+ } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
469
+ CstyleBehaviour.recordAutoInsert(editor, session, ")");
470
+ return {
471
+ text: '()',
472
+ selection: [1, 1]
473
+ };
474
+ }
475
+ } else if (text == ')') {
476
+ initContext(editor);
477
+ var cursor = editor.getCursorPosition();
478
+ var line = session.doc.getLine(cursor.row);
479
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
480
+ if (rightChar == ')') {
481
+ var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
482
+ if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
483
+ CstyleBehaviour.popAutoInsertedClosing();
484
+ return {
485
+ text: '',
486
+ selection: [1, 1]
487
+ };
488
+ }
489
+ }
490
+ }
491
+ });
492
+
493
+ this.add("parens", "deletion", function(state, action, editor, session, range) {
494
+ var selected = session.doc.getTextRange(range);
495
+ if (!range.isMultiLine() && selected == '(') {
496
+ initContext(editor);
497
+ var line = session.doc.getLine(range.start.row);
498
+ var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
499
+ if (rightChar == ')') {
500
+ range.end.column++;
501
+ return range;
502
+ }
503
+ }
504
+ });
505
+
506
+ this.add("brackets", "insertion", function(state, action, editor, session, text) {
507
+ if (text == '[') {
508
+ initContext(editor);
509
+ var selection = editor.getSelectionRange();
510
+ var selected = session.doc.getTextRange(selection);
511
+ if (selected !== "" && editor.getWrapBehavioursEnabled()) {
512
+ return getWrapped(selection, selected, '[', ']');
513
+ } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
514
+ CstyleBehaviour.recordAutoInsert(editor, session, "]");
515
+ return {
516
+ text: '[]',
517
+ selection: [1, 1]
518
+ };
519
+ }
520
+ } else if (text == ']') {
521
+ initContext(editor);
522
+ var cursor = editor.getCursorPosition();
523
+ var line = session.doc.getLine(cursor.row);
524
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
525
+ if (rightChar == ']') {
526
+ var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
527
+ if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
528
+ CstyleBehaviour.popAutoInsertedClosing();
529
+ return {
530
+ text: '',
531
+ selection: [1, 1]
532
+ };
533
+ }
534
+ }
535
+ }
536
+ });
537
+
538
+ this.add("brackets", "deletion", function(state, action, editor, session, range) {
539
+ var selected = session.doc.getTextRange(range);
540
+ if (!range.isMultiLine() && selected == '[') {
541
+ initContext(editor);
542
+ var line = session.doc.getLine(range.start.row);
543
+ var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
544
+ if (rightChar == ']') {
545
+ range.end.column++;
546
+ return range;
547
+ }
548
+ }
549
+ });
550
+
551
+ this.add("string_dquotes", "insertion", function(state, action, editor, session, text) {
552
+ if (text == '"' || text == "'") {
553
+ initContext(editor);
554
+ var quote = text;
555
+ var selection = editor.getSelectionRange();
556
+ var selected = session.doc.getTextRange(selection);
557
+ if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
558
+ return getWrapped(selection, selected, quote, quote);
559
+ } else if (!selected) {
560
+ var cursor = editor.getCursorPosition();
561
+ var line = session.doc.getLine(cursor.row);
562
+ var leftChar = line.substring(cursor.column-1, cursor.column);
563
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
564
+
565
+ var token = session.getTokenAt(cursor.row, cursor.column);
566
+ var rightToken = session.getTokenAt(cursor.row, cursor.column + 1);
567
+ if (leftChar == "\\" && token && /escape/.test(token.type))
568
+ return null;
569
+
570
+ var stringBefore = token && /string/.test(token.type);
571
+ var stringAfter = !rightToken || /string/.test(rightToken.type);
572
+
573
+ var pair;
574
+ if (rightChar == quote) {
575
+ pair = stringBefore !== stringAfter;
576
+ } else {
577
+ if (stringBefore && !stringAfter)
578
+ return null; // wrap string with different quote
579
+ if (stringBefore && stringAfter)
580
+ return null; // do not pair quotes inside strings
581
+ var wordRe = session.$mode.tokenRe;
582
+ wordRe.lastIndex = 0;
583
+ var isWordBefore = wordRe.test(leftChar);
584
+ wordRe.lastIndex = 0;
585
+ var isWordAfter = wordRe.test(leftChar);
586
+ if (isWordBefore || isWordAfter)
587
+ return null; // before or after alphanumeric
588
+ if (rightChar && !/[\s;,.})\]\\]/.test(rightChar))
589
+ return null; // there is rightChar and it isn't closing
590
+ pair = true;
591
+ }
592
+ return {
593
+ text: pair ? quote + quote : "",
594
+ selection: [1,1]
595
+ };
596
+ }
597
+ }
598
+ });
599
+
600
+ this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
601
+ var selected = session.doc.getTextRange(range);
602
+ if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
603
+ initContext(editor);
604
+ var line = session.doc.getLine(range.start.row);
605
+ var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
606
+ if (rightChar == selected) {
607
+ range.end.column++;
608
+ return range;
609
+ }
610
+ }
611
+ });
612
+
613
+ };
614
+
615
+
616
+ CstyleBehaviour.isSaneInsertion = function(editor, session) {
617
+ var cursor = editor.getCursorPosition();
618
+ var iterator = new TokenIterator(session, cursor.row, cursor.column);
619
+ if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
620
+ var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
621
+ if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
622
+ return false;
623
+ }
624
+ iterator.stepForward();
625
+ return iterator.getCurrentTokenRow() !== cursor.row ||
626
+ this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
627
+ };
628
+
629
+ CstyleBehaviour.$matchTokenType = function(token, types) {
630
+ return types.indexOf(token.type || token) > -1;
631
+ };
632
+
633
+ CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) {
634
+ var cursor = editor.getCursorPosition();
635
+ var line = session.doc.getLine(cursor.row);
636
+ if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0]))
637
+ context.autoInsertedBrackets = 0;
638
+ context.autoInsertedRow = cursor.row;
639
+ context.autoInsertedLineEnd = bracket + line.substr(cursor.column);
640
+ context.autoInsertedBrackets++;
641
+ };
642
+
643
+ CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
644
+ var cursor = editor.getCursorPosition();
645
+ var line = session.doc.getLine(cursor.row);
646
+ if (!this.isMaybeInsertedClosing(cursor, line))
647
+ context.maybeInsertedBrackets = 0;
648
+ context.maybeInsertedRow = cursor.row;
649
+ context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
650
+ context.maybeInsertedLineEnd = line.substr(cursor.column);
651
+ context.maybeInsertedBrackets++;
652
+ };
653
+
654
+ CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
655
+ return context.autoInsertedBrackets > 0 &&
656
+ cursor.row === context.autoInsertedRow &&
657
+ bracket === context.autoInsertedLineEnd[0] &&
658
+ line.substr(cursor.column) === context.autoInsertedLineEnd;
659
+ };
660
+
661
+ CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
662
+ return context.maybeInsertedBrackets > 0 &&
663
+ cursor.row === context.maybeInsertedRow &&
664
+ line.substr(cursor.column) === context.maybeInsertedLineEnd &&
665
+ line.substr(0, cursor.column) == context.maybeInsertedLineStart;
666
+ };
667
+
668
+ CstyleBehaviour.popAutoInsertedClosing = function() {
669
+ context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1);
670
+ context.autoInsertedBrackets--;
671
+ };
672
+
673
+ CstyleBehaviour.clearMaybeInsertedClosing = function() {
674
+ if (context) {
675
+ context.maybeInsertedBrackets = 0;
676
+ context.maybeInsertedRow = -1;
677
+ }
678
+ };
679
+
680
+
681
+
682
+ oop.inherits(CstyleBehaviour, Behaviour);
683
+
684
+ exports.CstyleBehaviour = CstyleBehaviour;
685
+ });
686
+
687
+ define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"], function(require, exports, module) {
688
+ "use strict";
689
+
690
+ var oop = require("../../lib/oop");
691
+ var BaseFoldMode = require("./fold_mode").FoldMode;
692
+ var Range = require("../../range").Range;
693
+
694
+ var FoldMode = exports.FoldMode = function() {};
695
+ oop.inherits(FoldMode, BaseFoldMode);
696
+
697
+ (function() {
698
+
699
+ this.getFoldWidgetRange = function(session, foldStyle, row) {
700
+ var range = this.indentationBlock(session, row);
701
+ if (range)
702
+ return range;
703
+
704
+ var re = /\S/;
705
+ var line = session.getLine(row);
706
+ var startLevel = line.search(re);
707
+ if (startLevel == -1 || line[startLevel] != "#")
708
+ return;
709
+
710
+ var startColumn = line.length;
711
+ var maxRow = session.getLength();
712
+ var startRow = row;
713
+ var endRow = row;
714
+
715
+ while (++row < maxRow) {
716
+ line = session.getLine(row);
717
+ var level = line.search(re);
718
+
719
+ if (level == -1)
720
+ continue;
721
+
722
+ if (line[level] != "#")
723
+ break;
724
+
725
+ endRow = row;
726
+ }
727
+
728
+ if (endRow > startRow) {
729
+ var endColumn = session.getLine(endRow).length;
730
+ return new Range(startRow, startColumn, endRow, endColumn);
731
+ }
732
+ };
733
+ this.getFoldWidget = function(session, foldStyle, row) {
734
+ var line = session.getLine(row);
735
+ var indent = line.search(/\S/);
736
+ var next = session.getLine(row + 1);
737
+ var prev = session.getLine(row - 1);
738
+ var prevIndent = prev.search(/\S/);
739
+ var nextIndent = next.search(/\S/);
740
+
741
+ if (indent == -1) {
742
+ session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? "start" : "";
743
+ return "";
744
+ }
745
+ if (prevIndent == -1) {
746
+ if (indent == nextIndent && line[indent] == "#" && next[indent] == "#") {
747
+ session.foldWidgets[row - 1] = "";
748
+ session.foldWidgets[row + 1] = "";
749
+ return "start";
750
+ }
751
+ } else if (prevIndent == indent && line[indent] == "#" && prev[indent] == "#") {
752
+ if (session.getLine(row - 2).search(/\S/) == -1) {
753
+ session.foldWidgets[row - 1] = "start";
754
+ session.foldWidgets[row + 1] = "";
755
+ return "";
756
+ }
757
+ }
758
+
759
+ if (prevIndent!= -1 && prevIndent < indent)
760
+ session.foldWidgets[row - 1] = "start";
761
+ else
762
+ session.foldWidgets[row - 1] = "";
763
+
764
+ if (indent < nextIndent)
765
+ return "start";
766
+ else
767
+ return "";
768
+ };
769
+
770
+ }).call(FoldMode.prototype);
771
+
772
+ });
773
+
774
+ define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/coffee"], function(require, exports, module) {
775
+ "use strict";
776
+
777
+ var oop = require("../lib/oop");
778
+ var TextMode = require("./text").Mode;
779
+ var RubyHighlightRules = require("./ruby_highlight_rules").RubyHighlightRules;
780
+ var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
781
+ var Range = require("../range").Range;
782
+ var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
783
+ var FoldMode = require("./folding/coffee").FoldMode;
784
+
785
+ var Mode = function() {
786
+ this.HighlightRules = RubyHighlightRules;
787
+ this.$outdent = new MatchingBraceOutdent();
788
+ this.$behaviour = new CstyleBehaviour();
789
+ this.foldingRules = new FoldMode();
790
+ };
791
+ oop.inherits(Mode, TextMode);
792
+
793
+ (function() {
794
+
795
+
796
+ this.lineCommentStart = "#";
797
+
798
+ this.getNextLineIndent = function(state, line, tab) {
799
+ var indent = this.$getIndent(line);
800
+
801
+ var tokenizedLine = this.getTokenizer().getLineTokens(line, state);
802
+ var tokens = tokenizedLine.tokens;
803
+
804
+ if (tokens.length && tokens[tokens.length-1].type == "comment") {
805
+ return indent;
806
+ }
807
+
808
+ if (state == "start") {
809
+ var match = line.match(/^.*[\{\(\[]\s*$/);
810
+ var startingClassOrMethod = line.match(/^\s*(class|def|module)\s.*$/);
811
+ var startingDoBlock = line.match(/.*do(\s*|\s+\|.*\|\s*)$/);
812
+ var startingConditional = line.match(/^\s*(if|else)\s*/)
813
+ if (match || startingClassOrMethod || startingDoBlock || startingConditional) {
814
+ indent += tab;
815
+ }
816
+ }
817
+
818
+ return indent;
819
+ };
820
+
821
+ this.checkOutdent = function(state, line, input) {
822
+ return /^\s+(end|else)$/.test(line + input) || this.$outdent.checkOutdent(line, input);
823
+ };
824
+
825
+ this.autoOutdent = function(state, session, row) {
826
+ var line = session.getLine(row);
827
+ if (/}/.test(line))
828
+ return this.$outdent.autoOutdent(session, row);
829
+ var indent = this.$getIndent(line);
830
+ var prevLine = session.getLine(row - 1);
831
+ var prevIndent = this.$getIndent(prevLine);
832
+ var tab = session.getTabString();
833
+ if (prevIndent.length <= indent.length) {
834
+ if (indent.slice(-tab.length) == tab)
835
+ session.remove(new Range(row, indent.length-tab.length, row, indent.length));
836
+ }
837
+ };
838
+
839
+ this.$id = "ace/mode/ruby";
840
+ }).call(Mode.prototype);
841
+
842
+ exports.Mode = Mode;
843
+ });