pry 0.12.2-java → 0.13.0-java

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 (158) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +110 -1
  3. data/LICENSE +1 -1
  4. data/README.md +331 -269
  5. data/bin/pry +5 -0
  6. data/lib/pry.rb +133 -119
  7. data/lib/pry/basic_object.rb +8 -4
  8. data/lib/pry/block_command.rb +22 -0
  9. data/lib/pry/class_command.rb +194 -0
  10. data/lib/pry/cli.rb +40 -31
  11. data/lib/pry/code.rb +39 -27
  12. data/lib/pry/code/code_file.rb +28 -24
  13. data/lib/pry/code/code_range.rb +4 -2
  14. data/lib/pry/code/loc.rb +15 -8
  15. data/lib/pry/code_object.rb +40 -38
  16. data/lib/pry/color_printer.rb +47 -46
  17. data/lib/pry/command.rb +166 -369
  18. data/lib/pry/command_set.rb +76 -73
  19. data/lib/pry/command_state.rb +31 -0
  20. data/lib/pry/commands/amend_line.rb +86 -81
  21. data/lib/pry/commands/bang.rb +18 -14
  22. data/lib/pry/commands/bang_pry.rb +15 -11
  23. data/lib/pry/commands/cat.rb +61 -54
  24. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  25. data/lib/pry/commands/cat/exception_formatter.rb +71 -60
  26. data/lib/pry/commands/cat/file_formatter.rb +55 -49
  27. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  28. data/lib/pry/commands/cd.rb +40 -35
  29. data/lib/pry/commands/change_inspector.rb +29 -22
  30. data/lib/pry/commands/change_prompt.rb +44 -39
  31. data/lib/pry/commands/clear_screen.rb +16 -10
  32. data/lib/pry/commands/code_collector.rb +148 -133
  33. data/lib/pry/commands/disable_pry.rb +23 -19
  34. data/lib/pry/commands/easter_eggs.rb +19 -30
  35. data/lib/pry/commands/edit.rb +184 -161
  36. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  37. data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
  38. data/lib/pry/commands/exit.rb +39 -35
  39. data/lib/pry/commands/exit_all.rb +24 -20
  40. data/lib/pry/commands/exit_program.rb +20 -16
  41. data/lib/pry/commands/find_method.rb +168 -160
  42. data/lib/pry/commands/fix_indent.rb +16 -12
  43. data/lib/pry/commands/help.rb +140 -133
  44. data/lib/pry/commands/hist.rb +151 -150
  45. data/lib/pry/commands/import_set.rb +20 -16
  46. data/lib/pry/commands/jump_to.rb +25 -21
  47. data/lib/pry/commands/list_inspectors.rb +35 -28
  48. data/lib/pry/commands/ls.rb +124 -102
  49. data/lib/pry/commands/ls/constants.rb +59 -42
  50. data/lib/pry/commands/ls/formatter.rb +50 -46
  51. data/lib/pry/commands/ls/globals.rb +38 -34
  52. data/lib/pry/commands/ls/grep.rb +17 -13
  53. data/lib/pry/commands/ls/instance_vars.rb +29 -27
  54. data/lib/pry/commands/ls/interrogatable.rb +18 -12
  55. data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
  56. data/lib/pry/commands/ls/local_names.rb +26 -22
  57. data/lib/pry/commands/ls/local_vars.rb +38 -28
  58. data/lib/pry/commands/ls/ls_entity.rb +47 -51
  59. data/lib/pry/commands/ls/methods.rb +44 -43
  60. data/lib/pry/commands/ls/methods_helper.rb +46 -42
  61. data/lib/pry/commands/ls/self_methods.rb +23 -22
  62. data/lib/pry/commands/nesting.rb +21 -17
  63. data/lib/pry/commands/play.rb +93 -82
  64. data/lib/pry/commands/pry_backtrace.rb +24 -17
  65. data/lib/pry/commands/pry_version.rb +15 -11
  66. data/lib/pry/commands/raise_up.rb +27 -22
  67. data/lib/pry/commands/reload_code.rb +60 -48
  68. data/lib/pry/commands/reset.rb +16 -12
  69. data/lib/pry/commands/ri.rb +55 -45
  70. data/lib/pry/commands/save_file.rb +45 -43
  71. data/lib/pry/commands/shell_command.rb +51 -51
  72. data/lib/pry/commands/shell_mode.rb +21 -17
  73. data/lib/pry/commands/show_doc.rb +81 -68
  74. data/lib/pry/commands/show_info.rb +189 -171
  75. data/lib/pry/commands/show_input.rb +16 -11
  76. data/lib/pry/commands/show_source.rb +109 -45
  77. data/lib/pry/commands/stat.rb +35 -31
  78. data/lib/pry/commands/switch_to.rb +21 -15
  79. data/lib/pry/commands/toggle_color.rb +20 -16
  80. data/lib/pry/commands/watch_expression.rb +89 -86
  81. data/lib/pry/commands/watch_expression/expression.rb +32 -27
  82. data/lib/pry/commands/whereami.rb +156 -148
  83. data/lib/pry/commands/wtf.rb +75 -50
  84. data/lib/pry/config.rb +311 -25
  85. data/lib/pry/config/attributable.rb +22 -0
  86. data/lib/pry/config/lazy_value.rb +29 -0
  87. data/lib/pry/config/memoized_value.rb +34 -0
  88. data/lib/pry/config/value.rb +24 -0
  89. data/lib/pry/control_d_handler.rb +28 -0
  90. data/lib/pry/core_extensions.rb +9 -7
  91. data/lib/pry/editor.rb +48 -21
  92. data/lib/pry/env.rb +18 -0
  93. data/lib/pry/exception_handler.rb +43 -0
  94. data/lib/pry/exceptions.rb +13 -16
  95. data/lib/pry/forwardable.rb +5 -1
  96. data/lib/pry/helpers.rb +2 -0
  97. data/lib/pry/helpers/base_helpers.rb +68 -197
  98. data/lib/pry/helpers/command_helpers.rb +50 -61
  99. data/lib/pry/helpers/documentation_helpers.rb +20 -13
  100. data/lib/pry/helpers/options_helpers.rb +14 -7
  101. data/lib/pry/helpers/platform.rb +7 -5
  102. data/lib/pry/helpers/table.rb +33 -26
  103. data/lib/pry/helpers/text.rb +17 -14
  104. data/lib/pry/history.rb +48 -56
  105. data/lib/pry/hooks.rb +21 -12
  106. data/lib/pry/indent.rb +54 -50
  107. data/lib/pry/input_completer.rb +248 -230
  108. data/lib/pry/input_lock.rb +8 -9
  109. data/lib/pry/inspector.rb +36 -24
  110. data/lib/pry/last_exception.rb +45 -45
  111. data/lib/pry/method.rb +141 -94
  112. data/lib/pry/method/disowned.rb +16 -4
  113. data/lib/pry/method/patcher.rb +12 -3
  114. data/lib/pry/method/weird_method_locator.rb +68 -44
  115. data/lib/pry/object_path.rb +33 -25
  116. data/lib/pry/output.rb +121 -35
  117. data/lib/pry/pager.rb +41 -42
  118. data/lib/pry/plugins.rb +25 -8
  119. data/lib/pry/prompt.rb +123 -54
  120. data/lib/pry/pry_class.rb +61 -98
  121. data/lib/pry/pry_instance.rb +217 -215
  122. data/lib/pry/repl.rb +18 -22
  123. data/lib/pry/repl_file_loader.rb +27 -21
  124. data/lib/pry/ring.rb +11 -6
  125. data/lib/pry/slop.rb +574 -563
  126. data/lib/pry/slop/commands.rb +164 -169
  127. data/lib/pry/slop/option.rb +172 -168
  128. data/lib/pry/syntax_highlighter.rb +26 -0
  129. data/lib/pry/system_command_handler.rb +17 -0
  130. data/lib/pry/testable.rb +59 -61
  131. data/lib/pry/testable/evalable.rb +21 -12
  132. data/lib/pry/testable/mockable.rb +18 -10
  133. data/lib/pry/testable/pry_tester.rb +71 -56
  134. data/lib/pry/testable/utility.rb +29 -21
  135. data/lib/pry/testable/variables.rb +49 -43
  136. data/lib/pry/version.rb +3 -1
  137. data/lib/pry/warning.rb +27 -0
  138. data/lib/pry/wrapped_module.rb +51 -42
  139. data/lib/pry/wrapped_module/candidate.rb +21 -14
  140. metadata +31 -30
  141. data/lib/pry/commands.rb +0 -6
  142. data/lib/pry/commands/disabled_commands.rb +0 -2
  143. data/lib/pry/commands/gem_cd.rb +0 -26
  144. data/lib/pry/commands/gem_install.rb +0 -32
  145. data/lib/pry/commands/gem_list.rb +0 -33
  146. data/lib/pry/commands/gem_open.rb +0 -29
  147. data/lib/pry/commands/gem_readme.rb +0 -25
  148. data/lib/pry/commands/gem_search.rb +0 -40
  149. data/lib/pry/commands/gem_stats.rb +0 -83
  150. data/lib/pry/commands/gist.rb +0 -102
  151. data/lib/pry/commands/install_command.rb +0 -54
  152. data/lib/pry/config/behavior.rb +0 -255
  153. data/lib/pry/config/convenience.rb +0 -28
  154. data/lib/pry/config/default.rb +0 -159
  155. data/lib/pry/config/memoization.rb +0 -48
  156. data/lib/pry/platform.rb +0 -91
  157. data/lib/pry/rubygem.rb +0 -84
  158. data/lib/pry/terminal.rb +0 -91
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
4
  class Method
3
5
  # A Disowned Method is one that's been removed from the class on which it was defined.
@@ -21,7 +23,8 @@ class Pry
21
23
  # @param [Object] receiver
22
24
  # @param [String] method_name
23
25
  def initialize(receiver, method_name)
24
- @receiver, @name = receiver, method_name
26
+ @receiver = receiver
27
+ @name = method_name
25
28
  @method = nil
26
29
  end
27
30
 
@@ -45,10 +48,19 @@ class Pry
45
48
  end
46
49
 
47
50
  # Raise a more useful error message instead of trying to forward to nil.
48
- def method_missing(meth_name, *args, &block)
49
- raise "Cannot call '#{meth_name}' on an undef'd method." if method(:name).respond_to?(meth_name)
51
+ # rubocop:disable Style/MethodMissingSuper
52
+ def method_missing(method_name, *args, &block)
53
+ if method(:name).respond_to?(method_name)
54
+ raise "Cannot call '#{method_name}' on an undef'd method."
55
+ end
56
+
57
+ method = Object.instance_method(:method_missing).bind(self)
58
+ method.call(method_name, *args, &block)
59
+ end
60
+ # rubocop:enable Style/MethodMissingSuper
50
61
 
51
- Object.instance_method(:method_missing).bind(self).call(meth_name, *args, &block)
62
+ def respond_to_missing?(method_name, include_private = false)
63
+ !method(:name).respond_to?(method_name) || super
52
64
  end
53
65
  end
54
66
  end
@@ -1,9 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
4
  class Method
3
5
  class Patcher
4
6
  attr_accessor :method
5
7
 
8
+ # rubocop:disable Style/ClassVars
6
9
  @@source_cache = {}
10
+ # rubocop:enable Style/ClassVars
7
11
 
8
12
  def initialize(method)
9
13
  @method = method
@@ -51,9 +55,12 @@ class Pry
51
55
  alias_method method.name, method.original_name
52
56
  alias_method method.original_name, temp_name
53
57
  end
54
-
55
58
  ensure
56
- method.send(:remove_method, temp_name) rescue nil
59
+ begin
60
+ method.send(:remove_method, temp_name)
61
+ rescue StandardError
62
+ nil
63
+ end
57
64
  end
58
65
 
59
66
  # Update the definition line so that it can be eval'd directly on the Method's
@@ -72,7 +79,9 @@ class Pry
72
79
  if line =~ /\Adef (?:.*?\.)?#{Regexp.escape(method.original_name)}(?=[\(\s;]|$)/
73
80
  "def #{method.original_name}#{$'}"
74
81
  else
75
- raise CommandError, "Could not find original `def #{method.original_name}` line to patch."
82
+ raise CommandError,
83
+ "Could not find original `def #{method.original_name}` line " \
84
+ "to patch."
76
85
  end
77
86
  end
78
87
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
4
  class Method
3
5
  # This class is responsible for locating the *real* `Pry::Method`
@@ -6,10 +8,11 @@ class Pry
6
8
  # Given a `Binding` from inside a method and a 'seed' Pry::Method object,
7
9
  # there are primarily two situations where the seed method doesn't match
8
10
  # the Binding:
9
- # 1. The Pry::Method is from a subclass 2. The Pry::Method represents a method of the same name
10
- # while the original was renamed to something else. For 1. we
11
- # search vertically up the inheritance chain,
12
- # and for 2. we search laterally along the object's method table.
11
+ # 1. The Pry::Method is from a subclass
12
+ # 2. The Pry::Method represents a method of the same name while the original
13
+ # was renamed to something else. For 1. we search vertically up the
14
+ # inheritance chain, and for 2. we search laterally along the object's
15
+ # method table.
13
16
  #
14
17
  # When we locate the method that matches the Binding we wrap it in
15
18
  # Pry::Method and return it, or return nil if we fail.
@@ -21,20 +24,25 @@ class Pry
21
24
  # must commence a search.
22
25
  #
23
26
  # @param [Pry::Method] method
24
- # @param [Binding] b
27
+ # @param [Binding] binding
25
28
  # @return [Boolean]
26
- def normal_method?(method, b)
27
- if method and method.source_file and method.source_range
28
- binding_file, binding_line = b.eval('__FILE__'), b.eval('__LINE__')
29
- File.expand_path(method.source_file) == File.expand_path(binding_file) and
30
- method.source_range.include?(binding_line)
29
+ def normal_method?(method, binding)
30
+ if method && method.source_file && method.source_range
31
+ if binding.respond_to?(:source_location)
32
+ binding_file, binding_line = binding.source_location
33
+ else
34
+ binding_file = binding.eval('__FILE__')
35
+ binding_line = binding.eval('__LINE__')
36
+ end
37
+ (File.expand_path(method.source_file) == File.expand_path(binding_file)) &&
38
+ method.source_range.include?(binding_line)
31
39
  end
32
- rescue
40
+ rescue StandardError
33
41
  false
34
42
  end
35
43
 
36
- def weird_method?(method, b)
37
- not normal_method?(method, b)
44
+ def weird_method?(method, binding)
45
+ !normal_method?(method, binding)
38
46
  end
39
47
  end
40
48
 
@@ -45,12 +53,13 @@ class Pry
45
53
  # @param [Binding] target The Binding that captures the method
46
54
  # we want to locate.
47
55
  def initialize(method, target)
48
- @method, @target = method, target
56
+ @method = method
57
+ @target = target
49
58
  end
50
59
 
51
60
  # @return [Pry::Method, nil] The Pry::Method that matches the
52
61
  # given binding.
53
- def get_method
62
+ def find_method
54
63
  find_method_in_superclass || find_renamed_method
55
64
  end
56
65
 
@@ -58,7 +67,7 @@ class Pry
58
67
  # This usually happens when the method captured by the Binding
59
68
  # has been subsequently deleted.
60
69
  def lost_method?
61
- !!(get_method.nil? && renamed_method_source_location)
70
+ !!(find_method.nil? && renamed_method_source_location)
62
71
  end
63
72
 
64
73
  private
@@ -77,47 +86,59 @@ class Pry
77
86
  end
78
87
 
79
88
  def target_file
80
- pry_file? ? target.eval('__FILE__') : File.expand_path(target.eval('__FILE__'))
89
+ file =
90
+ if target.respond_to?(:source_location)
91
+ target.source_location.first
92
+ else
93
+ target.eval('__FILE__')
94
+ end
95
+ pry_file? ? file : File.expand_path(file)
81
96
  end
82
97
 
83
98
  def target_line
84
- target.eval('__LINE__')
99
+ if target.respond_to?(:source_location)
100
+ target.source_location.last
101
+ else
102
+ target.eval('__LINE__')
103
+ end
85
104
  end
86
105
 
87
106
  def pry_file?
88
- Pry.eval_path == target.eval('__FILE__')
107
+ file =
108
+ if target.respond_to?(:source_location)
109
+ target.source_location.first
110
+ else
111
+ target.eval('__FILE__')
112
+ end
113
+ Pry.eval_path == file
89
114
  end
90
115
 
91
- # it's possible in some cases that the method we find by this approach is a sub-method of
92
- # the one we're currently in, consider:
116
+ # it's possible in some cases that the method we find by this approach is
117
+ # a sub-method of the one we're currently in, consider:
93
118
  #
94
119
  # class A; def b; binding.pry; end; end
95
120
  # class B < A; def b; super; end; end
96
121
  #
97
- # Given that we can normally find the source_range of methods, and that we know which
98
- # __FILE__ and __LINE__ the binding is at, we can hope to disambiguate these cases.
122
+ # Given that we can normally find the source_range of methods, and that we
123
+ # know which __FILE__ and __LINE__ the binding is at, we can hope to
124
+ # disambiguate these cases.
99
125
  #
100
- # This obviously won't work if the source is unavaiable for some reason, or if both
101
- # methods have the same __FILE__ and __LINE__.
126
+ # This obviously won't work if the source is unavaiable for some reason,
127
+ # or if both methods have the same __FILE__ and __LINE__.
102
128
  #
103
129
  # @return [Pry::Method, nil] The Pry::Method representing the
104
130
  # superclass method.
105
131
  def find_method_in_superclass
106
132
  guess = method
107
- if skip_superclass_search?
108
- return guess
109
- end
133
+ return guess if skip_superclass_search?
110
134
 
111
135
  while guess
112
136
  # needs rescue if this is a Disowned method or a C method or something...
113
137
  # TODO: Fix up the exception handling so we don't need a bare rescue
114
- if normal_method?(guess)
115
- return guess
116
- elsif guess != guess.super
117
- guess = guess.super
118
- else
119
- break
120
- end
138
+ return guess if normal_method?(guess)
139
+ break if guess == guess.super
140
+
141
+ guess = guess.super
121
142
  end
122
143
 
123
144
  # Uhoh... none of the methods in the chain had the right `__FILE__` and
@@ -133,22 +154,23 @@ class Pry
133
154
  # @return [Pry::Method, nil] The Pry::Method representing the
134
155
  # renamed method
135
156
  def find_renamed_method
136
- return if !valid_file?(target_file)
157
+ return unless valid_file?(target_file)
137
158
 
138
159
  alias_name = all_methods_for(target_self).find do |v|
139
- expanded_source_location(target_self.method(v).source_location) == renamed_method_source_location
160
+ location = target_self.method(v).source_location
161
+ expanded_source_location(location) == renamed_method_source_location
140
162
  end
141
163
 
142
164
  alias_name && Pry::Method(target_self.method(alias_name))
143
165
  end
144
166
 
145
- def expanded_source_location(sl)
146
- return if !sl
167
+ def expanded_source_location(source_location)
168
+ return unless source_location
147
169
 
148
170
  if pry_file?
149
- sl
171
+ source_location
150
172
  else
151
- [File.expand_path(sl.first), sl.last]
173
+ [File.expand_path(source_location.first), source_location.last]
152
174
  end
153
175
  end
154
176
 
@@ -160,14 +182,16 @@ class Pry
160
182
  # @return [Array<String, Fixnum>] The `source_location` of the
161
183
  # renamed method
162
184
  def renamed_method_source_location
163
- return @original_method_source_location if defined?(@original_method_source_location)
185
+ if defined?(@original_method_source_location)
186
+ return @original_method_source_location
187
+ end
164
188
 
165
189
  source_index = lines_for_file(target_file)[0..(target_line - 1)].rindex do |v|
166
190
  Pry::Method.method_definition?(method.name, v)
167
191
  end
168
192
 
169
- @original_method_source_location = source_index &&
170
- [target_file, index_to_line_number(source_index)]
193
+ @original_method_source_location =
194
+ source_index && [target_file, index_to_line_number(source_index)]
171
195
  end
172
196
 
173
197
  def index_to_line_number(index)
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'strscan'
4
+
1
5
  class Pry
2
6
  # `ObjectPath` implements the resolution of "object paths", which are strings
3
7
  # that are similar to filesystem paths but meant for traversing Ruby objects.
@@ -11,7 +15,7 @@ class Pry
11
15
  # Object paths are mostly relevant in the context of the `cd` command.
12
16
  # @see https://github.com/pry/pry/wiki/State-navigation
13
17
  class ObjectPath
14
- SPECIAL_TERMS = ["", "::", ".", ".."]
18
+ SPECIAL_TERMS = ["", "::", ".", ".."].freeze
15
19
 
16
20
  # @param [String] path_string The object path expressed as a string.
17
21
  # @param [Array<Binding>] current_stack The current state of the binding
@@ -27,36 +31,40 @@ class Pry
27
31
  scanner = StringScanner.new(@path_string.strip)
28
32
  stack = @current_stack.dup
29
33
 
30
- begin
31
- next_segment = ""
34
+ loop do
35
+ begin
36
+ next_segment = ""
32
37
 
33
- loop do
34
- # Scan for as long as we don't see a slash
35
- next_segment << scanner.scan(/[^\/]*/)
38
+ loop do
39
+ # Scan for as long as we don't see a slash
40
+ next_segment += scanner.scan(%r{[^/]*})
36
41
 
37
- if complete?(next_segment) || scanner.eos?
38
- scanner.getch # consume the slash
39
- break
42
+ if complete?(next_segment) || scanner.eos?
43
+ scanner.getch # consume the slash
44
+ break
45
+ else
46
+ next_segment += scanner.getch # append the slash
47
+ end
48
+ end
49
+
50
+ case next_segment.chomp
51
+ when ""
52
+ stack = [stack.first]
53
+ when "::"
54
+ stack.push(TOPLEVEL_BINDING)
55
+ when "."
56
+ next
57
+ when ".."
58
+ stack.pop unless stack.size == 1
40
59
  else
41
- next_segment << scanner.getch # append the slash
60
+ stack.push(Pry.binding_for(stack.last.eval(next_segment)))
42
61
  end
62
+ rescue RescuableException => e
63
+ return handle_failure(next_segment, e)
43
64
  end
44
65
 
45
- case next_segment.chomp
46
- when ""
47
- stack = [stack.first]
48
- when "::"
49
- stack.push(TOPLEVEL_BINDING)
50
- when "."
51
- next
52
- when ".."
53
- stack.pop unless stack.size == 1
54
- else
55
- stack.push(Pry.binding_for(stack.last.eval(next_segment)))
56
- end
57
- rescue RescuableException => e
58
- return handle_failure(next_segment, e)
59
- end until scanner.eos?
66
+ break if scanner.eos?
67
+ end
60
68
 
61
69
  stack
62
70
  end
@@ -1,50 +1,136 @@
1
- class Pry::Output
2
- attr_reader :_pry_
1
+ # frozen_string_literal: true
3
2
 
4
- def initialize(_pry_)
5
- @_pry_ = _pry_
6
- @boxed_io = _pry_.config.output
7
- end
3
+ class Pry
4
+ class Output
5
+ # @return [Array<Integer>] default terminal screen size [rows, cols]
6
+ DEFAULT_SIZE = [27, 80].freeze
7
+
8
+ attr_reader :pry_instance
9
+
10
+ def initialize(pry_instance)
11
+ @output = pry_instance.config.output
12
+ @color = pry_instance.config.color
13
+ end
14
+
15
+ def puts(*objs)
16
+ return print "\n" if objs.empty?
17
+
18
+ objs.each do |obj|
19
+ if (ary = Array.try_convert(obj))
20
+ puts(*ary)
21
+ else
22
+ print "#{obj.to_s.chomp}\n"
23
+ end
24
+ end
25
+ nil
26
+ end
27
+
28
+ def print(*objs)
29
+ objs.each do |obj|
30
+ @output.print decolorize_maybe(obj.to_s)
31
+ end
32
+ nil
33
+ end
34
+ alias << print
35
+ alias write print
8
36
 
9
- def puts(*objs)
10
- return print "\n" if objs.empty?
37
+ def tty?
38
+ @output.respond_to?(:tty?) && @output.tty?
39
+ end
11
40
 
12
- objs.each do |obj|
13
- if (ary = Array.try_convert(obj))
14
- puts(*ary)
41
+ def method_missing(method_name, *args, &block)
42
+ if @output.respond_to?(method_name)
43
+ @output.__send__(method_name, *args, &block)
15
44
  else
16
- print "#{obj.to_s.chomp}\n"
45
+ super
17
46
  end
18
47
  end
19
- nil
20
- end
21
48
 
22
- def print(*objs)
23
- objs.each do |obj|
24
- @boxed_io.print decolorize_maybe(obj.to_s)
49
+ def respond_to_missing?(method_name, include_private = false)
50
+ @output.respond_to?(method_name, include_private)
25
51
  end
26
- nil
27
- end
28
- alias << print
29
- alias write print
30
52
 
31
- def tty?
32
- @boxed_io.respond_to?(:tty?) and @boxed_io.tty?
33
- end
53
+ def decolorize_maybe(str)
54
+ return str if @color
34
55
 
35
- def method_missing(name, *args, &block)
36
- @boxed_io.__send__(name, *args, &block)
37
- end
56
+ Pry::Helpers::Text.strip_color(str)
57
+ end
38
58
 
39
- def respond_to_missing?(m, include_all = false)
40
- @boxed_io.respond_to?(m, include_all)
41
- end
59
+ # @return [Array<Integer>] a pair of [rows, columns] which gives the size of
60
+ # the window. If the window size cannot be determined, the default value.
61
+ def size
62
+ rows, cols = actual_screen_size
63
+ return [rows.to_i, cols.to_i] if rows.to_i != 0 && cols.to_i != 0
64
+
65
+ DEFAULT_SIZE
66
+ end
67
+
68
+ # Return a screen width or the default if that fails.
69
+ def width
70
+ size.last
71
+ end
72
+
73
+ # Return a screen height or the default if that fails.
74
+ def height
75
+ size.first
76
+ end
77
+
78
+ private
79
+
80
+ def actual_screen_size
81
+ # The best way, if possible (requires non-jruby >=1.9 or io-console gem).
82
+ io_console_size ||
83
+ # Fall back to the old standby, though it might be stale.
84
+ env_size ||
85
+ # Fall further back, though this one is also out of date without
86
+ # something calling Readline.set_screen_size.
87
+ readline_size ||
88
+ # Windows users can otherwise run ansicon and get a decent answer.
89
+ ansicon_env_size
90
+ end
91
+
92
+ def io_console_size
93
+ return if Pry::Helpers::Platform.jruby?
94
+
95
+ begin
96
+ require 'io/console'
97
+
98
+ begin
99
+ @output.winsize if tty? && @output.respond_to?(:winsize)
100
+ rescue Errno::EOPNOTSUPP # rubocop:disable Lint/HandleExceptions
101
+ # Output is probably a socket, which doesn't support #winsize.
102
+ end
103
+ rescue LoadError # rubocop:disable Lint/HandleExceptions
104
+ # They probably don't have the io/console stdlib or the io-console gem.
105
+ # We'll keep trying.
106
+ end
107
+ end
108
+
109
+ def env_size
110
+ size = [Pry::Env['LINES'] || Pry::Env['ROWS'], Pry::Env['COLUMNS']]
111
+ size if nonzero_column?(size)
112
+ end
113
+
114
+ def readline_size
115
+ return unless defined?(Readline) && Readline.respond_to?(:get_screen_size)
116
+
117
+ size = Readline.get_screen_size
118
+ size if nonzero_column?(size)
119
+ rescue Java::JavaLang::NullPointerException
120
+ # This rescue won't happen on jrubies later than:
121
+ # https://github.com/jruby/jruby/pull/436
122
+ nil
123
+ end
124
+
125
+ def ansicon_env_size
126
+ return unless Pry::Env['ANSICON'] =~ /\((.*)x(.*)\)/
127
+
128
+ size = [Regexp.last_match(2), Regexp.last_match(1)]
129
+ size if nonzero_column?(size)
130
+ end
42
131
 
43
- def decolorize_maybe(str)
44
- if _pry_.config.color
45
- str
46
- else
47
- Pry::Helpers::Text.strip_color str
132
+ def nonzero_column?(size)
133
+ size[1].to_i > 0
48
134
  end
49
135
  end
50
136
  end