pry 0.9.7.4-i386-mswin32 → 0.9.8-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.
Files changed (65) hide show
  1. data/.gitignore +2 -3
  2. data/CHANGELOG +43 -0
  3. data/README.markdown +3 -1
  4. data/Rakefile +51 -32
  5. data/bin/pry +2 -80
  6. data/lib/pry.rb +33 -26
  7. data/lib/pry/cli.rb +152 -0
  8. data/lib/pry/code.rb +351 -0
  9. data/lib/pry/command.rb +422 -0
  10. data/lib/pry/command_set.rb +259 -129
  11. data/lib/pry/commands.rb +0 -1
  12. data/lib/pry/config.rb +43 -9
  13. data/lib/pry/default_commands/context.rb +109 -92
  14. data/lib/pry/default_commands/documentation.rb +174 -63
  15. data/lib/pry/default_commands/easter_eggs.rb +26 -2
  16. data/lib/pry/default_commands/gems.rb +65 -37
  17. data/lib/pry/default_commands/input.rb +175 -243
  18. data/lib/pry/default_commands/introspection.rb +173 -112
  19. data/lib/pry/default_commands/ls.rb +96 -114
  20. data/lib/pry/default_commands/shell.rb +175 -70
  21. data/lib/pry/helpers/base_helpers.rb +7 -2
  22. data/lib/pry/helpers/command_helpers.rb +71 -77
  23. data/lib/pry/helpers/options_helpers.rb +10 -41
  24. data/lib/pry/helpers/text.rb +24 -4
  25. data/lib/pry/history.rb +55 -17
  26. data/lib/pry/history_array.rb +2 -0
  27. data/lib/pry/hooks.rb +252 -0
  28. data/lib/pry/indent.rb +9 -5
  29. data/lib/pry/method.rb +149 -50
  30. data/lib/pry/plugins.rb +12 -4
  31. data/lib/pry/pry_class.rb +69 -26
  32. data/lib/pry/pry_instance.rb +187 -115
  33. data/lib/pry/version.rb +1 -1
  34. data/lib/pry/wrapped_module.rb +73 -0
  35. data/man/pry.1 +195 -0
  36. data/man/pry.1.html +204 -0
  37. data/man/pry.1.ronn +141 -0
  38. data/pry.gemspec +29 -32
  39. data/test/helper.rb +32 -36
  40. data/test/test_cli.rb +78 -0
  41. data/test/test_code.rb +201 -0
  42. data/test/test_command.rb +327 -0
  43. data/test/test_command_integration.rb +512 -0
  44. data/test/test_command_set.rb +338 -12
  45. data/test/test_completion.rb +1 -1
  46. data/test/test_default_commands.rb +1 -2
  47. data/test/test_default_commands/test_context.rb +27 -5
  48. data/test/test_default_commands/test_documentation.rb +20 -8
  49. data/test/test_default_commands/test_input.rb +84 -45
  50. data/test/test_default_commands/test_introspection.rb +74 -17
  51. data/test/test_default_commands/test_ls.rb +9 -36
  52. data/test/test_default_commands/test_shell.rb +240 -13
  53. data/test/test_hooks.rb +490 -0
  54. data/test/test_indent.rb +2 -0
  55. data/test/test_method.rb +60 -0
  56. data/test/test_pry.rb +29 -904
  57. data/test/test_pry_defaults.rb +380 -0
  58. data/test/test_pry_history.rb +24 -24
  59. data/test/test_syntax_checking.rb +63 -0
  60. data/test/test_wrapped_module.rb +71 -0
  61. metadata +50 -39
  62. data/lib/pry/command_context.rb +0 -53
  63. data/lib/pry/command_processor.rb +0 -181
  64. data/lib/pry/extended_commands/user_command_api.rb +0 -65
  65. data/test/test_command_processor.rb +0 -176
@@ -1,4 +1,3 @@
1
- require "pry/command_processor.rb"
2
1
  require "pry/indent"
3
2
 
4
3
  class Pry
@@ -8,7 +7,6 @@ class Pry
8
7
  attr_accessor :commands
9
8
  attr_accessor :print
10
9
  attr_accessor :exception_handler
11
- attr_accessor :hooks
12
10
  attr_accessor :input_stack
13
11
 
14
12
  attr_accessor :custom_completions
@@ -16,13 +14,32 @@ class Pry
16
14
  attr_accessor :binding_stack
17
15
 
18
16
  attr_accessor :last_result
19
- attr_accessor :last_exception
20
17
  attr_accessor :last_file
21
18
  attr_accessor :last_dir
22
19
 
20
+ attr_reader :last_exception
21
+
23
22
  attr_reader :input_array
24
23
  attr_reader :output_array
25
24
 
25
+ attr_accessor :backtrace
26
+
27
+ # Special treatment for hooks as we want to alert people of the
28
+ # changed API
29
+ attr_reader :hooks
30
+
31
+ # FIXME:
32
+ # This is a hack to alert people of the new API.
33
+ # @param [Pry::Hooks] v Only accept `Pry::Hooks` now!
34
+ def hooks=(v)
35
+ if v.is_a?(Hash)
36
+ warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
37
+ @hooks = Pry::Hooks.from_hash(v)
38
+ else
39
+ @hooks = v
40
+ end
41
+ end
42
+
26
43
  # Create a new `Pry` object.
27
44
  # @param [Hash] options The optional configuration parameters.
28
45
  # @option options [#readline] :input The object to use for input.
@@ -35,7 +52,6 @@ class Pry
35
52
  def initialize(options={})
36
53
  refresh(options)
37
54
 
38
- @command_processor = CommandProcessor.new(self)
39
55
  @binding_stack = []
40
56
  @indent = Pry::Indent.new
41
57
  end
@@ -57,7 +73,7 @@ class Pry
57
73
  end
58
74
 
59
75
  defaults.merge!(options).each do |key, value|
60
- send "#{key}=", value
76
+ send("#{key}=", value) if respond_to?("#{key}=")
61
77
  end
62
78
 
63
79
  true
@@ -106,21 +122,14 @@ class Pry
106
122
  @output_array = Pry::HistoryArray.new(size)
107
123
  end
108
124
 
109
- # Execute the hook `hook_name`, if it is defined.
110
- # @param [Symbol] hook_name The hook to execute
111
- # @param [Array] args The arguments to pass to the hook.
112
- def exec_hook(hook_name, *args, &block)
113
- hooks[hook_name].call(*args, &block) if hooks[hook_name]
114
- end
115
-
116
125
  # Make sure special locals exist at start of session
117
126
  def initialize_special_locals(target)
118
127
  inject_local("_in_", @input_array, target)
119
128
  inject_local("_out_", @output_array, target)
120
129
  inject_local("_pry_", self, target)
121
- inject_local("_ex_", nil, target)
122
- inject_local("_file_", nil, target)
123
- inject_local("_dir_", nil, target)
130
+ inject_local("_ex_", last_exception, target)
131
+ inject_local("_file_", last_file, target)
132
+ inject_local("_dir_", last_dir, target)
124
133
 
125
134
  # without this line we get 1 test failure, ask Mon_Ouie
126
135
  set_last_result(nil, target)
@@ -136,13 +145,13 @@ class Pry
136
145
 
137
146
  def special_locals
138
147
  {
139
- :_in_ => @input_array,
140
- :_out_ => @output_array,
141
- :_pry_ => self,
142
- :_ex_ => last_exception,
148
+ :_in_ => @input_array,
149
+ :_out_ => @output_array,
150
+ :_pry_ => self,
151
+ :_ex_ => last_exception,
143
152
  :_file_ => last_file,
144
- :_dir_ => last_dir,
145
- :_ => last_result
153
+ :_dir_ => last_dir,
154
+ :_ => last_result
146
155
  }
147
156
  end
148
157
 
@@ -188,8 +197,9 @@ class Pry
188
197
  end
189
198
  end
190
199
 
200
+ break_data || nil
201
+ ensure
191
202
  repl_epilogue(target)
192
- break_data || target_self
193
203
  end
194
204
 
195
205
  # Perform a read-eval-print.
@@ -232,15 +242,16 @@ class Pry
232
242
 
233
243
  code = r(target)
234
244
 
235
- result = set_last_result(target.eval(code, Pry.eval_path, Pry.current_line), target)
245
+ result = target.eval(code, Pry.eval_path, Pry.current_line)
246
+ set_last_result(result, target, code)
247
+
236
248
  result
237
- rescue CommandError, Slop::InvalidOptionError => e
238
- output.puts "Error: #{e.message}"
239
- @suppress_output = true
240
249
  rescue RescuableException => e
241
- set_last_exception(e, target)
250
+ self.last_exception = e
251
+ e
242
252
  ensure
243
253
  update_input_history(code)
254
+ exec_hook :after_eval, result, self
244
255
  end
245
256
 
246
257
  # Perform a read.
@@ -259,16 +270,24 @@ class Pry
259
270
 
260
271
  val = ""
261
272
  loop do
262
- val = retrieve_line(eval_string, target)
263
-
264
- # eval_string may be mutated by this method
265
- process_line(val, eval_string, target)
273
+ begin
274
+ # eval_string will probably be mutated by this method
275
+ retrieve_line(eval_string, target)
276
+ rescue CommandError, Slop::InvalidOptionError => e
277
+ output.puts "Error: #{e.message}"
278
+ end
266
279
 
267
- break if valid_expression?(eval_string)
280
+ begin
281
+ break if complete_expression?(eval_string)
282
+ rescue SyntaxError => e
283
+ output.puts "SyntaxError: #{e.message.sub(/.*syntax error, */m, '')}"
284
+ eval_string = ""
285
+ end
268
286
  end
269
287
 
270
288
  @suppress_output = true if eval_string =~ /;\Z/ || eval_string.empty?
271
289
 
290
+ exec_hook :after_read, eval_string, self
272
291
  eval_string
273
292
  end
274
293
 
@@ -294,10 +313,15 @@ class Pry
294
313
  end
295
314
  end
296
315
 
297
- # Read a line of input and check for ^d, also determine prompt to use.
298
- # This method should not need to be invoked directly. This method also
299
- # automatically indents the input value using Pry::Indent if auto
300
- # indenting is enabled.
316
+ def should_force_encoding?(eval_string, val)
317
+ eval_string.empty? && val.respond_to?(:encoding) && val.encoding != eval_string.encoding
318
+ end
319
+ private :should_force_encoding?
320
+
321
+ # Read and process a line of input -- check for ^D, determine which prompt to
322
+ # use, rewrite the indentation if `Pry.config.auto_indent` is enabled, and,
323
+ # if the line is a command, process it and alter the eval_string accordingly.
324
+ # This method should not need to be invoked directly.
301
325
  #
302
326
  # @param [String] eval_string The cumulative lines of input.
303
327
  # @param [Binding] target The target of the session.
@@ -305,45 +329,60 @@ class Pry
305
329
  def retrieve_line(eval_string, target)
306
330
  @indent.reset if eval_string.empty?
307
331
 
308
- current_prompt = select_prompt(eval_string.empty?, target.eval('self'))
332
+ current_prompt = select_prompt(eval_string, target)
309
333
  indentation = Pry.config.auto_indent ? @indent.indent_level : ''
310
334
 
311
- val = readline(current_prompt + indentation)
335
+ val = readline("#{current_prompt}#{indentation}")
312
336
 
313
337
  # invoke handler if we receive EOF character (^D)
314
338
  if !val
315
339
  output.puts ""
316
340
  Pry.config.control_d_handler.call(eval_string, self)
317
- ""
318
- else
319
- # Change the eval_string into the input encoding (Issue 284)
320
- # TODO: This wouldn't be necessary if the eval_string was constructed from
321
- # input strings only.
322
- if eval_string.empty? && val.respond_to?(:encoding) && val.encoding != eval_string.encoding
323
- eval_string.force_encoding(val.encoding)
324
- end
341
+ return
342
+ end
325
343
 
326
- if !@command_processor.valid_command?(val, target) && Pry.config.auto_indent && !input.is_a?(StringIO)
327
- orig_val = "#{indentation}#{val}"
328
- val = @indent.indent(val)
344
+ # Change the eval_string into the input encoding (Issue 284)
345
+ # TODO: This wouldn't be necessary if the eval_string was constructed from
346
+ # input strings only.
347
+ if should_force_encoding?(eval_string, val)
348
+ eval_string.force_encoding(val.encoding)
349
+ end
329
350
 
330
- if orig_val != val && output.tty? && Pry::Helpers::BaseHelpers.use_ansi_codes? && Pry.config.correct_indent
331
- output.print @indent.correct_indentation(current_prompt + val, orig_val.length - val.length)
332
- end
351
+ if Pry.config.auto_indent && !input.is_a?(StringIO)
352
+ original_val = "#{indentation}#{val}"
353
+ indented_val = @indent.indent(val)
354
+
355
+ if original_val != indented_val && output.tty? && Pry::Helpers::BaseHelpers.use_ansi_codes? && Pry.config.correct_indent
356
+ output.print @indent.correct_indentation(current_prompt + indented_val, original_val.length - indented_val.length)
357
+ output.flush
333
358
  end
359
+ else
360
+ indented_val = val
361
+ end
334
362
 
335
- Pry.history << val.dup unless input.is_a?(StringIO)
336
- val
363
+ begin
364
+ if !process_command(val, eval_string, target)
365
+ eval_string << "#{indented_val.rstrip}\n" unless val.empty?
366
+ end
367
+ ensure
368
+ Pry.history << indented_val unless input.is_a?(StringIO)
337
369
  end
338
370
  end
339
371
 
340
- # Process the line received.
372
+ # If the given line is a valid command, process it in the context of the
373
+ # current `eval_string` and context.
341
374
  # This method should not need to be invoked directly.
342
375
  # @param [String] val The line to process.
343
376
  # @param [String] eval_string The cumulative lines of input.
344
377
  # @param [Binding] target The target of the Pry session.
345
- def process_line(val, eval_string, target)
346
- result = @command_processor.process_commands(val, eval_string, target)
378
+ # @return [Boolean] `true` if `val` is a command, `false` otherwise
379
+ def process_command(val, eval_string, target)
380
+ result = commands.process_line(val, {
381
+ :target => target,
382
+ :output => output,
383
+ :eval_string => eval_string,
384
+ :pry_instance => self
385
+ })
347
386
 
348
387
  # set a temporary (just so we can inject the value we want into eval_string)
349
388
  Thread.current[:__pry_cmd_result__] = result
@@ -351,16 +390,16 @@ class Pry
351
390
  # note that `result` wraps the result of command processing; if a
352
391
  # command was matched and invoked then `result.command?` returns true,
353
392
  # otherwise it returns false.
354
- if result.command? && !result.void_command?
355
-
356
- # the command that was invoked was non-void (had a return value) and so we make
357
- # the value of the current expression equal to the return value
358
- # of the command.
359
- eval_string.replace "Thread.current[:__pry_cmd_result__].retval\n"
393
+ if result.command?
394
+ if !result.void_command?
395
+ # the command that was invoked was non-void (had a return value) and so we make
396
+ # the value of the current expression equal to the return value
397
+ # of the command.
398
+ eval_string.replace "Thread.current[:__pry_cmd_result__].retval\n"
399
+ end
400
+ true
360
401
  else
361
- # only commands should have an empty `val`
362
- # so this ignores their result
363
- eval_string << "#{val.rstrip}\n" if !val.empty?
402
+ false
364
403
  end
365
404
  end
366
405
 
@@ -368,36 +407,63 @@ class Pry
368
407
  # @param [String] val The command (and its params) to execute.
369
408
  # @param [String] eval_string The current input buffer.
370
409
  # @param [Binding] target The binding to use..
371
- # @return [Pry::CommandContext::VOID_VALUE]
410
+ # @return [Pry::Command::VOID_VALUE]
372
411
  # @example
373
412
  # pry_instance.run_command("ls -m")
374
413
  def run_command(val, eval_string = "", target = binding_stack.last)
375
- process_line(val, eval_string, target)
376
- Pry::CommandContext::VOID_VALUE
414
+ commands.process_line(val,
415
+ :eval_string => eval_string,
416
+ :target => target,
417
+ :pry_instance => self,
418
+ :output => output
419
+ )
420
+ Pry::Command::VOID_VALUE
421
+ end
422
+
423
+ # Execute the specified hook.
424
+ # @param [Symbol] name The hook name to execute
425
+ # @param [*Object] args The arguments to pass to the hook
426
+ # @return [Object, Exception] The return value of the hook or the exception raised
427
+ #
428
+ # If executing a hook raises an exception, we log that and then continue sucessfully.
429
+ # To debug such errors, use the global variable $pry_hook_error, which is set as a
430
+ # result.
431
+ def exec_hook(name, *args, &block)
432
+ e_before = hooks.errors.size
433
+ hooks.exec_hook(name, *args, &block).tap do
434
+ hooks.errors[e_before..-1].each do |e|
435
+ output.puts "#{name} hook failed: #{e.class}: #{e.message}"
436
+ output.puts "#{e.backtrace.first}"
437
+ output.puts "(see _pry_.hooks.errors to debug)"
438
+ end
439
+ end
377
440
  end
378
441
 
379
442
  # Set the last result of an eval.
380
443
  # This method should not need to be invoked directly.
381
444
  # @param [Object] result The result.
382
445
  # @param [Binding] target The binding to set `_` on.
383
- def set_last_result(result, target)
446
+ # @param [String] code The code that was run.
447
+ def set_last_result(result, target, code="")
384
448
  @last_result_is_exception = false
385
449
  @output_array << result
386
450
 
387
- self.last_result = result
451
+ self.last_result = result unless code =~ /\A\s*\z/
388
452
  end
389
453
 
390
454
  # Set the last exception for a session.
391
- # This method should not need to be invoked directly.
392
- # @param [Exception] ex The exception.
393
- # @param [Binding] target The binding to set `_ex_` on.
394
- def set_last_exception(ex, target)
455
+ # @param [Exception] ex
456
+ def last_exception=(ex)
395
457
  class << ex
396
458
  attr_accessor :file, :line, :bt_index
397
459
  def bt_source_location_for(index)
398
460
  backtrace[index] =~ /(.*):(\d+)/
399
461
  [$1, $2.to_i]
400
462
  end
463
+
464
+ def inc_bt_index
465
+ @bt_index = (@bt_index + 1) % backtrace.size
466
+ end
401
467
  end
402
468
 
403
469
  ex.bt_index = 0
@@ -405,8 +471,7 @@ class Pry
405
471
 
406
472
  @last_result_is_exception = true
407
473
  @output_array << ex
408
-
409
- self.last_exception = ex
474
+ @last_exception = ex
410
475
  end
411
476
 
412
477
  # Update Pry's internal state after evalling code.
@@ -480,14 +545,17 @@ class Pry
480
545
 
481
546
  # Returns the appropriate prompt to use.
482
547
  # This method should not need to be invoked directly.
483
- # @param [Boolean] first_line Whether this is the first line of input
484
- # (and not multi-line input).
485
- # @param [Object] target_self The receiver of the Pry session.
548
+ # @param [String] eval_string The current input buffer.
549
+ # @param [Binding] target The target Binding of the Pry session.
486
550
  # @return [String] The prompt.
487
- def select_prompt(first_line, target_self)
551
+ def select_prompt(eval_string, target)
552
+ target_self = target.eval('self')
488
553
 
489
- if first_line
554
+ # If input buffer is empty then use normal prompt
555
+ if eval_string.empty?
490
556
  Array(prompt).first.call(target_self, binding_stack.size - 1, self)
557
+
558
+ # Otherwise use the wait prompt (indicating multi-line expression)
491
559
  else
492
560
  Array(prompt).last.call(target_self, binding_stack.size - 1, self)
493
561
  end
@@ -526,45 +594,49 @@ class Pry
526
594
  prompt_stack.size > 1 ? prompt_stack.pop : prompt
527
595
  end
528
596
 
529
- if RUBY_VERSION =~ /1.9/ && RUBY_ENGINE == "ruby"
530
- require 'ripper'
531
-
532
- # Determine if a string of code is a valid Ruby expression.
533
- # Ruby 1.9 uses Ripper, Ruby 1.8 uses RubyParser.
534
- # @param [String] code The code to validate.
535
- # @return [Boolean] Whether or not the code is a valid Ruby expression.
536
- # @example
537
- # valid_expression?("class Hello") #=> false
538
- # valid_expression?("class Hello; end") #=> true
539
- def valid_expression?(code)
540
- !!Ripper::SexpBuilder.new(code).parse
597
+ # Determine if a string of code is a complete Ruby expression.
598
+ # @param [String] code The code to validate.
599
+ # @return [Boolean] Whether or not the code is a complete Ruby expression.
600
+ # @raise [SyntaxError] Any SyntaxError that does not represent incompleteness.
601
+ # @example
602
+ # complete_expression?("class Hello") #=> false
603
+ # complete_expression?("class Hello; end") #=> true
604
+ def complete_expression?(str)
605
+ if defined?(Rubinius::Melbourne19) && RUBY_VERSION =~ /^1\.9/
606
+ Rubinius::Melbourne19.parse_string(str, Pry.eval_path)
607
+ elsif defined?(Rubinius::Melbourne)
608
+ Rubinius::Melbourne.parse_string(str, Pry.eval_path)
609
+ else
610
+ catch(:valid) do
611
+ Helpers::BaseHelpers.silence_warnings do
612
+ eval("BEGIN{throw :valid}\n#{str}", binding, Pry.eval_path)
613
+ end
614
+ end
541
615
  end
542
616
 
543
- elsif RUBY_VERSION =~ /1.9/ && RUBY_ENGINE == 'jruby'
544
-
545
- # JRuby doesn't have Ripper, so use its native parser for 1.9 mode.
546
- def valid_expression?(code)
547
- JRuby.parse(code)
548
- true
549
- rescue SyntaxError
617
+ # Assert that a line which ends with a , is incomplete.
618
+ str !~ /[,]\z/
619
+ rescue SyntaxError => e
620
+ if incomplete_user_input_exception?(e)
550
621
  false
622
+ else
623
+ raise e
551
624
  end
625
+ end
552
626
 
553
- else
554
- require 'ruby_parser'
555
-
556
- # Determine if a string of code is a valid Ruby expression.
557
- # Ruby 1.9 uses Ripper, Ruby 1.8 uses RubyParser.
558
- # @param [String] code The code to validate.
559
- # @return [Boolean] Whether or not the code is a valid Ruby expression.
560
- # @example
561
- # valid_expression?("class Hello") #=> false
562
- # valid_expression?("class Hello; end") #=> true
563
- def valid_expression?(code)
564
- # NOTE: we're using .dup because RubyParser mutates the input
565
- RubyParser.new.parse(code.dup)
627
+ # Check whether the exception indicates that the user should input more.
628
+ #
629
+ # @param [SyntaxError] the exception object that was raised.
630
+ # @param [Array<String>] The stack frame of the function that executed eval.
631
+ # @return [Boolean]
632
+ #
633
+ def incomplete_user_input_exception?(ex)
634
+ case ex.message
635
+ when /unexpected (\$end|end-of-file|END_OF_FILE)/, # mri, jruby, ironruby
636
+ /unterminated (quoted string|string|regexp) meets end of file/, # "quoted string" is ironruby
637
+ /missing 'end' for/, /: expecting '[})\]]'$/, /can't find string ".*" anywhere before EOF/, /expecting keyword_end/ # rbx
566
638
  true
567
- rescue Racc::ParseError, SyntaxError
639
+ else
568
640
  false
569
641
  end
570
642
  end