stackprofiler 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/README.md +1 -1
  4. data/config.ru +3 -2
  5. data/lib/stackprofiler.rb +0 -1
  6. data/lib/stackprofiler/filters/build_tree.rb +3 -4
  7. data/lib/stackprofiler/filters/gem_removal.rb +3 -0
  8. data/lib/stackprofiler/web_ui.rb +34 -11
  9. data/lib/stackprofiler/web_ui/public/css/stackprofiler.css +77 -0
  10. data/lib/stackprofiler/web_ui/public/js/stackprofiler.js +129 -58
  11. data/lib/stackprofiler/web_ui/public/vendor/ace/ace.js +18298 -0
  12. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-beautify.js +334 -0
  13. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-chromevox.js +541 -0
  14. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-elastic_tabstops_lite.js +275 -0
  15. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-emmet.js +1190 -0
  16. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-error_marker.js +6 -0
  17. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-keybinding_menu.js +170 -0
  18. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-language_tools.js +1934 -0
  19. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-linking.js +52 -0
  20. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-modelist.js +187 -0
  21. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-old_ie.js +494 -0
  22. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-searchbox.js +409 -0
  23. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-settings_menu.js +637 -0
  24. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-spellcheck.js +71 -0
  25. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-split.js +246 -0
  26. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-static_highlight.js +154 -0
  27. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-statusbar.js +51 -0
  28. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-textarea.js +632 -0
  29. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-themelist.js +58 -0
  30. data/lib/stackprofiler/web_ui/public/vendor/ace/ext-whitespace.js +181 -0
  31. data/lib/stackprofiler/web_ui/public/vendor/ace/keybinding-emacs.js +1182 -0
  32. data/lib/stackprofiler/web_ui/public/vendor/ace/keybinding-vim.js +5320 -0
  33. data/lib/stackprofiler/web_ui/public/vendor/ace/mode-haml.js +525 -0
  34. data/lib/stackprofiler/web_ui/public/vendor/ace/mode-html.js +2427 -0
  35. data/lib/stackprofiler/web_ui/public/vendor/ace/mode-html_ruby.js +2955 -0
  36. data/lib/stackprofiler/web_ui/public/vendor/ace/mode-javascript.js +1025 -0
  37. data/lib/stackprofiler/web_ui/public/vendor/ace/mode-json.js +668 -0
  38. data/lib/stackprofiler/web_ui/public/vendor/ace/mode-ruby.js +839 -0
  39. data/lib/stackprofiler/web_ui/public/vendor/ace/mode-xml.js +637 -0
  40. data/lib/stackprofiler/web_ui/public/vendor/ace/mode-yaml.js +256 -0
  41. data/lib/stackprofiler/web_ui/public/vendor/ace/theme-xcode.js +89 -0
  42. data/lib/stackprofiler/web_ui/public/vendor/ace/worker-coffee.js +7599 -0
  43. data/lib/stackprofiler/web_ui/public/vendor/ace/worker-css.js +8682 -0
  44. data/lib/stackprofiler/web_ui/public/vendor/ace/worker-html.js +11527 -0
  45. data/lib/stackprofiler/web_ui/public/vendor/ace/worker-javascript.js +10429 -0
  46. data/lib/stackprofiler/web_ui/public/vendor/ace/worker-json.js +2319 -0
  47. data/lib/stackprofiler/web_ui/views/index.erb +1 -1
  48. data/lib/stackprofiler/web_ui/views/layout.erb +2 -55
  49. data/stackprofiler.gemspec +2 -4
  50. metadata +42 -19
  51. data/lib/stackprofiler/web_ui/views/code.erb +0 -17
@@ -0,0 +1,839 @@
1
+ ace.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 : "keyword.operator",
255
+ regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"
256
+ }, {
257
+ token : "paren.lparen",
258
+ regex : "[[({]"
259
+ }, {
260
+ token : "paren.rparen",
261
+ regex : "[\\])}]"
262
+ }, {
263
+ token : "text",
264
+ regex : "\\s+"
265
+ }
266
+ ],
267
+ "comment" : [
268
+ {
269
+ token : "comment", // closing comment
270
+ regex : "^=end(?:$|\\s.*$)",
271
+ next : "start"
272
+ }, {
273
+ token : "comment", // comment spanning whole line
274
+ regex : ".+"
275
+ }
276
+ ]
277
+ };
278
+
279
+ this.normalizeRules();
280
+ };
281
+
282
+ oop.inherits(RubyHighlightRules, TextHighlightRules);
283
+
284
+ exports.RubyHighlightRules = RubyHighlightRules;
285
+ });
286
+
287
+ ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) {
288
+ "use strict";
289
+
290
+ var Range = require("../range").Range;
291
+
292
+ var MatchingBraceOutdent = function() {};
293
+
294
+ (function() {
295
+
296
+ this.checkOutdent = function(line, input) {
297
+ if (! /^\s+$/.test(line))
298
+ return false;
299
+
300
+ return /^\s*\}/.test(input);
301
+ };
302
+
303
+ this.autoOutdent = function(doc, row) {
304
+ var line = doc.getLine(row);
305
+ var match = line.match(/^(\s*\})/);
306
+
307
+ if (!match) return 0;
308
+
309
+ var column = match[1].length;
310
+ var openBracePos = doc.findMatchingBracket({row: row, column: column});
311
+
312
+ if (!openBracePos || openBracePos.row == row) return 0;
313
+
314
+ var indent = this.$getIndent(doc.getLine(openBracePos.row));
315
+ doc.replace(new Range(row, 0, row, column-1), indent);
316
+ };
317
+
318
+ this.$getIndent = function(line) {
319
+ return line.match(/^\s*/)[0];
320
+ };
321
+
322
+ }).call(MatchingBraceOutdent.prototype);
323
+
324
+ exports.MatchingBraceOutdent = MatchingBraceOutdent;
325
+ });
326
+
327
+ ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) {
328
+ "use strict";
329
+
330
+ var oop = require("../../lib/oop");
331
+ var Behaviour = require("../behaviour").Behaviour;
332
+ var TokenIterator = require("../../token_iterator").TokenIterator;
333
+ var lang = require("../../lib/lang");
334
+
335
+ var SAFE_INSERT_IN_TOKENS =
336
+ ["text", "paren.rparen", "punctuation.operator"];
337
+ var SAFE_INSERT_BEFORE_TOKENS =
338
+ ["text", "paren.rparen", "punctuation.operator", "comment"];
339
+
340
+ var context;
341
+ var contextCache = {};
342
+ var initContext = function(editor) {
343
+ var id = -1;
344
+ if (editor.multiSelect) {
345
+ id = editor.selection.index;
346
+ if (contextCache.rangeCount != editor.multiSelect.rangeCount)
347
+ contextCache = {rangeCount: editor.multiSelect.rangeCount};
348
+ }
349
+ if (contextCache[id])
350
+ return context = contextCache[id];
351
+ context = contextCache[id] = {
352
+ autoInsertedBrackets: 0,
353
+ autoInsertedRow: -1,
354
+ autoInsertedLineEnd: "",
355
+ maybeInsertedBrackets: 0,
356
+ maybeInsertedRow: -1,
357
+ maybeInsertedLineStart: "",
358
+ maybeInsertedLineEnd: ""
359
+ };
360
+ };
361
+
362
+ var CstyleBehaviour = function() {
363
+ this.add("braces", "insertion", function(state, action, editor, session, text) {
364
+ var cursor = editor.getCursorPosition();
365
+ var line = session.doc.getLine(cursor.row);
366
+ if (text == '{') {
367
+ initContext(editor);
368
+ var selection = editor.getSelectionRange();
369
+ var selected = session.doc.getTextRange(selection);
370
+ if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) {
371
+ return {
372
+ text: '{' + selected + '}',
373
+ selection: false
374
+ };
375
+ } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
376
+ if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) {
377
+ CstyleBehaviour.recordAutoInsert(editor, session, "}");
378
+ return {
379
+ text: '{}',
380
+ selection: [1, 1]
381
+ };
382
+ } else {
383
+ CstyleBehaviour.recordMaybeInsert(editor, session, "{");
384
+ return {
385
+ text: '{',
386
+ selection: [1, 1]
387
+ };
388
+ }
389
+ }
390
+ } else if (text == '}') {
391
+ initContext(editor);
392
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
393
+ if (rightChar == '}') {
394
+ var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row});
395
+ if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
396
+ CstyleBehaviour.popAutoInsertedClosing();
397
+ return {
398
+ text: '',
399
+ selection: [1, 1]
400
+ };
401
+ }
402
+ }
403
+ } else if (text == "\n" || text == "\r\n") {
404
+ initContext(editor);
405
+ var closing = "";
406
+ if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) {
407
+ closing = lang.stringRepeat("}", context.maybeInsertedBrackets);
408
+ CstyleBehaviour.clearMaybeInsertedClosing();
409
+ }
410
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
411
+ if (rightChar === '}') {
412
+ var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}');
413
+ if (!openBracePos)
414
+ return null;
415
+ var next_indent = this.$getIndent(session.getLine(openBracePos.row));
416
+ } else if (closing) {
417
+ var next_indent = this.$getIndent(line);
418
+ } else {
419
+ CstyleBehaviour.clearMaybeInsertedClosing();
420
+ return;
421
+ }
422
+ var indent = next_indent + session.getTabString();
423
+
424
+ return {
425
+ text: '\n' + indent + '\n' + next_indent + closing,
426
+ selection: [1, indent.length, 1, indent.length]
427
+ };
428
+ } else {
429
+ CstyleBehaviour.clearMaybeInsertedClosing();
430
+ }
431
+ });
432
+
433
+ this.add("braces", "deletion", function(state, action, editor, session, range) {
434
+ var selected = session.doc.getTextRange(range);
435
+ if (!range.isMultiLine() && selected == '{') {
436
+ initContext(editor);
437
+ var line = session.doc.getLine(range.start.row);
438
+ var rightChar = line.substring(range.end.column, range.end.column + 1);
439
+ if (rightChar == '}') {
440
+ range.end.column++;
441
+ return range;
442
+ } else {
443
+ context.maybeInsertedBrackets--;
444
+ }
445
+ }
446
+ });
447
+
448
+ this.add("parens", "insertion", function(state, action, editor, session, text) {
449
+ if (text == '(') {
450
+ initContext(editor);
451
+ var selection = editor.getSelectionRange();
452
+ var selected = session.doc.getTextRange(selection);
453
+ if (selected !== "" && editor.getWrapBehavioursEnabled()) {
454
+ return {
455
+ text: '(' + selected + ')',
456
+ selection: false
457
+ };
458
+ } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
459
+ CstyleBehaviour.recordAutoInsert(editor, session, ")");
460
+ return {
461
+ text: '()',
462
+ selection: [1, 1]
463
+ };
464
+ }
465
+ } else if (text == ')') {
466
+ initContext(editor);
467
+ var cursor = editor.getCursorPosition();
468
+ var line = session.doc.getLine(cursor.row);
469
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
470
+ if (rightChar == ')') {
471
+ var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row});
472
+ if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
473
+ CstyleBehaviour.popAutoInsertedClosing();
474
+ return {
475
+ text: '',
476
+ selection: [1, 1]
477
+ };
478
+ }
479
+ }
480
+ }
481
+ });
482
+
483
+ this.add("parens", "deletion", function(state, action, editor, session, range) {
484
+ var selected = session.doc.getTextRange(range);
485
+ if (!range.isMultiLine() && selected == '(') {
486
+ initContext(editor);
487
+ var line = session.doc.getLine(range.start.row);
488
+ var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
489
+ if (rightChar == ')') {
490
+ range.end.column++;
491
+ return range;
492
+ }
493
+ }
494
+ });
495
+
496
+ this.add("brackets", "insertion", function(state, action, editor, session, text) {
497
+ if (text == '[') {
498
+ initContext(editor);
499
+ var selection = editor.getSelectionRange();
500
+ var selected = session.doc.getTextRange(selection);
501
+ if (selected !== "" && editor.getWrapBehavioursEnabled()) {
502
+ return {
503
+ text: '[' + selected + ']',
504
+ selection: false
505
+ };
506
+ } else if (CstyleBehaviour.isSaneInsertion(editor, session)) {
507
+ CstyleBehaviour.recordAutoInsert(editor, session, "]");
508
+ return {
509
+ text: '[]',
510
+ selection: [1, 1]
511
+ };
512
+ }
513
+ } else if (text == ']') {
514
+ initContext(editor);
515
+ var cursor = editor.getCursorPosition();
516
+ var line = session.doc.getLine(cursor.row);
517
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
518
+ if (rightChar == ']') {
519
+ var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row});
520
+ if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) {
521
+ CstyleBehaviour.popAutoInsertedClosing();
522
+ return {
523
+ text: '',
524
+ selection: [1, 1]
525
+ };
526
+ }
527
+ }
528
+ }
529
+ });
530
+
531
+ this.add("brackets", "deletion", function(state, action, editor, session, range) {
532
+ var selected = session.doc.getTextRange(range);
533
+ if (!range.isMultiLine() && selected == '[') {
534
+ initContext(editor);
535
+ var line = session.doc.getLine(range.start.row);
536
+ var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
537
+ if (rightChar == ']') {
538
+ range.end.column++;
539
+ return range;
540
+ }
541
+ }
542
+ });
543
+
544
+ this.add("string_dquotes", "insertion", function(state, action, editor, session, text) {
545
+ if (text == '"' || text == "'") {
546
+ initContext(editor);
547
+ var quote = text;
548
+ var selection = editor.getSelectionRange();
549
+ var selected = session.doc.getTextRange(selection);
550
+ if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
551
+ return {
552
+ text: quote + selected + quote,
553
+ selection: false
554
+ };
555
+ } else {
556
+ var cursor = editor.getCursorPosition();
557
+ var line = session.doc.getLine(cursor.row);
558
+ var leftChar = line.substring(cursor.column-1, cursor.column);
559
+ var rightChar = line.substring(cursor.column, cursor.column + 1);
560
+
561
+ var token = session.getTokenAt(cursor.row, cursor.column);
562
+ var rightToken = session.getTokenAt(cursor.row, cursor.column + 1);
563
+ if (leftChar == "\\" && token && /escape/.test(token.type))
564
+ return null;
565
+
566
+ var stringBefore = token && /string/.test(token.type);
567
+ var stringAfter = !rightToken || /string/.test(rightToken.type);
568
+
569
+ var pair;
570
+ if (rightChar == quote) {
571
+ pair = stringBefore !== stringAfter;
572
+ } else {
573
+ if (stringBefore && !stringAfter)
574
+ return null; // wrap string with different quote
575
+ if (stringBefore && stringAfter)
576
+ return null; // do not pair quotes inside strings
577
+ var wordRe = session.$mode.tokenRe;
578
+ wordRe.lastIndex = 0;
579
+ var isWordBefore = wordRe.test(leftChar);
580
+ wordRe.lastIndex = 0;
581
+ var isWordAfter = wordRe.test(leftChar);
582
+ if (isWordBefore || isWordAfter)
583
+ return null; // before or after alphanumeric
584
+ if (rightChar && !/[\s;,.})\]\\]/.test(rightChar))
585
+ return null; // there is rightChar and it isn't closing
586
+ pair = true;
587
+ }
588
+ return {
589
+ text: pair ? quote + quote : "",
590
+ selection: [1,1]
591
+ };
592
+ }
593
+ }
594
+ });
595
+
596
+ this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
597
+ var selected = session.doc.getTextRange(range);
598
+ if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
599
+ initContext(editor);
600
+ var line = session.doc.getLine(range.start.row);
601
+ var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
602
+ if (rightChar == selected) {
603
+ range.end.column++;
604
+ return range;
605
+ }
606
+ }
607
+ });
608
+
609
+ };
610
+
611
+
612
+ CstyleBehaviour.isSaneInsertion = function(editor, session) {
613
+ var cursor = editor.getCursorPosition();
614
+ var iterator = new TokenIterator(session, cursor.row, cursor.column);
615
+ if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) {
616
+ var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1);
617
+ if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS))
618
+ return false;
619
+ }
620
+ iterator.stepForward();
621
+ return iterator.getCurrentTokenRow() !== cursor.row ||
622
+ this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS);
623
+ };
624
+
625
+ CstyleBehaviour.$matchTokenType = function(token, types) {
626
+ return types.indexOf(token.type || token) > -1;
627
+ };
628
+
629
+ CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) {
630
+ var cursor = editor.getCursorPosition();
631
+ var line = session.doc.getLine(cursor.row);
632
+ if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0]))
633
+ context.autoInsertedBrackets = 0;
634
+ context.autoInsertedRow = cursor.row;
635
+ context.autoInsertedLineEnd = bracket + line.substr(cursor.column);
636
+ context.autoInsertedBrackets++;
637
+ };
638
+
639
+ CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) {
640
+ var cursor = editor.getCursorPosition();
641
+ var line = session.doc.getLine(cursor.row);
642
+ if (!this.isMaybeInsertedClosing(cursor, line))
643
+ context.maybeInsertedBrackets = 0;
644
+ context.maybeInsertedRow = cursor.row;
645
+ context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket;
646
+ context.maybeInsertedLineEnd = line.substr(cursor.column);
647
+ context.maybeInsertedBrackets++;
648
+ };
649
+
650
+ CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) {
651
+ return context.autoInsertedBrackets > 0 &&
652
+ cursor.row === context.autoInsertedRow &&
653
+ bracket === context.autoInsertedLineEnd[0] &&
654
+ line.substr(cursor.column) === context.autoInsertedLineEnd;
655
+ };
656
+
657
+ CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) {
658
+ return context.maybeInsertedBrackets > 0 &&
659
+ cursor.row === context.maybeInsertedRow &&
660
+ line.substr(cursor.column) === context.maybeInsertedLineEnd &&
661
+ line.substr(0, cursor.column) == context.maybeInsertedLineStart;
662
+ };
663
+
664
+ CstyleBehaviour.popAutoInsertedClosing = function() {
665
+ context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1);
666
+ context.autoInsertedBrackets--;
667
+ };
668
+
669
+ CstyleBehaviour.clearMaybeInsertedClosing = function() {
670
+ if (context) {
671
+ context.maybeInsertedBrackets = 0;
672
+ context.maybeInsertedRow = -1;
673
+ }
674
+ };
675
+
676
+
677
+
678
+ oop.inherits(CstyleBehaviour, Behaviour);
679
+
680
+ exports.CstyleBehaviour = CstyleBehaviour;
681
+ });
682
+
683
+ ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"], function(require, exports, module) {
684
+ "use strict";
685
+
686
+ var oop = require("../../lib/oop");
687
+ var BaseFoldMode = require("./fold_mode").FoldMode;
688
+ var Range = require("../../range").Range;
689
+
690
+ var FoldMode = exports.FoldMode = function() {};
691
+ oop.inherits(FoldMode, BaseFoldMode);
692
+
693
+ (function() {
694
+
695
+ this.getFoldWidgetRange = function(session, foldStyle, row) {
696
+ var range = this.indentationBlock(session, row);
697
+ if (range)
698
+ return range;
699
+
700
+ var re = /\S/;
701
+ var line = session.getLine(row);
702
+ var startLevel = line.search(re);
703
+ if (startLevel == -1 || line[startLevel] != "#")
704
+ return;
705
+
706
+ var startColumn = line.length;
707
+ var maxRow = session.getLength();
708
+ var startRow = row;
709
+ var endRow = row;
710
+
711
+ while (++row < maxRow) {
712
+ line = session.getLine(row);
713
+ var level = line.search(re);
714
+
715
+ if (level == -1)
716
+ continue;
717
+
718
+ if (line[level] != "#")
719
+ break;
720
+
721
+ endRow = row;
722
+ }
723
+
724
+ if (endRow > startRow) {
725
+ var endColumn = session.getLine(endRow).length;
726
+ return new Range(startRow, startColumn, endRow, endColumn);
727
+ }
728
+ };
729
+ this.getFoldWidget = function(session, foldStyle, row) {
730
+ var line = session.getLine(row);
731
+ var indent = line.search(/\S/);
732
+ var next = session.getLine(row + 1);
733
+ var prev = session.getLine(row - 1);
734
+ var prevIndent = prev.search(/\S/);
735
+ var nextIndent = next.search(/\S/);
736
+
737
+ if (indent == -1) {
738
+ session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? "start" : "";
739
+ return "";
740
+ }
741
+ if (prevIndent == -1) {
742
+ if (indent == nextIndent && line[indent] == "#" && next[indent] == "#") {
743
+ session.foldWidgets[row - 1] = "";
744
+ session.foldWidgets[row + 1] = "";
745
+ return "start";
746
+ }
747
+ } else if (prevIndent == indent && line[indent] == "#" && prev[indent] == "#") {
748
+ if (session.getLine(row - 2).search(/\S/) == -1) {
749
+ session.foldWidgets[row - 1] = "start";
750
+ session.foldWidgets[row + 1] = "";
751
+ return "";
752
+ }
753
+ }
754
+
755
+ if (prevIndent!= -1 && prevIndent < indent)
756
+ session.foldWidgets[row - 1] = "start";
757
+ else
758
+ session.foldWidgets[row - 1] = "";
759
+
760
+ if (indent < nextIndent)
761
+ return "start";
762
+ else
763
+ return "";
764
+ };
765
+
766
+ }).call(FoldMode.prototype);
767
+
768
+ });
769
+
770
+ ace.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) {
771
+ "use strict";
772
+
773
+ var oop = require("../lib/oop");
774
+ var TextMode = require("./text").Mode;
775
+ var RubyHighlightRules = require("./ruby_highlight_rules").RubyHighlightRules;
776
+ var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
777
+ var Range = require("../range").Range;
778
+ var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;
779
+ var FoldMode = require("./folding/coffee").FoldMode;
780
+
781
+ var Mode = function() {
782
+ this.HighlightRules = RubyHighlightRules;
783
+ this.$outdent = new MatchingBraceOutdent();
784
+ this.$behaviour = new CstyleBehaviour();
785
+ this.foldingRules = new FoldMode();
786
+ };
787
+ oop.inherits(Mode, TextMode);
788
+
789
+ (function() {
790
+
791
+
792
+ this.lineCommentStart = "#";
793
+
794
+ this.getNextLineIndent = function(state, line, tab) {
795
+ var indent = this.$getIndent(line);
796
+
797
+ var tokenizedLine = this.getTokenizer().getLineTokens(line, state);
798
+ var tokens = tokenizedLine.tokens;
799
+
800
+ if (tokens.length && tokens[tokens.length-1].type == "comment") {
801
+ return indent;
802
+ }
803
+
804
+ if (state == "start") {
805
+ var match = line.match(/^.*[\{\(\[]\s*$/);
806
+ var startingClassOrMethod = line.match(/^\s*(class|def|module)\s.*$/);
807
+ var startingDoBlock = line.match(/.*do(\s*|\s+\|.*\|\s*)$/);
808
+ var startingConditional = line.match(/^\s*(if|else)\s*/)
809
+ if (match || startingClassOrMethod || startingDoBlock || startingConditional) {
810
+ indent += tab;
811
+ }
812
+ }
813
+
814
+ return indent;
815
+ };
816
+
817
+ this.checkOutdent = function(state, line, input) {
818
+ return /^\s+(end|else)$/.test(line + input) || this.$outdent.checkOutdent(line, input);
819
+ };
820
+
821
+ this.autoOutdent = function(state, session, row) {
822
+ var line = session.getLine(row);
823
+ if (/}/.test(line))
824
+ return this.$outdent.autoOutdent(session, row);
825
+ var indent = this.$getIndent(line);
826
+ var prevLine = session.getLine(row - 1);
827
+ var prevIndent = this.$getIndent(prevLine);
828
+ var tab = session.getTabString();
829
+ if (prevIndent.length <= indent.length) {
830
+ if (indent.slice(-tab.length) == tab)
831
+ session.remove(new Range(row, indent.length-tab.length, row, indent.length));
832
+ }
833
+ };
834
+
835
+ this.$id = "ace/mode/ruby";
836
+ }).call(Mode.prototype);
837
+
838
+ exports.Mode = Mode;
839
+ });