pry 0.12.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +162 -1
- data/LICENSE +1 -1
- data/README.md +331 -269
- data/bin/pry +5 -0
- data/lib/pry.rb +132 -119
- data/lib/pry/basic_object.rb +8 -4
- data/lib/pry/block_command.rb +22 -0
- data/lib/pry/class_command.rb +194 -0
- data/lib/pry/cli.rb +43 -51
- data/lib/pry/code.rb +40 -28
- data/lib/pry/code/code_file.rb +28 -24
- data/lib/pry/code/code_range.rb +4 -2
- data/lib/pry/code/loc.rb +15 -8
- data/lib/pry/code_object.rb +40 -38
- data/lib/pry/color_printer.rb +47 -46
- data/lib/pry/command.rb +166 -369
- data/lib/pry/command_set.rb +76 -73
- data/lib/pry/command_state.rb +31 -0
- data/lib/pry/commands/amend_line.rb +86 -81
- data/lib/pry/commands/bang.rb +18 -14
- data/lib/pry/commands/bang_pry.rb +15 -11
- data/lib/pry/commands/cat.rb +61 -54
- data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
- data/lib/pry/commands/cat/exception_formatter.rb +71 -60
- data/lib/pry/commands/cat/file_formatter.rb +55 -49
- data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
- data/lib/pry/commands/cd.rb +40 -35
- data/lib/pry/commands/change_inspector.rb +29 -22
- data/lib/pry/commands/change_prompt.rb +44 -39
- data/lib/pry/commands/clear_screen.rb +16 -10
- data/lib/pry/commands/code_collector.rb +148 -133
- data/lib/pry/commands/disable_pry.rb +23 -19
- data/lib/pry/commands/easter_eggs.rb +19 -30
- data/lib/pry/commands/edit.rb +184 -161
- data/lib/pry/commands/edit/exception_patcher.rb +21 -17
- data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
- data/lib/pry/commands/exit.rb +39 -35
- data/lib/pry/commands/exit_all.rb +24 -20
- data/lib/pry/commands/exit_program.rb +20 -16
- data/lib/pry/commands/find_method.rb +168 -160
- data/lib/pry/commands/fix_indent.rb +16 -12
- data/lib/pry/commands/help.rb +140 -133
- data/lib/pry/commands/hist.rb +151 -150
- data/lib/pry/commands/import_set.rb +20 -16
- data/lib/pry/commands/jump_to.rb +25 -21
- data/lib/pry/commands/list_inspectors.rb +35 -28
- data/lib/pry/commands/ls.rb +124 -102
- data/lib/pry/commands/ls/constants.rb +59 -42
- data/lib/pry/commands/ls/formatter.rb +50 -46
- data/lib/pry/commands/ls/globals.rb +38 -34
- data/lib/pry/commands/ls/grep.rb +17 -13
- data/lib/pry/commands/ls/instance_vars.rb +29 -27
- data/lib/pry/commands/ls/interrogatable.rb +18 -12
- data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
- data/lib/pry/commands/ls/local_names.rb +26 -22
- data/lib/pry/commands/ls/local_vars.rb +38 -28
- data/lib/pry/commands/ls/ls_entity.rb +47 -51
- data/lib/pry/commands/ls/methods.rb +44 -43
- data/lib/pry/commands/ls/methods_helper.rb +46 -42
- data/lib/pry/commands/ls/self_methods.rb +23 -22
- data/lib/pry/commands/nesting.rb +21 -17
- data/lib/pry/commands/play.rb +93 -82
- data/lib/pry/commands/pry_backtrace.rb +22 -17
- data/lib/pry/commands/pry_version.rb +15 -11
- data/lib/pry/commands/raise_up.rb +27 -22
- data/lib/pry/commands/reload_code.rb +60 -48
- data/lib/pry/commands/reset.rb +16 -12
- data/lib/pry/commands/ri.rb +55 -45
- data/lib/pry/commands/save_file.rb +45 -43
- data/lib/pry/commands/shell_command.rb +51 -51
- data/lib/pry/commands/shell_mode.rb +21 -17
- data/lib/pry/commands/show_doc.rb +80 -68
- data/lib/pry/commands/show_info.rb +189 -171
- data/lib/pry/commands/show_input.rb +16 -11
- data/lib/pry/commands/show_source.rb +110 -45
- data/lib/pry/commands/stat.rb +35 -31
- data/lib/pry/commands/switch_to.rb +21 -15
- data/lib/pry/commands/toggle_color.rb +20 -16
- data/lib/pry/commands/watch_expression.rb +89 -86
- data/lib/pry/commands/watch_expression/expression.rb +32 -27
- data/lib/pry/commands/whereami.rb +156 -148
- data/lib/pry/commands/wtf.rb +75 -50
- data/lib/pry/config.rb +307 -25
- data/lib/pry/config/attributable.rb +22 -0
- data/lib/pry/config/lazy_value.rb +29 -0
- data/lib/pry/config/memoized_value.rb +34 -0
- data/lib/pry/config/value.rb +24 -0
- data/lib/pry/control_d_handler.rb +28 -0
- data/lib/pry/core_extensions.rb +9 -7
- data/lib/pry/editor.rb +48 -21
- data/lib/pry/env.rb +18 -0
- data/lib/pry/exception_handler.rb +43 -0
- data/lib/pry/exceptions.rb +13 -16
- data/lib/pry/forwardable.rb +5 -1
- data/lib/pry/helpers.rb +2 -0
- data/lib/pry/helpers/base_helpers.rb +68 -197
- data/lib/pry/helpers/command_helpers.rb +50 -61
- data/lib/pry/helpers/documentation_helpers.rb +20 -13
- data/lib/pry/helpers/options_helpers.rb +14 -7
- data/lib/pry/helpers/platform.rb +7 -5
- data/lib/pry/helpers/table.rb +33 -26
- data/lib/pry/helpers/text.rb +17 -14
- data/lib/pry/history.rb +48 -56
- data/lib/pry/hooks.rb +21 -12
- data/lib/pry/indent.rb +54 -50
- data/lib/pry/input_completer.rb +248 -230
- data/lib/pry/input_lock.rb +8 -9
- data/lib/pry/inspector.rb +36 -24
- data/lib/pry/last_exception.rb +45 -45
- data/lib/pry/method.rb +141 -94
- data/lib/pry/method/disowned.rb +16 -4
- data/lib/pry/method/patcher.rb +12 -3
- data/lib/pry/method/weird_method_locator.rb +68 -44
- data/lib/pry/object_path.rb +33 -25
- data/lib/pry/output.rb +121 -35
- data/lib/pry/pager.rb +186 -180
- data/lib/pry/prompt.rb +123 -54
- data/lib/pry/pry_class.rb +61 -103
- data/lib/pry/pry_instance.rb +217 -215
- data/lib/pry/repl.rb +18 -22
- data/lib/pry/repl_file_loader.rb +27 -21
- data/lib/pry/ring.rb +11 -6
- data/lib/pry/slop.rb +574 -563
- data/lib/pry/slop/commands.rb +164 -169
- data/lib/pry/slop/option.rb +172 -168
- data/lib/pry/syntax_highlighter.rb +26 -0
- data/lib/pry/system_command_handler.rb +17 -0
- data/lib/pry/testable.rb +59 -61
- data/lib/pry/testable/evalable.rb +21 -12
- data/lib/pry/testable/mockable.rb +18 -10
- data/lib/pry/testable/pry_tester.rb +71 -56
- data/lib/pry/testable/utility.rb +29 -21
- data/lib/pry/testable/variables.rb +49 -43
- data/lib/pry/version.rb +3 -1
- data/lib/pry/warning.rb +27 -0
- data/lib/pry/wrapped_module.rb +51 -42
- data/lib/pry/wrapped_module/candidate.rb +21 -14
- metadata +35 -35
- data/lib/pry/commands.rb +0 -6
- data/lib/pry/commands/disabled_commands.rb +0 -2
- data/lib/pry/commands/gem_cd.rb +0 -26
- data/lib/pry/commands/gem_install.rb +0 -32
- data/lib/pry/commands/gem_list.rb +0 -33
- data/lib/pry/commands/gem_open.rb +0 -29
- data/lib/pry/commands/gem_readme.rb +0 -25
- data/lib/pry/commands/gem_search.rb +0 -40
- data/lib/pry/commands/gem_stats.rb +0 -83
- data/lib/pry/commands/gist.rb +0 -102
- data/lib/pry/commands/install_command.rb +0 -54
- data/lib/pry/config/behavior.rb +0 -255
- data/lib/pry/config/convenience.rb +0 -28
- data/lib/pry/config/default.rb +0 -159
- data/lib/pry/config/memoization.rb +0 -48
- data/lib/pry/platform.rb +0 -91
- data/lib/pry/plugins.rb +0 -122
- data/lib/pry/rubygem.rb +0 -84
- data/lib/pry/terminal.rb +0 -91
data/lib/pry/method/disowned.rb
CHANGED
@@ -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
|
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
|
-
|
49
|
-
|
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
|
-
|
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
|
data/lib/pry/method/patcher.rb
CHANGED
@@ -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
|
-
|
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,
|
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
|
10
|
-
#
|
11
|
-
# search vertically up the
|
12
|
-
# and for 2. we search laterally along the object's
|
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]
|
27
|
+
# @param [Binding] binding
|
25
28
|
# @return [Boolean]
|
26
|
-
def normal_method?(method,
|
27
|
-
if method
|
28
|
-
|
29
|
-
|
30
|
-
|
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,
|
37
|
-
|
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
|
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
|
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
|
-
!!(
|
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
|
-
|
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.
|
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
|
-
|
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
|
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
|
98
|
-
# __FILE__ and __LINE__ the binding is at, we can hope to
|
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,
|
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
|
-
|
116
|
-
|
117
|
-
|
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
|
157
|
+
return unless valid_file?(target_file)
|
137
158
|
|
138
159
|
alias_name = all_methods_for(target_self).find do |v|
|
139
|
-
|
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(
|
146
|
-
return
|
167
|
+
def expanded_source_location(source_location)
|
168
|
+
return unless source_location
|
147
169
|
|
148
170
|
if pry_file?
|
149
|
-
|
171
|
+
source_location
|
150
172
|
else
|
151
|
-
[File.expand_path(
|
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
|
-
|
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 =
|
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)
|
data/lib/pry/object_path.rb
CHANGED
@@ -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
|
-
|
31
|
-
|
34
|
+
loop do
|
35
|
+
begin
|
36
|
+
next_segment = ""
|
32
37
|
|
33
|
-
|
34
|
-
|
35
|
-
|
38
|
+
loop do
|
39
|
+
# Scan for as long as we don't see a slash
|
40
|
+
next_segment += scanner.scan(%r{[^/]*})
|
36
41
|
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
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
|
-
|
46
|
-
|
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
|
data/lib/pry/output.rb
CHANGED
@@ -1,50 +1,136 @@
|
|
1
|
-
|
2
|
-
attr_reader :_pry_
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
@
|
7
|
-
|
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
|
-
|
10
|
-
|
37
|
+
def tty?
|
38
|
+
@output.respond_to?(:tty?) && @output.tty?
|
39
|
+
end
|
11
40
|
|
12
|
-
|
13
|
-
if
|
14
|
-
|
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
|
-
|
45
|
+
super
|
17
46
|
end
|
18
47
|
end
|
19
|
-
nil
|
20
|
-
end
|
21
48
|
|
22
|
-
|
23
|
-
|
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
|
-
|
32
|
-
|
33
|
-
end
|
53
|
+
def decolorize_maybe(str)
|
54
|
+
return str if @color
|
34
55
|
|
35
|
-
|
36
|
-
|
37
|
-
end
|
56
|
+
Pry::Helpers::Text.strip_color(str)
|
57
|
+
end
|
38
58
|
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
44
|
-
|
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
|