pry 0.9.8pre5-i386-mswin32 → 0.9.8pre6-i386-mswin32

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.
@@ -28,67 +28,94 @@ class Pry
28
28
  _pry_.instance_eval(&Pry::FILE_COMPLETIONS)
29
29
  end
30
30
  end
31
-
32
31
  alias_command "file-mode", "shell-mode"
33
32
 
34
- command "cat", "Show code from a file or Pry's input buffer. Type `cat --help` for more information." do |*args|
35
- start_line = 0
36
- end_line = -1
37
- file_name = nil
38
- bt_index = 0
33
+ command_class "cat", "Show code from a file, Pry's input buffer, or the last exception." do
34
+ banner <<-USAGE
35
+ Usage: cat FILE
36
+ cat --ex [STACK_INDEX]
37
+ cat --in [INPUT_INDEX_OR_RANGE]
39
38
 
40
- opts = Slop.parse!(args) do |opt|
41
- opt.on :s, :start, "Start line (defaults to start of file)Line 1 is the first line.", true, :as => Integer do |line|
42
- start_line = line - 1
43
- end
39
+ cat is capable of showing part or all of a source file, the context of the
40
+ last exception, or an expression from Pry's input history.
44
41
 
45
- opt.on :e, :end, "End line (defaults to end of file). Line -1 is the last line", true, :as => Integer do |line|
46
- end_line = line - 1
47
- end
42
+ cat --ex defaults to showing the lines surrounding the location of the last
43
+ exception. Invoking it more than once travels up the exception's backtrace,
44
+ and providing a number shows the context of the given index of the backtrace.
45
+ USAGE
48
46
 
49
- opt.on :ex, "Show a window of N lines either side of the last exception (defaults to 5).", :optional => true, :as => Integer do |bt_index_arg|
50
- window_size = Pry.config.exception_window_size || 5
51
- ex = _pry_.last_exception
52
- next if !ex
53
- if bt_index_arg
54
- bt_index = bt_index_arg
55
- else
56
- bt_index = ex.bt_index
57
- end
58
- ex.bt_index = (bt_index + 1) % ex.backtrace.size
59
-
60
- ex_file, ex_line = ex.bt_source_location_for(bt_index)
61
- start_line = (ex_line - 1) - window_size
62
- start_line = start_line < 0 ? 0 : start_line
63
- end_line = (ex_line - 1) + window_size
64
- if ex_file && RbxPath.is_core_path?(ex_file)
65
- file_name = RbxPath.convert_path_to_full(ex_file)
47
+ def options(opt)
48
+ opt.on :ex, "Show the context of the last exception.", :optional => true, :as => Integer
49
+ opt.on :i, :in, "Show one or more entries from Pry's expression history.", :optional => true, :as => Range, :default => -5..-1
50
+
51
+ opt.on :s, :start, "Starting line (defaults to the first line).", :optional => true, :as => Integer
52
+ opt.on :e, :end, "Ending line (defaults to the last line).", :optional => true, :as => Integer
53
+ opt.on :l, :'line-numbers', "Show line numbers."
54
+ opt.on :t, :type, "The file type for syntax highlighting (e.g., 'ruby' or 'python').", true, :as => Symbol
55
+
56
+ opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
57
+ end
58
+
59
+ def process
60
+ handler = case
61
+ when opts.present?(:ex)
62
+ method :process_ex
63
+ when opts.present?(:in)
64
+ method :process_in
66
65
  else
67
- file_name = ex_file
66
+ method :process_file
68
67
  end
69
- end
70
68
 
71
- opt.on :i, :in, "Show entries from Pry's input expression history. Takes an index or range.", :optional => true, :as => Range, :default => -5..-1
69
+ output = handler.call do |code|
70
+ code.code_type = opts[:type] || :ruby
72
71
 
73
- opt.on :l, "line-numbers", "Show line numbers."
74
- opt.on :t, :type, "The specific file type for syntax higlighting (e.g ruby, python)", true, :as => Symbol
75
- opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
76
- opt.on :h, :help, "This message." do
77
- output.puts opt.help
72
+ code.between(opts[:start] || 1, opts[:end] || -1).
73
+ with_line_numbers(opts.present?(:'line-numbers') || opts.present?(:ex))
78
74
  end
75
+
76
+ render_output(output, opts)
79
77
  end
80
78
 
81
- next if opts.present?(:help)
79
+ def process_ex
80
+ window_size = Pry.config.default_window_size || 5
81
+ ex = _pry_.last_exception
82
+
83
+ raise CommandError, "No exception found." unless ex
82
84
 
83
- if opts.present?(:ex)
84
- if file_name.nil?
85
- raise CommandError, "No Exception or Exception has no associated file."
85
+ if opts[:ex].nil?
86
+ bt_index = ex.bt_index
87
+ ex.inc_bt_index
88
+ else
89
+ bt_index = opts[:ex]
86
90
  end
87
- else
88
- file_name = args.shift
91
+
92
+ ex_file, ex_line = ex.bt_source_location_for(bt_index)
93
+
94
+ raise CommandError, "The given backtrace level is out of bounds." unless ex_file
95
+
96
+ if RbxPath.is_core_path?(ex_file)
97
+ ex_file = RbxPath.convert_path_to_full(ex_file)
98
+ end
99
+
100
+ start_line = ex_line - window_size
101
+ start_line = 1 if start_line < 1
102
+ end_line = ex_line + window_size
103
+
104
+ header = unindent <<-HEADER
105
+ #{text.bold 'Exception:'} #{ex.class}: #{ex.message}
106
+ --
107
+ #{text.bold('From:')} #{ex_file} @ line #{ex_line} @ #{text.bold("level: #{bt_index}")} of backtrace (of #{ex.backtrace.size - 1}).
108
+
109
+ HEADER
110
+
111
+ code = yield(Pry::Code.from_file(ex_file).
112
+ between(start_line, end_line).
113
+ with_marker(ex_line))
114
+
115
+ "#{header}#{code}"
89
116
  end
90
117
 
91
- if opts.present?(:in)
118
+ def process_in
92
119
  normalized_range = absolute_index_range(opts[:i], _pry_.input_array.length)
93
120
  input_items = _pry_.input_array[normalized_range] || []
94
121
 
@@ -98,66 +125,37 @@ class Pry
98
125
  raise CommandError, "No expressions found."
99
126
  end
100
127
 
101
- if opts[:i].is_a?(Range)
128
+ if zipped_items.length > 1
102
129
  contents = ""
103
-
104
130
  zipped_items.each do |i, s|
105
131
  contents << "#{text.bold(i.to_s)}:\n"
106
-
107
- code = syntax_highlight_by_file_type_or_specified(s, nil, :ruby)
108
-
109
- if opts.present?(:'line-numbers')
110
- contents << text.indent(text.with_line_numbers(code, 1), 2)
111
- else
112
- contents << text.indent(code, 2)
113
- end
132
+ contents << yield(Pry::Code(s).with_indentation(2)).to_s
114
133
  end
115
134
  else
116
- contents = syntax_highlight_by_file_type_or_specified(zipped_items.first.last, nil, :ruby)
117
- end
118
- else
119
- unless file_name
120
- raise CommandError, "Must provide a file name."
135
+ contents = yield(Pry::Code(zipped_items.first.last))
121
136
  end
122
137
 
123
- begin
124
- contents, _, _ = read_between_the_lines(file_name, start_line, end_line)
125
- rescue Errno::ENOENT
126
- raise CommandError, "Could not find file: #{file_name}"
127
- end
138
+ contents
139
+ end
128
140
 
129
- contents = syntax_highlight_by_file_type_or_specified(contents, file_name, opts[:type])
141
+ def process_file
142
+ file_name = args.shift
130
143
 
131
- if opts.present?(:'line-numbers')
132
- contents = text.with_line_numbers contents, start_line + 1
144
+ unless file_name
145
+ raise CommandError, "Must provide a filename, --in, or --ex."
133
146
  end
134
- end
135
147
 
136
- # add the arrow pointing to line that caused the exception
137
- if opts.present?(:ex)
138
- ex_file, ex_line = _pry_.last_exception.bt_source_location_for(bt_index)
139
- contents = text.with_line_numbers contents, start_line + 1, :bright_red
148
+ file_name, line_num = file_name.split(':')
149
+ set_file_and_dir_locals(file_name)
140
150
 
141
- contents = contents.lines.each_with_index.map do |line, idx|
142
- l = idx + start_line
143
- if l == (ex_line - 1)
144
- " =>#{line}"
145
- else
146
- " #{line}"
147
- end
148
- end.join
149
-
150
- # header for exceptions
151
- output.puts "\n#{Pry::Helpers::Text.bold('Exception:')} #{_pry_.last_exception.class}: #{_pry_.last_exception.message}\n--"
152
- output.puts "#{Pry::Helpers::Text.bold('From:')} #{ex_file} @ line #{ex_line} @ #{text.bold('level: ')} #{bt_index} of backtrace (of #{_pry_.last_exception.backtrace.size - 1}).\n\n"
153
- end
151
+ code = yield(Pry::Code.from_file(file_name))
154
152
 
155
- set_file_and_dir_locals(file_name)
153
+ if line_num
154
+ code = code.around(line_num.to_i,
155
+ Pry.config.default_window_size || 7)
156
+ end
156
157
 
157
- if opts.present?(:flood)
158
- output.puts contents
159
- else
160
- stagger_output(contents)
158
+ code
161
159
  end
162
160
  end
163
161
  end
@@ -6,26 +6,21 @@ class Pry
6
6
 
7
7
  module_function
8
8
 
9
- # if start_line is not false then add line numbers starting with start_line
10
- def render_output(should_flood, start_line, text, color=:blue)
11
- if start_line
12
- text = Pry::Helpers::Text.with_line_numbers text, start_line, color
13
- end
14
-
15
- if should_flood
16
- output.puts text
17
- else
18
- stagger_output(text)
19
- end
20
- end
21
-
22
9
  # Open a temp file and yield it to the block, closing it after
23
10
  # @return [String] The path of the temp file
24
- def temp_file
25
- file = Tempfile.new(['pry', '.rb'])
11
+ def temp_file(ext='.rb')
12
+ file = Tempfile.new(['pry', ext])
26
13
  yield file
27
14
  ensure
28
- file.close(true)
15
+ file.close(true) if file
16
+ end
17
+
18
+ def render_output(str, opts={})
19
+ if opts[:flood]
20
+ output.puts str
21
+ else
22
+ stagger_output str
23
+ end
29
24
  end
30
25
 
31
26
  def get_method_or_raise(name, target, opts={}, omit_help=false)
@@ -34,7 +29,7 @@ class Pry
34
29
  if name && !meth
35
30
  command_error("The method '#{name}' could not be found.", omit_help)
36
31
  elsif !meth
37
- command_error("No method name given, and context is not a method.", omit_help)
32
+ command_error("No method name given, and context is not a method.", omit_help, NonMethodContextError)
38
33
  end
39
34
 
40
35
  (opts[:super] || 0).times do
@@ -49,9 +44,9 @@ class Pry
49
44
  meth
50
45
  end
51
46
 
52
- def command_error(message, omit_help)
47
+ def command_error(message, omit_help, klass=CommandError)
53
48
  message += " Type `#{command_name} --help` for help." unless omit_help
54
- raise CommandError, message
49
+ raise klass, message
55
50
  end
56
51
 
57
52
  def make_header(meth, content=meth.source)
@@ -66,63 +61,6 @@ class Pry
66
61
  header << "#{Pry::Helpers::Text.bold("Number of lines:")} #{content.each_line.count.to_s}\n"
67
62
  end
68
63
 
69
- def file_map
70
- {
71
- [".c", ".h"] => :c,
72
- [".cpp", ".hpp", ".cc", ".h", "cxx"] => :cpp,
73
- [".rb", "Rakefile", ".irbrc", ".gemspec", ".pryrc"] => :ruby,
74
- ".py" => :python,
75
- ".diff" => :diff,
76
- ".css" => :css,
77
- ".html" => :html,
78
- [".yaml", ".yml"] => :yaml,
79
- ".xml" => :xml,
80
- ".php" => :php,
81
- ".js" => :javascript,
82
- ".java" => :java,
83
- ".rhtml" => :rhtml,
84
- ".json" => :json
85
- }
86
- end
87
-
88
- def syntax_highlight_by_file_type_or_specified(contents, file_name, file_type)
89
- if file_type
90
- language_detected = file_type
91
- else
92
- _, language_detected = file_map.find do |k, v|
93
- Array(k).any? do |matcher|
94
- matcher == File.extname(file_name) || matcher == File.basename(file_name)
95
- end
96
- end
97
- end
98
-
99
- if Pry.color
100
- CodeRay.scan(contents, language_detected).term
101
- else
102
- contents
103
- end
104
- end
105
-
106
- # convert negative line numbers to positive by wrapping around
107
- # last line (as per array indexing with negative numbers)
108
- def normalized_line_number(line_number, total_lines)
109
- line_number < 0 ? line_number + total_lines : line_number
110
- end
111
-
112
- # returns the file content between the lines and the normalized
113
- # start and end line numbers.
114
- def read_between_the_lines(file_name, start_line, end_line)
115
- if file_name == Pry.eval_path
116
- content = Pry.line_buffer.drop(1).join
117
- else
118
- content = File.read(File.expand_path(file_name))
119
- end
120
- lines_array = content.each_line.to_a
121
-
122
- [lines_array[start_line..end_line].join, normalized_line_number(start_line, lines_array.size),
123
- normalized_line_number(end_line, lines_array.size)]
124
- end
125
-
126
64
  def process_rdoc(comment, code_type)
127
65
  comment = comment.dup
128
66
  comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
data/lib/pry/hooks.rb CHANGED
@@ -20,6 +20,10 @@ class Pry
20
20
  end
21
21
  protected :hooks
22
22
 
23
+ def errors
24
+ @errors ||= []
25
+ end
26
+
23
27
  # Destructively merge the contents of two `Pry:Hooks` instances.
24
28
  # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge
25
29
 
@@ -89,7 +93,14 @@ class Pry
89
93
  # silence warnings to get rid of 1.8's "warning: multiple values
90
94
  # for a block parameter" warnings
91
95
  Pry::Helpers::BaseHelpers.silence_warnings do
92
- @hooks[event_name].map { |hook_name, callable| callable.call(*args, &block) }.last
96
+ @hooks[event_name].map do |hook_name, callable|
97
+ begin
98
+ callable.call(*args, &block)
99
+ rescue RescuableException => e
100
+ errors << e
101
+ e
102
+ end
103
+ end.last
93
104
  end
94
105
  end
95
106
 
data/lib/pry/pry_class.rb CHANGED
@@ -116,7 +116,7 @@ class Pry
116
116
  pry_instance.backtrace = caller.tap(&:shift)
117
117
 
118
118
  # yield the binding_stack to the hook for modification
119
- Pry.config.hooks.exec_hook(
119
+ pry_instance.exec_hook(
120
120
  :when_started,
121
121
  binding_stack = [target],
122
122
  options,
@@ -220,8 +220,8 @@ class Pry
220
220
  config.prompt = DEFAULT_PROMPT
221
221
  config.print = DEFAULT_PRINT
222
222
  config.exception_handler = DEFAULT_EXCEPTION_HANDLER
223
- config.exception_window_size = 5
224
223
  config.exception_whitelist = DEFAULT_EXCEPTION_WHITELIST
224
+ config.default_window_size = 5
225
225
  config.hooks = DEFAULT_HOOKS
226
226
  config.input_stack = []
227
227
  config.color = Helpers::BaseHelpers.use_ansi_codes?
@@ -237,7 +237,7 @@ class Pry
237
237
  config.collision_warning = false
238
238
 
239
239
  config.gist ||= OpenStruct.new
240
- config.gist.inspecter = proc &:pretty_inspect
240
+ config.gist.inspecter = proc(&:pretty_inspect)
241
241
 
242
242
  config.plugins ||= OpenStruct.new
243
243
  config.plugins.enabled = true
@@ -15,10 +15,11 @@ class Pry
15
15
  attr_accessor :binding_stack
16
16
 
17
17
  attr_accessor :last_result
18
- attr_accessor :last_exception
19
18
  attr_accessor :last_file
20
19
  attr_accessor :last_dir
21
20
 
21
+ attr_reader :last_exception
22
+
22
23
  attr_reader :input_array
23
24
  attr_reader :output_array
24
25
 
@@ -142,7 +143,7 @@ class Pry
142
143
  # Initialize the repl session.
143
144
  # @param [Binding] target The target binding for the session.
144
145
  def repl_prologue(target)
145
- hooks.exec_hook :before_session, output, target, self
146
+ exec_hook :before_session, output, target, self
146
147
  initialize_special_locals(target)
147
148
 
148
149
  @input_array << nil # add empty input so _in_ and _out_ match
@@ -154,7 +155,7 @@ class Pry
154
155
  # Clean-up after the repl session.
155
156
  # @param [Binding] target The target binding for the session.
156
157
  def repl_epilogue(target)
157
- hooks.exec_hook :after_session, output, target, self
158
+ exec_hook :after_session, output, target, self
158
159
 
159
160
  Pry.active_sessions -= 1
160
161
  binding_stack.pop
@@ -231,10 +232,11 @@ class Pry
231
232
 
232
233
  result
233
234
  rescue RescuableException => e
234
- result = set_last_exception(e, target)
235
+ self.last_exception = e
236
+ e
235
237
  ensure
236
238
  update_input_history(code)
237
- hooks.exec_hook :after_eval, result, self
239
+ exec_hook :after_eval, result, self
238
240
  end
239
241
 
240
242
  # Perform a read.
@@ -270,7 +272,7 @@ class Pry
270
272
 
271
273
  @suppress_output = true if eval_string =~ /;\Z/ || eval_string.empty?
272
274
 
273
- hooks.exec_hook :after_read, eval_string, self
275
+ exec_hook :after_read, eval_string, self
274
276
  eval_string
275
277
  end
276
278
 
@@ -337,6 +339,7 @@ class Pry
337
339
 
338
340
  if original_val != indented_val && output.tty? && Pry::Helpers::BaseHelpers.use_ansi_codes? && Pry.config.correct_indent
339
341
  output.print @indent.correct_indentation(current_prompt + indented_val, original_val.length - indented_val.length)
342
+ output.flush
340
343
  end
341
344
  else
342
345
  indented_val = val
@@ -402,6 +405,25 @@ class Pry
402
405
  Pry::Command::VOID_VALUE
403
406
  end
404
407
 
408
+ # Execute the specified hook.
409
+ # @param [Symbol] name The hook name to execute
410
+ # @param [*Object] args The arguments to pass to the hook
411
+ # @return [Object, Exception] The return value of the hook or the exception raised
412
+ #
413
+ # If executing a hook raises an exception, we log that and then continue sucessfully.
414
+ # To debug such errors, use the global variable $pry_hook_error, which is set as a
415
+ # result.
416
+ def exec_hook(name, *args, &block)
417
+ e_before = hooks.errors.size
418
+ hooks.exec_hook(name, *args, &block).tap do
419
+ hooks.errors[e_before..-1].each do |e|
420
+ output.puts "#{name} hook failed: #{e.class}: #{e.message}"
421
+ output.puts "#{e.backtrace.first}"
422
+ output.puts "(see _pry_.hooks.errors to debug)"
423
+ end
424
+ end
425
+ end
426
+
405
427
  # Set the last result of an eval.
406
428
  # This method should not need to be invoked directly.
407
429
  # @param [Object] result The result.
@@ -415,16 +437,18 @@ class Pry
415
437
  end
416
438
 
417
439
  # Set the last exception for a session.
418
- # This method should not need to be invoked directly.
419
- # @param [Exception] ex The exception.
420
- # @param [Binding] target The binding to set `_ex_` on.
421
- def set_last_exception(ex, target)
440
+ # @param [Exception] ex
441
+ def last_exception=(ex)
422
442
  class << ex
423
443
  attr_accessor :file, :line, :bt_index
424
444
  def bt_source_location_for(index)
425
445
  backtrace[index] =~ /(.*):(\d+)/
426
446
  [$1, $2.to_i]
427
447
  end
448
+
449
+ def inc_bt_index
450
+ @bt_index = (@bt_index + 1) % backtrace.size
451
+ end
428
452
  end
429
453
 
430
454
  ex.bt_index = 0
@@ -432,8 +456,7 @@ class Pry
432
456
 
433
457
  @last_result_is_exception = true
434
458
  @output_array << ex
435
-
436
- self.last_exception = ex
459
+ @last_exception = ex
437
460
  end
438
461
 
439
462
  # Update Pry's internal state after evalling code.
@@ -569,9 +592,11 @@ class Pry
569
592
  elsif defined?(Rubinius::Melbourne)
570
593
  Rubinius::Melbourne.parse_string(str, Pry.eval_path)
571
594
  else
572
- catch(:valid) {
573
- eval("BEGIN{throw :valid}\n#{str}", binding, Pry.eval_path)
574
- }
595
+ catch(:valid) do
596
+ Helpers::BaseHelpers.silence_warnings do
597
+ eval("BEGIN{throw :valid}\n#{str}", binding, Pry.eval_path)
598
+ end
599
+ end
575
600
  end
576
601
 
577
602
  # Assert that a line which ends with a , is incomplete.