pry 0.10.3 → 0.12.2

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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +251 -16
  3. data/LICENSE +1 -1
  4. data/README.md +35 -51
  5. data/bin/pry +3 -11
  6. data/lib/pry/basic_object.rb +6 -0
  7. data/lib/pry/cli.rb +50 -52
  8. data/lib/pry/code/code_file.rb +13 -6
  9. data/lib/pry/code/code_range.rb +3 -3
  10. data/lib/pry/code/loc.rb +14 -8
  11. data/lib/pry/code.rb +12 -5
  12. data/lib/pry/code_object.rb +27 -4
  13. data/lib/pry/color_printer.rb +20 -10
  14. data/lib/pry/command.rb +76 -45
  15. data/lib/pry/command_set.rb +17 -45
  16. data/lib/pry/commands/amend_line.rb +3 -4
  17. data/lib/pry/commands/bang.rb +1 -1
  18. data/lib/pry/commands/cat/exception_formatter.rb +10 -8
  19. data/lib/pry/commands/cat/file_formatter.rb +7 -3
  20. data/lib/pry/commands/cat/input_expression_formatter.rb +1 -1
  21. data/lib/pry/commands/cat.rb +7 -6
  22. data/lib/pry/commands/change_prompt.rb +29 -9
  23. data/lib/pry/commands/clear_screen.rb +14 -0
  24. data/lib/pry/commands/code_collector.rb +25 -23
  25. data/lib/pry/commands/easter_eggs.rb +12 -12
  26. data/lib/pry/commands/edit/file_and_line_locator.rb +1 -1
  27. data/lib/pry/commands/edit.rb +15 -10
  28. data/lib/pry/commands/exit.rb +2 -1
  29. data/lib/pry/commands/find_method.rb +12 -14
  30. data/lib/pry/commands/gem_cd.rb +1 -1
  31. data/lib/pry/commands/gem_install.rb +2 -2
  32. data/lib/pry/commands/gem_list.rb +2 -2
  33. data/lib/pry/commands/gem_open.rb +2 -2
  34. data/lib/pry/commands/gem_readme.rb +25 -0
  35. data/lib/pry/commands/gem_search.rb +40 -0
  36. data/lib/pry/commands/gem_stats.rb +83 -0
  37. data/lib/pry/commands/gist.rb +7 -6
  38. data/lib/pry/commands/help.rb +3 -3
  39. data/lib/pry/commands/hist.rb +11 -10
  40. data/lib/pry/commands/import_set.rb +2 -1
  41. data/lib/pry/commands/install_command.rb +7 -6
  42. data/lib/pry/commands/jump_to.rb +7 -7
  43. data/lib/pry/commands/list_inspectors.rb +2 -2
  44. data/lib/pry/commands/ls/constants.rb +14 -3
  45. data/lib/pry/commands/ls/formatter.rb +4 -2
  46. data/lib/pry/commands/ls/globals.rb +0 -2
  47. data/lib/pry/commands/ls/grep.rb +0 -2
  48. data/lib/pry/commands/ls/instance_vars.rb +0 -1
  49. data/lib/pry/commands/ls/jruby_hacks.rb +2 -2
  50. data/lib/pry/commands/ls/local_names.rb +0 -2
  51. data/lib/pry/commands/ls/local_vars.rb +0 -2
  52. data/lib/pry/commands/ls/ls_entity.rb +0 -1
  53. data/lib/pry/commands/ls/methods.rb +0 -3
  54. data/lib/pry/commands/ls/methods_helper.rb +1 -1
  55. data/lib/pry/commands/ls/self_methods.rb +2 -1
  56. data/lib/pry/commands/ls.rb +30 -31
  57. data/lib/pry/commands/play.rb +3 -4
  58. data/lib/pry/commands/pry_backtrace.rb +1 -1
  59. data/lib/pry/commands/raise_up.rb +2 -1
  60. data/lib/pry/commands/reload_code.rb +2 -2
  61. data/lib/pry/commands/ri.rb +9 -4
  62. data/lib/pry/commands/shell_command.rb +36 -9
  63. data/lib/pry/commands/shell_mode.rb +6 -6
  64. data/lib/pry/commands/show_doc.rb +5 -7
  65. data/lib/pry/commands/show_info.rb +41 -20
  66. data/lib/pry/commands/show_source.rb +5 -2
  67. data/lib/pry/commands/stat.rb +1 -1
  68. data/lib/pry/commands/watch_expression/expression.rb +1 -1
  69. data/lib/pry/commands/watch_expression.rb +9 -7
  70. data/lib/pry/commands/whereami.rb +16 -9
  71. data/lib/pry/commands/wtf.rb +15 -2
  72. data/lib/pry/config/behavior.rb +230 -114
  73. data/lib/pry/config/convenience.rb +24 -21
  74. data/lib/pry/config/default.rb +151 -153
  75. data/lib/pry/config/memoization.rb +48 -0
  76. data/lib/pry/config.rb +30 -19
  77. data/lib/pry/core_extensions.rb +15 -4
  78. data/lib/pry/editor.rb +5 -12
  79. data/lib/pry/exceptions.rb +1 -3
  80. data/lib/pry/forwardable.rb +23 -0
  81. data/lib/pry/helpers/base_helpers.rb +197 -110
  82. data/lib/pry/helpers/command_helpers.rb +5 -4
  83. data/lib/pry/helpers/documentation_helpers.rb +3 -2
  84. data/lib/pry/helpers/options_helpers.rb +6 -6
  85. data/lib/pry/helpers/platform.rb +58 -0
  86. data/lib/pry/helpers/table.rb +20 -15
  87. data/lib/pry/helpers/text.rb +82 -74
  88. data/lib/pry/helpers.rb +1 -0
  89. data/lib/pry/history.rb +44 -10
  90. data/lib/pry/hooks.rb +50 -109
  91. data/lib/pry/indent.rb +21 -19
  92. data/lib/pry/input_completer.rb +146 -123
  93. data/lib/pry/input_lock.rb +0 -2
  94. data/lib/pry/last_exception.rb +2 -2
  95. data/lib/pry/method/disowned.rb +3 -1
  96. data/lib/pry/method/patcher.rb +2 -5
  97. data/lib/pry/method/weird_method_locator.rb +21 -11
  98. data/lib/pry/method.rb +44 -38
  99. data/lib/pry/object_path.rb +5 -4
  100. data/lib/pry/output.rb +37 -37
  101. data/lib/pry/pager.rb +195 -181
  102. data/lib/pry/platform.rb +91 -0
  103. data/lib/pry/plugins.rb +27 -8
  104. data/lib/pry/prompt.rb +144 -25
  105. data/lib/pry/pry_class.rb +83 -33
  106. data/lib/pry/pry_instance.rb +94 -59
  107. data/lib/pry/repl.rb +70 -11
  108. data/lib/pry/repl_file_loader.rb +2 -3
  109. data/lib/pry/ring.rb +84 -0
  110. data/lib/pry/rubygem.rb +9 -7
  111. data/lib/pry/slop/LICENSE +20 -0
  112. data/lib/pry/slop/commands.rb +195 -0
  113. data/lib/pry/slop/option.rb +206 -0
  114. data/lib/pry/slop.rb +661 -0
  115. data/lib/pry/terminal.rb +18 -6
  116. data/lib/pry/testable/evalable.rb +15 -0
  117. data/lib/pry/testable/mockable.rb +14 -0
  118. data/lib/pry/testable/pry_tester.rb +73 -0
  119. data/lib/pry/testable/utility.rb +26 -0
  120. data/lib/pry/testable/variables.rb +46 -0
  121. data/lib/pry/testable.rb +70 -0
  122. data/lib/pry/version.rb +1 -1
  123. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +9 -14
  124. data/lib/pry/wrapped_module.rb +22 -21
  125. data/lib/pry.rb +21 -50
  126. metadata +35 -46
  127. data/lib/pry/commands/list_prompts.rb +0 -35
  128. data/lib/pry/commands/simple_prompt.rb +0 -22
  129. data/lib/pry/history_array.rb +0 -121
  130. data/lib/pry/rbx_path.rb +0 -22
  131. data/lib/pry/test/helper.rb +0 -170
@@ -16,11 +16,12 @@
16
16
  # This will show a list of available commands and their usage. For more
17
17
  # information about Pry you can refer to the following resources:
18
18
  #
19
- # * http://pry.github.com/
19
+ # * http://pryrepl.org/
20
20
  # * https://github.com/pry/pry
21
21
  # * the IRC channel, which is #pry on the Freenode network
22
22
  #
23
23
 
24
+ # rubocop:disable Metrics/ClassLength
24
25
  class Pry
25
26
  attr_accessor :binding_stack
26
27
  attr_accessor :custom_completions
@@ -34,8 +35,13 @@ class Pry
34
35
  attr_reader :last_exception
35
36
  attr_reader :command_state
36
37
  attr_reader :exit_value
37
- attr_reader :input_array
38
- attr_reader :output_array
38
+
39
+ # @since v0.12.0
40
+ attr_reader :input_ring
41
+
42
+ # @since v0.12.0
43
+ attr_reader :output_ring
44
+
39
45
  attr_reader :config
40
46
 
41
47
  extend Pry::Config::Convenience
@@ -62,7 +68,7 @@ class Pry
62
68
  # The backtrace of the session's `binding.pry` line, if applicable.
63
69
  # @option options [Object] :target
64
70
  # The initial context for this session.
65
- def initialize(options={})
71
+ def initialize(options = {})
66
72
  @binding_stack = []
67
73
  @indent = Pry::Indent.new
68
74
  @command_state = {}
@@ -72,23 +78,47 @@ class Pry
72
78
  @config = Pry::Config.new
73
79
  config.merge!(options)
74
80
  push_prompt(config.prompt)
75
- @input_array = Pry::HistoryArray.new config.memory_size
76
- @output_array = Pry::HistoryArray.new config.memory_size
81
+ @input_ring = Pry::Ring.new(config.memory_size)
82
+ @output_ring = Pry::Ring.new(config.memory_size)
77
83
  @custom_completions = config.command_completions
78
84
  set_last_result nil
79
- @input_array << nil
85
+ @input_ring << nil
80
86
  push_initial_binding(target)
81
87
  exec_hook(:when_started, target, options, self)
82
88
  end
83
89
 
84
- # The current prompt.
90
+ @input_array_warn = false
91
+ # @deprecated Use {#input_ring} instead.
92
+ def input_array
93
+ unless @input_array_warn
94
+ loc = caller_locations(1..1).first
95
+ warn(
96
+ "#{loc.path}:#{loc.lineno}: warning: method #{self.class}##{__method__} " \
97
+ "is deprecated. Use #{self.class}#input_ring instead"
98
+ )
99
+ @input_array_warn = true
100
+ end
101
+
102
+ @input_ring
103
+ end
104
+
105
+ @output_array_warn = false
106
+ # @deprecated Use {#output_ring} instead.
107
+ def output_array
108
+ unless @output_array_warn
109
+ loc = caller_locations(1..1).first
110
+ warn(
111
+ "#{loc.path}:#{loc.lineno}: warning: method #{self.class}##{__method__} " \
112
+ "is deprecated. Use #{self.class}#output_ring instead"
113
+ )
114
+ @output_array_warn = true
115
+ end
116
+
117
+ @output_ring
118
+ end
119
+
85
120
  # This is the prompt at the top of the prompt stack.
86
- #
87
- # @example
88
- # self.prompt = Pry::SIMPLE_PROMPT
89
- # self.prompt # => Pry::SIMPLE_PROMPT
90
- #
91
- # @return [Array<Proc>] Current prompt.
121
+ # @return [Array<Proc>] the current prompt
92
122
  def prompt
93
123
  prompt_stack.last
94
124
  end
@@ -103,7 +133,7 @@ class Pry
103
133
 
104
134
  # Initialize this instance by pushing its initial context into the binding
105
135
  # stack. If no target is given, start at the top level.
106
- def push_initial_binding(target=nil)
136
+ def push_initial_binding(target = nil)
107
137
  push_binding(target || Pry.toplevel_binding)
108
138
  end
109
139
 
@@ -124,7 +154,7 @@ class Pry
124
154
  #
125
155
  # Generate completions.
126
156
  #
127
- # @param [String] input
157
+ # @param [String] str
128
158
  # What the user has typed so far
129
159
  #
130
160
  # @return [Array<String>]
@@ -132,6 +162,7 @@ class Pry
132
162
  #
133
163
  def complete(str)
134
164
  return EMPTY_COMPLETIONS unless config.completer
165
+
135
166
  Pry.critical_section do
136
167
  completer = config.completer.new(config.input, self)
137
168
  completer.call str, target: current_binding, custom_completions: custom_completions.call.push(*sticky_locals.keys)
@@ -171,13 +202,13 @@ class Pry
171
202
  # @return [Integer] The maximum amount of objects remembered by the inp and
172
203
  # out arrays. Defaults to 100.
173
204
  def memory_size
174
- @output_array.max_size
205
+ @output_ring.max_size
175
206
  end
176
207
 
177
208
  undef :memory_size= if method_defined? :memory_size=
178
209
  def memory_size=(size)
179
- @input_array = Pry::HistoryArray.new(size)
180
- @output_array = Pry::HistoryArray.new(size)
210
+ @input_ring = Pry::Ring.new(size)
211
+ @output_ring = Pry::Ring.new(size)
181
212
  end
182
213
 
183
214
  # Inject all the sticky locals into the current binding.
@@ -197,14 +228,14 @@ class Pry
197
228
  end
198
229
 
199
230
  def sticky_locals
200
- { _in_: input_array,
201
- _out_: output_array,
231
+ { _in_: input_ring,
232
+ _out_: output_ring,
202
233
  _pry_: self,
203
234
  _ex_: last_exception && last_exception.wrapped_exception,
204
235
  _file_: last_file,
205
236
  _dir_: last_dir,
206
237
  _: proc { last_result },
207
- __: proc { output_array[-2] }
238
+ __: proc { output_ring[-2] }
208
239
  }.merge(config.extra_sticky_locals)
209
240
  end
210
241
 
@@ -234,7 +265,7 @@ class Pry
234
265
  # @return [Boolean] Is Pry ready to accept more input?
235
266
  # @raise [Exception] If the user uses the `raise-up` command, this method
236
267
  # will raise that exception.
237
- def eval(line, options={})
268
+ def eval(line, options = {})
238
269
  return false if @stopped
239
270
 
240
271
  exit_value = nil
@@ -254,6 +285,7 @@ class Pry
254
285
 
255
286
  # TODO: make this configurable?
256
287
  raise exception if exception
288
+
257
289
  return false
258
290
  end
259
291
 
@@ -269,7 +301,7 @@ class Pry
269
301
  @suppress_output = false
270
302
  inject_sticky_locals!
271
303
  begin
272
- if !process_command_safely(line.lstrip)
304
+ if !process_command_safely(line)
273
305
  @eval_string << "#{line.chomp}\n" if !line.empty? || !@eval_string.empty?
274
306
  end
275
307
  rescue RescuableException => e
@@ -310,7 +342,7 @@ class Pry
310
342
  # This workaround has a side effect: java exceptions specified
311
343
  # in `Pry.config.exception_whitelist` are ignored.
312
344
  jruby_exceptions = []
313
- if Pry::Helpers::BaseHelpers.jruby?
345
+ if Helpers::Platform.jruby?
314
346
  jruby_exceptions << Java::JavaLang::Exception
315
347
  end
316
348
 
@@ -325,7 +357,7 @@ class Pry
325
357
  # Eliminate following warning:
326
358
  # warning: singleton on non-persistent Java type X
327
359
  # (http://wiki.jruby.org/Persistence)
328
- if Pry::Helpers::BaseHelpers.jruby? && e.class.respond_to?('__persistent__')
360
+ if Helpers::Platform.jruby? && e.class.respond_to?('__persistent__')
329
361
  e.class.__persistent__ = true
330
362
  end
331
363
  self.last_exception = e
@@ -345,7 +377,7 @@ class Pry
345
377
  # (If nested sessions are going to exist, this method is fine, but a goal is
346
378
  # to come up with an alternative to nested sessions altogether.)
347
379
  def repl(target = nil)
348
- Pry::REPL.new(self, :target => target).start
380
+ Pry::REPL.new(self, target: target).start
349
381
  end
350
382
 
351
383
  def evaluate_ruby(code)
@@ -373,7 +405,7 @@ class Pry
373
405
  # serialize something in the user's program, let's not assume we can serialize
374
406
  # the exception either.
375
407
  begin
376
- output.puts "(pry) output error: #{e.inspect}"
408
+ output.puts "(pry) output error: #{e.inspect}\n#{e.backtrace.join("\n")}"
377
409
  rescue RescuableException => e
378
410
  if last_result_is_exception?
379
411
  output.puts "(pry) output error: failed to show exception"
@@ -400,12 +432,14 @@ class Pry
400
432
  # @param [String] val The line to process.
401
433
  # @return [Boolean] `true` if `val` is a command, `false` otherwise
402
434
  def process_command(val)
435
+ val = val.lstrip if /^\s\S/ !~ val
403
436
  val = val.chomp
404
437
  result = commands.process_line(val,
405
- :target => current_binding,
406
- :output => output,
407
- :eval_string => @eval_string,
408
- :pry_instance => self
438
+ target: current_binding,
439
+ output: output,
440
+ eval_string: @eval_string,
441
+ pry_instance: self,
442
+ hooks: hooks
409
443
  )
410
444
 
411
445
  # set a temporary (just so we can inject the value we want into eval_string)
@@ -433,7 +467,7 @@ class Pry
433
467
  # @return [Boolean] `true` if `val` is a command, `false` otherwise
434
468
  def process_command_safely(val)
435
469
  process_command(val)
436
- rescue CommandError, Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e
470
+ rescue CommandError, Pry::Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e
437
471
  Pry.last_internal_error = e
438
472
  output.puts "Error: #{e.message}"
439
473
  true
@@ -446,10 +480,10 @@ class Pry
446
480
  # pry_instance.run_command("ls -m")
447
481
  def run_command(val)
448
482
  commands.process_line(val,
449
- :eval_string => @eval_string,
450
- :target => current_binding,
451
- :pry_instance => self,
452
- :output => output
483
+ eval_string: @eval_string,
484
+ target: current_binding,
485
+ pry_instance: self,
486
+ output: output
453
487
  )
454
488
  Pry::Command::VOID_VALUE
455
489
  end
@@ -477,9 +511,9 @@ class Pry
477
511
  # This method should not need to be invoked directly.
478
512
  # @param [Object] result The result.
479
513
  # @param [String] code The code that was run.
480
- def set_last_result(result, code="")
514
+ def set_last_result(result, code = "")
481
515
  @last_result_is_exception = false
482
- @output_array << result
516
+ @output_ring << result
483
517
 
484
518
  self.last_result = result unless code =~ /\A\s*\z/
485
519
  end
@@ -493,7 +527,7 @@ class Pry
493
527
  def last_exception=(e)
494
528
  last_exception = Pry::LastException.new(e)
495
529
  @last_result_is_exception = true
496
- @output_array << last_exception
530
+ @output_ring << last_exception
497
531
  @last_exception = last_exception
498
532
  end
499
533
 
@@ -501,8 +535,8 @@ class Pry
501
535
  # This method should not need to be invoked directly.
502
536
  # @param [String] code The code we just eval'd
503
537
  def update_input_history(code)
504
- # Always push to the @input_array as the @output_array is always pushed to.
505
- @input_array << code
538
+ # Always push to the @input_ring as the @output_ring is always pushed to.
539
+ @input_ring << code
506
540
  if code
507
541
  Pry.line_buffer.push(*code.each_line)
508
542
  Pry.current_line += code.lines.count
@@ -527,28 +561,26 @@ class Pry
527
561
  # @return [String] The prompt.
528
562
  def select_prompt
529
563
  object = current_binding.eval('self')
530
-
531
- open_token = @indent.open_delimiters.any? ? @indent.open_delimiters.last :
532
- @indent.stack.last
533
-
534
- c = Pry::Config.from_hash({
535
- :object => object,
536
- :nesting_level => binding_stack.size - 1,
537
- :open_token => open_token,
538
- :session_line => Pry.history.session_line_count + 1,
539
- :history_line => Pry.history.history_line_count + 1,
540
- :expr_number => input_array.count,
541
- :_pry_ => self,
542
- :binding_stack => binding_stack,
543
- :input_array => input_array,
544
- :eval_string => @eval_string,
545
- :cont => !@eval_string.empty?})
564
+ open_token = @indent.open_delimiters.last || @indent.stack.last
565
+
566
+ c = Pry::Config.assign({
567
+ object: object,
568
+ nesting_level: binding_stack.size - 1,
569
+ open_token: open_token,
570
+ session_line: Pry.history.session_line_count + 1,
571
+ history_line: Pry.history.history_line_count + 1,
572
+ expr_number: input_ring.count,
573
+ _pry_: self,
574
+ binding_stack: binding_stack,
575
+ input_ring: input_ring,
576
+ eval_string: @eval_string,
577
+ cont: !@eval_string.empty?
578
+ })
546
579
 
547
580
  Pry.critical_section do
548
581
  # If input buffer is empty then use normal prompt
549
582
  if eval_string.empty?
550
583
  generate_prompt(Array(prompt).first, c)
551
-
552
584
  # Otherwise use the wait prompt (indicating multi-line expression)
553
585
  else
554
586
  generate_prompt(Array(prompt).last, c)
@@ -653,7 +685,9 @@ class Pry
653
685
  raise exception
654
686
  end
655
687
  end
688
+
656
689
  def raise_up(*args); raise_up_common(false, *args); end
690
+
657
691
  def raise_up!(*args); raise_up_common(true, *args); end
658
692
 
659
693
  # Convenience accessor for the `quiet` config key.
@@ -662,3 +696,4 @@ class Pry
662
696
  config.quiet
663
697
  end
664
698
  end
699
+ # rubocop:enable Metrics/ClassLength
data/lib/pry/repl.rb CHANGED
@@ -1,8 +1,6 @@
1
- require 'forwardable'
2
-
3
1
  class Pry
4
2
  class REPL
5
- extend Forwardable
3
+ extend Pry::Forwardable
6
4
  def_delegators :@pry, :input, :output
7
5
 
8
6
  # @return [Pry] The instance of {Pry} that the user is controlling.
@@ -23,6 +21,8 @@ class Pry
23
21
  @pry = pry
24
22
  @indent = Pry::Indent.new
25
23
 
24
+ @readline_output = nil
25
+
26
26
  if options[:target]
27
27
  @pry.push_binding options[:target]
28
28
  end
@@ -49,7 +49,7 @@ class Pry
49
49
 
50
50
  # Clear the line before starting Pry. This fixes issue #566.
51
51
  if pry.config.correct_indent
52
- Kernel.print Pry::Helpers::BaseHelpers.windows_ansi? ? "\e[0F" : "\e[0G"
52
+ Kernel.print(Helpers::Platform.windows_ansi? ? "\e[0F" : "\e[0G")
53
53
  end
54
54
  end
55
55
 
@@ -106,8 +106,9 @@ class Pry
106
106
 
107
107
  if output.tty? && pry.config.correct_indent && Pry::Helpers::BaseHelpers.use_ansi_codes?
108
108
  output.print @indent.correct_indentation(
109
- current_prompt, indented_val,
110
- original_val.length - indented_val.length
109
+ current_prompt,
110
+ indented_val,
111
+ calculate_overhang(current_prompt, original_val, indented_val)
111
112
  )
112
113
  output.flush
113
114
  end
@@ -168,20 +169,21 @@ class Pry
168
169
  # @return [String?] The next line of input, or `nil` on <Ctrl-D>.
169
170
  def read_line(current_prompt)
170
171
  handle_read_errors do
171
- if defined? Coolline and input.is_a? Coolline
172
+ if coolline_available?
172
173
  input.completion_proc = proc do |cool|
173
174
  completions = @pry.complete cool.completed_word
174
175
  completions.compact
175
176
  end
176
177
  elsif input.respond_to? :completion_proc=
177
- input.completion_proc = proc do |input|
178
- @pry.complete input
178
+ input.completion_proc = proc do |inp|
179
+ @pry.complete inp
179
180
  end
180
181
  end
181
182
 
182
- if defined?(Readline) and input == Readline
183
+ if readline_available?
184
+ set_readline_output
183
185
  input_readline(current_prompt, false) # false since we'll add it manually
184
- elsif defined? Coolline and input.is_a? Coolline
186
+ elsif coolline_available?
185
187
  input_readline(current_prompt)
186
188
  else
187
189
  if input.method(:readline).arity == 1
@@ -198,5 +200,62 @@ class Pry
198
200
  input.readline(*args)
199
201
  end
200
202
  end
203
+
204
+ def readline_available?
205
+ defined?(Readline) && input == Readline
206
+ end
207
+
208
+ def coolline_available?
209
+ defined?(Coolline) && input.is_a?(Coolline)
210
+ end
211
+
212
+ # If `$stdout` is not a tty, it's probably a pipe.
213
+ # @example
214
+ # # `piping?` returns `false`
215
+ # % pry
216
+ # [1] pry(main)
217
+ #
218
+ # # `piping?` returns `true`
219
+ # % pry | tee log
220
+ def piping?
221
+ return false unless $stdout.respond_to?(:tty?)
222
+
223
+ !$stdout.tty? && $stdin.tty? && !Helpers::Platform.windows?
224
+ end
225
+
226
+ # @return [void]
227
+ def set_readline_output
228
+ return if @readline_output
229
+
230
+ if piping?
231
+ @readline_output = (Readline.output = Pry.config.output)
232
+ end
233
+ end
234
+
235
+ # Calculates correct overhang for current line. Supports vi Readline
236
+ # mode and its indicators such as "(ins)" or "(cmd)".
237
+ #
238
+ # @return [Integer]
239
+ # @note This doesn't calculate overhang for Readline's emacs mode with an
240
+ # indicator because emacs is the default mode and it doesn't use
241
+ # indicators in 99% of cases.
242
+ def calculate_overhang(current_prompt, original_val, indented_val)
243
+ overhang = original_val.length - indented_val.length
244
+
245
+ if readline_available? && Readline.respond_to?(:vi_editing_mode?)
246
+ begin
247
+ # rb-readline doesn't support this method:
248
+ # https://github.com/ConnorAtherton/rb-readline/issues/152
249
+ if Readline.vi_editing_mode?
250
+ overhang += current_prompt.length - indented_val.length
251
+ end
252
+ rescue NotImplementedError
253
+ # VI editing mode is unsupported on JRuby.
254
+ # https://github.com/pry/pry/issues/1840
255
+ nil
256
+ end
257
+ end
258
+ [0, overhang].max
259
+ end
201
260
  end
202
261
  end
@@ -1,5 +1,4 @@
1
1
  class Pry
2
-
3
2
  # A class to manage the loading of files through the REPL loop.
4
3
  # This is an interesting trick as it processes your file as if it
5
4
  # was user input in an interactive session. As a result, all Pry
@@ -13,7 +12,7 @@ class Pry
13
12
  class REPLFileLoader
14
13
  def initialize(file_name)
15
14
  full_name = File.expand_path(file_name)
16
- raise RuntimeError, "No such file: #{full_name}" if !File.exists?(full_name)
15
+ raise RuntimeError, "No such file: #{full_name}" if !File.exist?(full_name)
17
16
 
18
17
  define_additional_commands
19
18
  @content = File.read(full_name)
@@ -42,7 +41,7 @@ class Pry
42
41
  end
43
42
 
44
43
  content.lines.each do |line|
45
- break unless _pry_.eval line, :generated => true
44
+ break unless _pry_.eval line, generated: true
46
45
  end
47
46
 
48
47
  unless _pry_.eval_string.empty?
data/lib/pry/ring.rb ADDED
@@ -0,0 +1,84 @@
1
+ class Pry
2
+ # A ring is a thread-safe fixed-capacity array to which you can only add
3
+ # elements. Older entries are overwritten as you add new elements, so that the
4
+ # ring can never contain more than `max_size` elemens.
5
+ #
6
+ # @example
7
+ # ring = Pry::Ring.new(3)
8
+ # ring << 1 << 2 << 3
9
+ # ring.to_a #=> [1, 2, 3]
10
+ # ring << 4
11
+ # ring.to_a #=> [2, 3, 4]
12
+ #
13
+ # ring[0] #=> 2
14
+ # ring[-1] #=> 4
15
+ # ring.clear
16
+ # ring[0] #=> nil
17
+ #
18
+ # @api public
19
+ # @since v0.12.0
20
+ class Ring
21
+ # @return [Integer] maximum buffer size
22
+ attr_reader :max_size
23
+
24
+ # @return [Integer] how many objects were added during the lifetime of the
25
+ # ring
26
+ attr_reader :count
27
+ alias size count
28
+
29
+ # @param [Integer] max_size Maximum buffer size. The buffer will start
30
+ # overwriting elements once its reaches its maximum capacity
31
+ def initialize(max_size)
32
+ @max_size = max_size
33
+ @mutex = Mutex.new
34
+ clear
35
+ end
36
+
37
+ # Push `value` to the current index.
38
+ #
39
+ # @param [Object] value
40
+ # @return [self]
41
+ def <<(value)
42
+ @mutex.synchronize do
43
+ @buffer[count % max_size] = value
44
+ @count += 1
45
+ self
46
+ end
47
+ end
48
+
49
+ # Read the value stored at `index`.
50
+ #
51
+ # @param [Integer, Range] index The element (if Integer) or elements
52
+ # (if Range) associated with `index`
53
+ # @return [Object, Array<Object>, nil] element(s) at `index`, `nil` if none
54
+ # exist
55
+ def [](index)
56
+ @mutex.synchronize do
57
+ return @buffer[(count + index) % max_size] if index.is_a?(Integer)
58
+ return @buffer[index] if count <= max_size
59
+
60
+ # Swap parts of array when the array turns page and starts overwriting
61
+ # from the beginning, then apply the range.
62
+ last_part = @buffer.slice([index.end, max_size - 1].min, count % max_size)
63
+ (last_part + (@buffer - last_part))[index]
64
+ end
65
+ end
66
+
67
+ # @return [Array<Object>] the buffer as unwinded array
68
+ def to_a
69
+ return @buffer.dup if count <= max_size
70
+
71
+ last_part = @buffer.slice(count % max_size, @buffer.size)
72
+ last_part + (@buffer - last_part)
73
+ end
74
+
75
+ # Clear the buffer and reset count.
76
+ # @return [void]
77
+ def clear
78
+ @mutex.synchronize do
79
+ @buffer = []
80
+ @count = 0
81
+ end
82
+ end
83
+ end
84
+ end
data/lib/pry/rubygem.rb CHANGED
@@ -23,7 +23,7 @@ class Pry
23
23
  Gem.source_index.find_name(name)
24
24
  end
25
25
 
26
- first_spec = specs.sort_by{ |spec| Gem::Version.new(spec.version) }.last
26
+ first_spec = specs.sort_by { |spec| Gem::Version.new(spec.version) }.last
27
27
 
28
28
  first_spec or raise CommandError, "Gem `#{name}` not found"
29
29
  end
@@ -34,9 +34,9 @@ class Pry
34
34
  # @return [Array<Gem::Specification>]
35
35
  def list(pattern = /.*/)
36
36
  if Gem::Specification.respond_to?(:each)
37
- Gem::Specification.select{|spec| spec.name =~ pattern }
37
+ Gem::Specification.select { |spec| spec.name =~ pattern }
38
38
  else
39
- Gem.source_index.gems.values.select{|spec| spec.name =~ pattern }
39
+ Gem.source_index.gems.values.select { |spec| spec.name =~ pattern }
40
40
  end
41
41
  end
42
42
 
@@ -57,7 +57,9 @@ class Pry
57
57
  # @param [String] name
58
58
  # @return [void]
59
59
  def install(name)
60
- gemrc_opts = Gem.configuration['gem'].split(' ')
60
+ require 'rubygems/dependency_installer'
61
+ gem_config = Gem.configuration['gem']
62
+ gemrc_opts = (gem_config.nil? ? "" : gem_config.split(' '))
61
63
  destination = if gemrc_opts.include?('--user-install')
62
64
  Gem.user_dir
63
65
  elsif File.writable?(Gem.dir)
@@ -65,14 +67,14 @@ class Pry
65
67
  else
66
68
  Gem.user_dir
67
69
  end
68
- installer = Gem::DependencyInstaller.new(:install_dir => destination)
70
+ installer = Gem::DependencyInstaller.new(install_dir: destination)
69
71
  installer.install(name)
70
72
  rescue Errno::EACCES
71
73
  raise CommandError,
72
- "Insufficient permissions to install #{ Pry::Helpers::Text.green(name) }."
74
+ "Insufficient permissions to install #{green(name)}."
73
75
  rescue Gem::GemNotFoundException
74
76
  raise CommandError,
75
- "Gem #{ Pry::Helpers::Text.green(name) } not found. Aborting installation."
77
+ "Gem #{green(name)} not found. Aborting installation."
76
78
  else
77
79
  Gem.refresh
78
80
  end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Lee Jarvis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.