express_admin 1.4.8 → 1.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ });