pry 0.9.9.6pre2-i386-mswin32 → 0.9.10-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 (68) hide show
  1. data/CHANGELOG +41 -0
  2. data/CONTRIBUTORS +27 -26
  3. data/README.markdown +4 -4
  4. data/Rakefile +2 -2
  5. data/lib/pry.rb +25 -19
  6. data/lib/pry/cli.rb +31 -10
  7. data/lib/pry/code.rb +41 -83
  8. data/lib/pry/command.rb +87 -76
  9. data/lib/pry/command_set.rb +13 -20
  10. data/lib/pry/completion.rb +139 -121
  11. data/lib/pry/config.rb +4 -0
  12. data/lib/pry/core_extensions.rb +88 -31
  13. data/lib/pry/default_commands/cd.rb +31 -8
  14. data/lib/pry/default_commands/context.rb +4 -58
  15. data/lib/pry/default_commands/easter_eggs.rb +1 -1
  16. data/lib/pry/default_commands/editing.rb +21 -14
  17. data/lib/pry/default_commands/find_method.rb +5 -7
  18. data/lib/pry/default_commands/gist.rb +187 -0
  19. data/lib/pry/default_commands/hist.rb +6 -6
  20. data/lib/pry/default_commands/input_and_output.rb +73 -129
  21. data/lib/pry/default_commands/introspection.rb +107 -52
  22. data/lib/pry/default_commands/ls.rb +1 -1
  23. data/lib/pry/default_commands/misc.rb +0 -5
  24. data/lib/pry/default_commands/whereami.rb +92 -0
  25. data/lib/pry/helpers/base_helpers.rb +6 -1
  26. data/lib/pry/helpers/command_helpers.rb +30 -9
  27. data/lib/pry/helpers/documentation_helpers.rb +7 -7
  28. data/lib/pry/helpers/options_helpers.rb +1 -1
  29. data/lib/pry/helpers/text.rb +7 -9
  30. data/lib/pry/history.rb +15 -2
  31. data/lib/pry/hooks.rb +1 -1
  32. data/lib/pry/indent.rb +17 -10
  33. data/lib/pry/method.rb +35 -19
  34. data/lib/pry/module_candidate.rb +130 -0
  35. data/lib/pry/pry_class.rb +54 -22
  36. data/lib/pry/pry_instance.rb +71 -14
  37. data/lib/pry/repl_file_loader.rb +80 -0
  38. data/lib/pry/version.rb +1 -1
  39. data/lib/pry/wrapped_module.rb +121 -142
  40. data/pry.gemspec +13 -13
  41. data/test/candidate_helper1.rb +11 -0
  42. data/test/candidate_helper2.rb +8 -0
  43. data/test/helper.rb +16 -0
  44. data/test/test_code.rb +1 -1
  45. data/test/test_command.rb +364 -270
  46. data/test/test_command_integration.rb +235 -267
  47. data/test/test_completion.rb +36 -0
  48. data/test/test_control_d_handler.rb +45 -0
  49. data/test/test_default_commands/example.erb +5 -0
  50. data/test/test_default_commands/test_cd.rb +316 -11
  51. data/test/test_default_commands/test_context.rb +143 -192
  52. data/test/test_default_commands/test_documentation.rb +81 -14
  53. data/test/test_default_commands/test_find_method.rb +10 -2
  54. data/test/test_default_commands/test_input.rb +102 -111
  55. data/test/test_default_commands/test_introspection.rb +17 -12
  56. data/test/test_default_commands/test_ls.rb +8 -6
  57. data/test/test_default_commands/test_shell.rb +18 -15
  58. data/test/test_default_commands/test_show_source.rb +170 -44
  59. data/test/test_exception_whitelist.rb +6 -2
  60. data/test/test_hooks.rb +32 -0
  61. data/test/test_input_stack.rb +19 -16
  62. data/test/test_method.rb +0 -4
  63. data/test/test_prompt.rb +60 -0
  64. data/test/test_pry.rb +23 -31
  65. data/test/test_pry_defaults.rb +75 -57
  66. data/test/test_syntax_checking.rb +12 -11
  67. data/test/test_wrapped_module.rb +103 -0
  68. metadata +72 -26
data/lib/pry/pry_class.rb CHANGED
@@ -5,7 +5,8 @@ require 'pry/config'
5
5
  class Pry
6
6
 
7
7
  # The RC Files to load.
8
- RC_FILES = ["~/.pryrc", "./.pryrc"]
8
+ RC_FILES = ["~/.pryrc"]
9
+ LOCAL_RC_FILE = "./.pryrc"
9
10
 
10
11
  # class accessors
11
12
  class << self
@@ -43,12 +44,12 @@ class Pry
43
44
  # @return [Boolean] Whether Pry was activated from the command line.
44
45
  attr_accessor :cli
45
46
 
46
- # @return [Fixnum] The number of active Pry sessions.
47
- attr_accessor :active_sessions
48
-
49
47
  # @return [Boolean] Whether Pry sessions are quiet by default.
50
48
  attr_accessor :quiet
51
49
 
50
+ # @return [Binding] A top level binding with no local variables
51
+ attr_accessor :toplevel_binding
52
+
52
53
  # plugin forwardables
53
54
  def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
54
55
 
@@ -56,19 +57,31 @@ class Pry
56
57
  :hooks, :color, :pager, :editor, :memory_size, :input_stack, :extra_sticky_locals
57
58
  end
58
59
 
60
+
61
+ # Load the given file in the context of `Pry.toplevel_binding`
62
+ # @param [String] file_name The unexpanded file path.
63
+ def self.load_file_at_toplevel(file_name)
64
+ full_name = File.expand_path(file_name)
65
+ begin
66
+ toplevel_binding.eval(File.read(full_name)) if File.exists?(full_name)
67
+ rescue RescuableException => e
68
+ puts "Error loading #{file_name}: #{e}"
69
+ end
70
+ end
71
+
59
72
  # Load the rc files given in the `Pry::RC_FILES` array.
60
73
  # This method can also be used to reload the files if they have changed.
61
74
  def self.load_rc
62
- files = RC_FILES.collect { |file_name| File.expand_path(file_name) }.uniq
63
- files.each do |file_name|
64
- begin
65
- load(file_name) if File.exists?(file_name)
66
- rescue RescuableException => e
67
- puts "Error loading #{file_name}: #{e}"
68
- end
75
+ RC_FILES.uniq.each do |file_name|
76
+ load_file_at_toplevel(file_name)
69
77
  end
70
78
  end
71
79
 
80
+ # Load the local RC file (./.pryrc)
81
+ def self.load_local_rc
82
+ load_file_at_toplevel(LOCAL_RC_FILE)
83
+ end
84
+
72
85
  # Load any Ruby files specified with the -r flag on the command line.
73
86
  def self.load_requires
74
87
  Pry.config.requires.each do |file|
@@ -92,6 +105,7 @@ class Pry
92
105
  # note these have to be loaded here rather than in pry_instance as
93
106
  # we only want them loaded once per entire Pry lifetime.
94
107
  load_rc if Pry.config.should_load_rc
108
+ load_local_rc if Pry.config.should_load_local_rc
95
109
  load_plugins if Pry.config.should_load_plugins
96
110
  load_requires if Pry.config.should_load_requires
97
111
  load_history if Pry.config.history.should_load
@@ -108,7 +122,7 @@ class Pry
108
122
  # @option options (see Pry#initialize)
109
123
  # @example
110
124
  # Pry.start(Object.new, :input => MyInput.new)
111
- def self.start(target=TOPLEVEL_BINDING, options={})
125
+ def self.start(target=toplevel_binding, options={})
112
126
  target = Pry.binding_for(target)
113
127
  initial_session_setup
114
128
 
@@ -122,12 +136,7 @@ class Pry
122
136
  pry_instance.backtrace.shift if pry_instance.backtrace.first =~ /pry.*core_extensions.*pry/
123
137
 
124
138
  # yield the binding_stack to the hook for modification
125
- pry_instance.exec_hook(
126
- :when_started,
127
- target,
128
- options,
129
- pry_instance
130
- )
139
+ pry_instance.exec_hook(:when_started, target, options, pry_instance)
131
140
 
132
141
  if !pry_instance.binding_stack.empty?
133
142
  head = pry_instance.binding_stack.pop
@@ -135,10 +144,23 @@ class Pry
135
144
  head = target
136
145
  end
137
146
 
147
+ # Clear the line before starting Pry. This fixes the issue discussed here:
148
+ # https://github.com/pry/pry/issues/566
149
+ if Pry.config.auto_indent
150
+ Kernel.print Pry::Helpers::BaseHelpers.windows_ansi? ? "\e[0F" : "\e[0G"
151
+ end
152
+
138
153
  # Enter the matrix
139
154
  pry_instance.repl(head)
140
155
  end
141
156
 
157
+ # Execute the file through the REPL loop, non-interactively.
158
+ # @param [String] file_name File name to load through the REPL.
159
+ def self.load_file_through_repl(file_name)
160
+ require "pry/repl_file_loader"
161
+ REPLFileLoader.new(file_name).load
162
+ end
163
+
142
164
  # An inspector that clips the output to `max_length` chars.
143
165
  # In case of > `max_length` chars the `#<Object...> notation is used.
144
166
  # @param obj The object to view.
@@ -178,7 +200,7 @@ class Pry
178
200
 
179
201
  # Run a Pry command from outside a session. The commands available are
180
202
  # those referenced by `Pry.commands` (the default command set).
181
- # @param [String] arg_string The Pry command (including arguments,
203
+ # @param [String] command_string The Pry command (including arguments,
182
204
  # if any).
183
205
  # @param [Hash] options Optional named parameters.
184
206
  # @return [Object] The return value of the Pry command.
@@ -234,10 +256,11 @@ class Pry
234
256
  config.system = DEFAULT_SYSTEM
235
257
  config.editor = default_editor_for_platform
236
258
  config.should_load_rc = true
259
+ config.should_load_local_rc = true
237
260
  config.should_trap_interrupts = Helpers::BaseHelpers.jruby?
238
261
  config.disable_auto_reload = false
239
262
  config.command_prefix = ""
240
- config.auto_indent = true
263
+ config.auto_indent = Helpers::BaseHelpers.use_ansi_codes?
241
264
  config.correct_indent = true
242
265
  config.collision_warning = false
243
266
 
@@ -312,7 +335,6 @@ class Pry
312
335
  self.current_line = 1
313
336
  self.line_buffer = [""]
314
337
  self.eval_path = "(pry)"
315
- self.active_sessions = 0
316
338
 
317
339
  fix_coderay_colors
318
340
  end
@@ -328,7 +350,7 @@ class Pry
328
350
  begin
329
351
  require 'coderay/encoders/term'
330
352
  CodeRay::Encoders::Term::TOKEN_COLORS
331
- rescue => e
353
+ rescue
332
354
  end
333
355
  end
334
356
 
@@ -363,4 +385,14 @@ class Pry
363
385
  end
364
386
  end
365
387
 
388
+ # Grab a copy of the TOPLEVEL_BINDING without any local variables.
389
+ # This binding has a default definee of Object, and new methods are
390
+ # private (just as in TOPLEVEL_BINDING).
391
+ def self.__pry__
392
+ binding
393
+ end
394
+ Pry.toplevel_binding = __pry__
395
+ Pry.toplevel_binding.eval("private")
396
+ class << self; undef __pry__; end
397
+
366
398
  Pry.init
@@ -1,5 +1,26 @@
1
1
  require "pry/indent"
2
2
 
3
+ ##
4
+ # Pry is a powerful alternative to the standard IRB shell for Ruby. It
5
+ # features syntax highlighting, a flexible plugin architecture, runtime
6
+ # invocation and source and documentation browsing.
7
+ #
8
+ # Pry can be started similar to other command line utilities by simply running
9
+ # the following command:
10
+ #
11
+ # pry
12
+ #
13
+ # Once inside Pry you can invoke the help message:
14
+ #
15
+ # help
16
+ #
17
+ # This will show a list of available commands and their usage. For more
18
+ # information about Pry you can refer to the following resources:
19
+ #
20
+ # * http://pry.github.com/
21
+ # * https://github.com/pry/pry
22
+ # * the IRC channel, which is #pry on the Freenode network
23
+ #
3
24
  class Pry
4
25
 
5
26
  attr_accessor :input
@@ -28,6 +49,11 @@ class Pry
28
49
 
29
50
  attr_accessor :extra_sticky_locals
30
51
 
52
+ attr_accessor :suppress_output
53
+
54
+ # This is exposed via Pry::Command#state.
55
+ attr_reader :command_state
56
+
31
57
  # Special treatment for hooks as we want to alert people of the
32
58
  # changed API
33
59
  attr_reader :hooks
@@ -57,8 +83,9 @@ class Pry
57
83
  def initialize(options={})
58
84
  refresh(options)
59
85
 
60
- @binding_stack = []
61
- @indent = Pry::Indent.new
86
+ @binding_stack = []
87
+ @indent = Pry::Indent.new
88
+ @command_state = {}
62
89
  end
63
90
 
64
91
  # Refresh the Pry instance settings from the Pry class.
@@ -117,7 +144,7 @@ class Pry
117
144
  # @return [Object] The value the local was set to.
118
145
  def inject_local(name, value, b)
119
146
  Thread.current[:__pry_local__] = value.is_a?(Proc) ? value.call : value
120
- b.eval("#{name} = Thread.current[:__pry_local__]")
147
+ b.eval("#{name} = ::Thread.current[:__pry_local__]")
121
148
  ensure
122
149
  Thread.current[:__pry_local__] = nil
123
150
  end
@@ -172,7 +199,6 @@ class Pry
172
199
 
173
200
  @input_array << nil # add empty input so _in_ and _out_ match
174
201
 
175
- Pry.active_sessions += 1
176
202
  binding_stack.push target
177
203
  end
178
204
 
@@ -181,9 +207,8 @@ class Pry
181
207
  def repl_epilogue(target)
182
208
  exec_hook :after_session, output, target, self
183
209
 
184
- Pry.active_sessions -= 1
185
210
  binding_stack.pop
186
- Pry.save_history if Pry.config.history.should_save && Pry.active_sessions == 0
211
+ Pry.save_history if Pry.config.history.should_save
187
212
  end
188
213
 
189
214
  # Start a read-eval-print-loop.
@@ -196,7 +221,6 @@ class Pry
196
221
  # Pry.new.repl(Object.new)
197
222
  def repl(target=TOPLEVEL_BINDING)
198
223
  target = Pry.binding_for(target)
199
- target_self = target.eval('self')
200
224
 
201
225
  repl_prologue(target)
202
226
 
@@ -246,6 +270,8 @@ class Pry
246
270
 
247
271
  code = r(target)
248
272
 
273
+ exec_hook :before_eval, code, self
274
+
249
275
  result = target.eval(code, Pry.eval_path, Pry.current_line)
250
276
  set_last_result(result, target, code)
251
277
 
@@ -272,12 +298,11 @@ class Pry
272
298
  target = Pry.binding_for(target)
273
299
  @suppress_output = false
274
300
 
275
- val = ""
276
301
  loop do
277
302
  begin
278
303
  # eval_string will probably be mutated by this method
279
304
  retrieve_line(eval_string, target)
280
- rescue CommandError, Slop::InvalidOptionError => e
305
+ rescue CommandError, Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e
281
306
  output.puts "Error: #{e.message}"
282
307
  end
283
308
 
@@ -298,9 +323,9 @@ class Pry
298
323
  # Output the result or pass to an exception handler (if result is an exception).
299
324
  def show_result(result)
300
325
  if last_result_is_exception?
301
- exception_handler.call output, result, self
326
+ exception_handler.call(output, result, self)
302
327
  else
303
- print.call output, result
328
+ print.call(output, result)
304
329
  end
305
330
  rescue RescuableException => e
306
331
  # Being uber-paranoid here, given that this exception arose because we couldn't
@@ -346,7 +371,7 @@ class Pry
346
371
  # Handle <Ctrl+C> like Bash, empty the current input buffer but do not quit.
347
372
  # This is only for ruby-1.9; other versions of ruby do not let you send Interrupt
348
373
  # from within Readline.
349
- rescue Interrupt => e
374
+ rescue Interrupt
350
375
  output.puts ""
351
376
  eval_string.replace("")
352
377
  return
@@ -514,6 +539,7 @@ class Pry
514
539
  # Manage switching of input objects on encountering EOFErrors
515
540
  def handle_read_errors
516
541
  should_retry = true
542
+ exception_count = 0
517
543
  begin
518
544
  yield
519
545
  rescue EOFError
@@ -527,6 +553,7 @@ class Pry
527
553
  else
528
554
  self.input = input_stack.pop
529
555
  end
556
+
530
557
  retry
531
558
 
532
559
  # Interrupts are handled in r() because they need to tweak eval_string
@@ -539,6 +566,11 @@ class Pry
539
566
  # anything about it.
540
567
  rescue RescuableException => e
541
568
  puts "Error: #{e.message}"
569
+ output.puts e.backtrace
570
+ exception_count += 1
571
+ if exception_count < 5
572
+ retry
573
+ end
542
574
  puts "FATAL: Pry failed to get user input using `#{input}`."
543
575
  puts "To fix this you may be able to pass input and output file descriptors to pry directly. e.g."
544
576
  puts " Pry.config.input = STDIN"
@@ -594,15 +626,40 @@ class Pry
594
626
  def select_prompt(eval_string, target)
595
627
  target_self = target.eval('self')
596
628
 
629
+ open_token = @indent.open_delimiters.any? ? @indent.open_delimiters.last :
630
+ @indent.stack.last
631
+
632
+ c = OpenStruct.new(
633
+ :object => target_self,
634
+ :nesting_level => binding_stack.size - 1,
635
+ :open_token => open_token,
636
+ :session_line => Pry.history.session_line_count + 1,
637
+ :history_line => Pry.history.history_line_count + 1,
638
+ :expr_number => input_array.count,
639
+ :_pry_ => self,
640
+ :binding_stack => binding_stack,
641
+ :input_array => input_array,
642
+ :eval_string => eval_string,
643
+ :cont => !eval_string.empty?)
644
+
597
645
  # If input buffer is empty then use normal prompt
598
646
  if eval_string.empty?
599
- Array(prompt).first.call(target_self, binding_stack.size - 1, self)
647
+ generate_prompt(Array(prompt).first, c)
600
648
 
601
649
  # Otherwise use the wait prompt (indicating multi-line expression)
602
650
  else
603
- Array(prompt).last.call(target_self, binding_stack.size - 1, self)
651
+ generate_prompt(Array(prompt).last, c)
652
+ end
653
+ end
654
+
655
+ def generate_prompt(prompt_proc, conf)
656
+ if prompt_proc.arity == 1
657
+ prompt_proc.call(conf)
658
+ else
659
+ prompt_proc.call(conf.object, conf.nesting_level, conf._pry_)
604
660
  end
605
661
  end
662
+ private :generate_prompt
606
663
 
607
664
  # the array that the prompt stack is stored in
608
665
  def prompt_stack
@@ -0,0 +1,80 @@
1
+ class Pry
2
+
3
+ # A class to manage the loading of files through the REPL loop.
4
+ # This is an interesting trick as it processes your file as if it
5
+ # was user input in an interactive session. As a result, all Pry
6
+ # commands are available, and they are executed non-interactively. Furthermore
7
+ # the session becomes interactive when the repl loop processes a
8
+ # 'make-interactive' command in the file. The session also becomes
9
+ # interactive when an exception is encountered, enabling you to fix
10
+ # the error before returning to non-interactive processing with the
11
+ # 'make-non-interactive' command.
12
+
13
+ class REPLFileLoader
14
+ def initialize(file_name)
15
+ full_name = File.expand_path(file_name)
16
+ raise RuntimeError, "No such file: #{full_name}" if !File.exists?(full_name)
17
+
18
+ @content = StringIO.new(File.read(full_name))
19
+ end
20
+
21
+ # Switch to interactive mode, i.e take input from the user
22
+ # and use the regular print and exception handlers.
23
+ # @param [Pry] _pry_ the Pry instance to make interactive.
24
+ def interactive_mode(_pry_)
25
+ _pry_.input = Pry.config.input
26
+ _pry_.print = Pry.config.print
27
+ _pry_.exception_handler = Pry.config.exception_handler
28
+ end
29
+
30
+ # Switch to non-interactive mode. Essentially
31
+ # this means there is no result output
32
+ # and that the session becomes interactive when an exception is encountered.
33
+ # @param [Pry] _pry_ the Pry instance to make non-interactive.
34
+ def non_interactive_mode(_pry_)
35
+ _pry_.print = proc {}
36
+ _pry_.exception_handler = proc do |o, e, _pry_|
37
+ _pry_.run_command "cat --ex"
38
+ o.puts "...exception encountered, going interactive!"
39
+ interactive_mode(_pry_)
40
+ end
41
+ end
42
+
43
+ # Define a few extra commands useful for flipping back & forth
44
+ # between interactive/non-interactive modes
45
+ def define_additional_commands
46
+ s = self
47
+
48
+ Pry::Commands.command "make-interactive", "Make the session interactive" do
49
+ _pry_.input_stack.push _pry_.input
50
+ s.interactive_mode(_pry_)
51
+ end
52
+
53
+ Pry::Commands.command "make-non-interactive", "Make the session non-interactive" do
54
+ _pry_.input = _pry_.input_stack.pop
55
+ s.non_interactive_mode(_pry_)
56
+ end
57
+
58
+ Pry::Commands.command "load-file", "Load another file through the repl" do |file_name|
59
+ content = StringIO.new(File.read(File.expand_path(file_name)))
60
+ _pry_.input_stack.push(_pry_.input)
61
+ _pry_.input = content
62
+ end
63
+ end
64
+
65
+ # Actually load the file through the REPL by setting file content
66
+ # as the REPL input stream.
67
+ def load
68
+ Pry.initial_session_setup
69
+ define_additional_commands
70
+
71
+ Pry.config.hooks.add_hook(:when_started, :start_non_interactively) do |o, t, _pry_|
72
+ non_interactive_mode(_pry_)
73
+ end
74
+
75
+ Pry.start(Pry.toplevel_binding,
76
+ :input => @content,
77
+ :input_stack => [StringIO.new("exit-all\n")])
78
+ end
79
+ end
80
+ end
data/lib/pry/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Pry
2
- VERSION = "0.9.9.6pre2"
2
+ VERSION = "0.9.10"
3
3
  end