pry 0.9.8.4-i386-mingw32 → 0.9.9-i386-mingw32
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.
- data/.gitignore +1 -0
- data/CHANGELOG +26 -0
- data/README.markdown +3 -3
- data/lib/pry.rb +9 -1
- data/lib/pry/code.rb +93 -0
- data/lib/pry/command.rb +35 -22
- data/lib/pry/command_set.rb +97 -67
- data/lib/pry/config.rb +63 -10
- data/lib/pry/core_extensions.rb +24 -18
- data/lib/pry/default_commands/context.rb +72 -12
- data/lib/pry/default_commands/easter_eggs.rb +4 -0
- data/lib/pry/default_commands/editing.rb +43 -15
- data/lib/pry/default_commands/find_method.rb +171 -0
- data/lib/pry/default_commands/hist.rb +10 -6
- data/lib/pry/default_commands/introspection.rb +183 -30
- data/lib/pry/default_commands/ls.rb +77 -7
- data/lib/pry/default_commands/misc.rb +1 -0
- data/lib/pry/default_commands/navigating_pry.rb +1 -8
- data/lib/pry/helpers/base_helpers.rb +10 -2
- data/lib/pry/helpers/command_helpers.rb +23 -40
- data/lib/pry/helpers/documentation_helpers.rb +65 -0
- data/lib/pry/indent.rb +17 -4
- data/lib/pry/method.rb +61 -45
- data/lib/pry/pry_class.rb +9 -3
- data/lib/pry/pry_instance.rb +99 -65
- data/lib/pry/rbx_method.rb +2 -9
- data/lib/pry/version.rb +1 -1
- data/lib/pry/wrapped_module.rb +236 -1
- data/pry.gemspec +5 -5
- data/test/helper.rb +22 -0
- data/test/test_command.rb +29 -0
- data/test/test_command_integration.rb +193 -10
- data/test/test_command_set.rb +82 -17
- data/test/test_default_commands/test_cd.rb +16 -0
- data/test/test_default_commands/test_context.rb +61 -0
- data/test/test_default_commands/test_documentation.rb +163 -43
- data/test/test_default_commands/test_find_method.rb +42 -0
- data/test/test_default_commands/test_input.rb +32 -0
- data/test/test_default_commands/test_introspection.rb +50 -197
- data/test/test_default_commands/test_ls.rb +22 -0
- data/test/test_default_commands/test_show_source.rb +306 -0
- data/test/test_pry.rb +3 -3
- data/test/test_pry_defaults.rb +21 -0
- data/test/test_sticky_locals.rb +81 -1
- data/test/test_syntax_checking.rb +7 -6
- metadata +24 -16
@@ -32,21 +32,25 @@ class Pry
|
|
32
32
|
def process
|
33
33
|
@history = Pry::Code(Pry.history.to_a)
|
34
34
|
|
35
|
+
if opts.present?(:show)
|
36
|
+
@history = @history.between(opts[:show])
|
37
|
+
end
|
38
|
+
|
39
|
+
if opts.present?(:grep)
|
40
|
+
@history = @history.grep(opts[:grep])
|
41
|
+
end
|
42
|
+
|
35
43
|
@history = case
|
36
44
|
when opts.present?(:head)
|
37
|
-
@history.
|
45
|
+
@history.take_lines(1, opts[:head] || 10)
|
38
46
|
when opts.present?(:tail)
|
39
|
-
@history.
|
47
|
+
@history.take_lines(-(opts[:tail] || 10), opts[:tail] || 10)
|
40
48
|
when opts.present?(:show)
|
41
49
|
@history.between(opts[:show])
|
42
50
|
else
|
43
51
|
@history
|
44
52
|
end
|
45
53
|
|
46
|
-
if opts.present?(:grep)
|
47
|
-
@history = @history.grep(opts[:grep])
|
48
|
-
end
|
49
|
-
|
50
54
|
if opts.present?(:'exclude-pry')
|
51
55
|
@history = @history.select { |l, ln| !command_set.valid_command?(l) }
|
52
56
|
end
|
@@ -3,23 +3,127 @@ require 'tempfile'
|
|
3
3
|
class Pry
|
4
4
|
module DefaultCommands
|
5
5
|
|
6
|
+
# For show-doc and show-source
|
7
|
+
module ModuleIntrospectionHelpers
|
8
|
+
attr_accessor :module_object
|
9
|
+
|
10
|
+
def module?(name)
|
11
|
+
self.module_object = Pry::WrappedModule.from_str(name, target)
|
12
|
+
end
|
13
|
+
|
14
|
+
def method?
|
15
|
+
!!method_object
|
16
|
+
rescue CommandError
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def process(name)
|
21
|
+
if module?(name)
|
22
|
+
code_or_doc = process_module
|
23
|
+
else method?
|
24
|
+
code_or_doc = process_method
|
25
|
+
end
|
26
|
+
|
27
|
+
render_output(code_or_doc, opts)
|
28
|
+
end
|
29
|
+
|
30
|
+
def module_start_line(mod, candidate=0)
|
31
|
+
if opts.present?(:'base-one')
|
32
|
+
1
|
33
|
+
else
|
34
|
+
mod.source_line_for_candidate(candidate)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def use_line_numbers?
|
39
|
+
opts.present?(:b) || opts.present?(:l)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
6
43
|
Introspection = Pry::CommandSet.new do
|
7
44
|
|
8
|
-
create_command "show-doc", "Show the comments above METH. Aliases: \?", :shellwords => false do
|
45
|
+
create_command "show-doc", "Show the comments above METH. Aliases: \?", :shellwords => false do
|
46
|
+
include ModuleIntrospectionHelpers
|
47
|
+
include Helpers::DocumentationHelpers
|
48
|
+
extend Helpers::BaseHelpers
|
49
|
+
|
9
50
|
banner <<-BANNER
|
10
51
|
Usage: show-doc [OPTIONS] [METH]
|
52
|
+
Aliases: ?
|
53
|
+
|
11
54
|
Show the comments above method METH. Tries instance methods first and then methods by default.
|
12
|
-
e.g show-doc hello_method
|
55
|
+
e.g show-doc hello_method # docs for hello_method
|
56
|
+
e.g show-doc Pry # docs for Pry class
|
57
|
+
e.g show-doc Pry -a # docs for all definitions of Pry class (all monkey patches)
|
13
58
|
BANNER
|
14
59
|
|
60
|
+
options :requires_gem => "ruby18_source_location" if mri_18?
|
61
|
+
|
62
|
+
def setup
|
63
|
+
require 'ruby18_source_location' if mri_18?
|
64
|
+
end
|
65
|
+
|
15
66
|
def options(opt)
|
16
67
|
method_options(opt)
|
17
68
|
opt.on :l, "line-numbers", "Show line numbers."
|
18
69
|
opt.on :b, "base-one", "Show line numbers but start numbering at 1 (useful for `amend-line` and `play` commands)."
|
19
70
|
opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
71
|
+
opt.on :a, :all, "Show docs for all definitions and monkeypatches of the module (modules only)"
|
20
72
|
end
|
21
73
|
|
22
|
-
def
|
74
|
+
def process_module
|
75
|
+
if opts.present?(:all)
|
76
|
+
all_modules
|
77
|
+
else
|
78
|
+
normal_module
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def normal_module
|
83
|
+
mod = module_object
|
84
|
+
|
85
|
+
# source_file reveals the underlying .c file in case of core
|
86
|
+
# classes on MRI. This is different to source_location, which
|
87
|
+
# will return nil.
|
88
|
+
if mod.yard_docs?
|
89
|
+
file_name, line = mod.source_file, nil
|
90
|
+
else
|
91
|
+
file_name, line = mod.source_location
|
92
|
+
end
|
93
|
+
|
94
|
+
if mod.doc.empty?
|
95
|
+
output.puts "No documentation found."
|
96
|
+
""
|
97
|
+
else
|
98
|
+
set_file_and_dir_locals(file_name) if !mod.yard_docs?
|
99
|
+
doc = ""
|
100
|
+
doc << mod.doc
|
101
|
+
|
102
|
+
doc = Code.new(doc, module_start_line(mod), :text).
|
103
|
+
with_line_numbers(use_line_numbers?).to_s
|
104
|
+
|
105
|
+
doc.insert(0, "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} @ line #{line ? line : "N/A"}:\n\n")
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def all_modules
|
110
|
+
mod = module_object
|
111
|
+
|
112
|
+
doc = ""
|
113
|
+
doc << "Found #{mod.number_of_candidates} candidates for `#{mod.name}` definition:\n"
|
114
|
+
mod.number_of_candidates.times do |v|
|
115
|
+
begin
|
116
|
+
doc << "\nCandidate #{v+1}/#{mod.number_of_candidates}: #{mod.source_file_for_candidate(v)} @ #{mod.source_line_for_candidate(v)}:\n\n"
|
117
|
+
dc = mod.doc_for_candidate(v)
|
118
|
+
doc << (dc.empty? ? "No documentation found.\n" : dc)
|
119
|
+
rescue Pry::RescuableException
|
120
|
+
next
|
121
|
+
end
|
122
|
+
end
|
123
|
+
doc
|
124
|
+
end
|
125
|
+
|
126
|
+
def process_method
|
23
127
|
meth = method_object
|
24
128
|
raise Pry::CommandError, "No documentation found." if meth.doc.nil? || meth.doc.empty?
|
25
129
|
|
@@ -30,12 +134,20 @@ class Pry
|
|
30
134
|
output.puts "#{text.bold("Signature:")} #{meth.signature}"
|
31
135
|
output.puts
|
32
136
|
|
33
|
-
if
|
137
|
+
if use_line_numbers?
|
34
138
|
doc = Code.new(doc, start_line, :text).
|
35
|
-
with_line_numbers(true)
|
139
|
+
with_line_numbers(true).to_s
|
36
140
|
end
|
37
141
|
|
38
|
-
|
142
|
+
doc
|
143
|
+
end
|
144
|
+
|
145
|
+
def module_start_line(mod, candidate=0)
|
146
|
+
if opts.present?(:'base-one')
|
147
|
+
1
|
148
|
+
else
|
149
|
+
mod.source_line_for_candidate(candidate) - mod.doc_for_candidate(candidate).lines.count
|
150
|
+
end
|
39
151
|
end
|
40
152
|
|
41
153
|
def start_line
|
@@ -45,12 +157,11 @@ class Pry
|
|
45
157
|
(method_object.source_line - method_object.doc.lines.count) || 1
|
46
158
|
end
|
47
159
|
end
|
48
|
-
|
49
160
|
end
|
50
161
|
|
51
162
|
alias_command "?", "show-doc"
|
52
163
|
|
53
|
-
create_command "stat", "View method information and set _file_ and _dir_ locals.", :shellwords => false do
|
164
|
+
create_command "stat", "View method information and set _file_ and _dir_ locals.", :shellwords => false do
|
54
165
|
banner <<-BANNER
|
55
166
|
Usage: stat [OPTIONS] [METH]
|
56
167
|
Show method information for method METH and set _file_ and _dir_ locals.
|
@@ -77,45 +188,87 @@ class Pry
|
|
77
188
|
end
|
78
189
|
end
|
79
190
|
|
80
|
-
create_command "show-
|
81
|
-
|
191
|
+
create_command "show-source" do
|
192
|
+
include ModuleIntrospectionHelpers
|
193
|
+
extend Helpers::BaseHelpers
|
194
|
+
|
195
|
+
description "Show the source for METH or CLASS. Aliases: $, show-method"
|
82
196
|
|
83
197
|
banner <<-BANNER
|
84
|
-
Usage: show-
|
85
|
-
Aliases: $, show-
|
198
|
+
Usage: show-source [OPTIONS] [METH|CLASS]
|
199
|
+
Aliases: $, show-method
|
86
200
|
|
87
|
-
Show the source for method METH. Tries instance methods first and then methods by default.
|
201
|
+
Show the source for method METH or CLASS. Tries instance methods first and then methods by default.
|
88
202
|
|
89
|
-
e.g: `show-
|
90
|
-
e.g: `show-
|
91
|
-
e.g: `show-
|
203
|
+
e.g: `show-source hello_method`
|
204
|
+
e.g: `show-source -m hello_method`
|
205
|
+
e.g: `show-source Pry#rep` # source for Pry#rep method
|
206
|
+
e.g: `show-source Pry` # source for Pry class
|
207
|
+
e.g: `show-source Pry -a` # source for all Pry class definitions (all monkey patches)
|
92
208
|
|
93
209
|
https://github.com/pry/pry/wiki/Source-browsing#wiki-Show_method
|
94
210
|
BANNER
|
95
211
|
|
96
|
-
|
97
|
-
|
98
|
-
|
212
|
+
options :shellwords => false
|
213
|
+
options :requires_gem => "ruby18_source_location" if mri_18?
|
214
|
+
|
215
|
+
def setup
|
216
|
+
require 'ruby18_source_location' if mri_18?
|
217
|
+
end
|
99
218
|
|
100
219
|
def options(opt)
|
101
220
|
method_options(opt)
|
102
221
|
opt.on :l, "line-numbers", "Show line numbers."
|
103
222
|
opt.on :b, "base-one", "Show line numbers but start numbering at 1 (useful for `amend-line` and `play` commands)."
|
104
223
|
opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
224
|
+
opt.on :a, :all, "Show source for all definitions and monkeypatches of the module (modules only)"
|
105
225
|
end
|
106
226
|
|
107
|
-
def
|
227
|
+
def process_method
|
108
228
|
raise CommandError, "Could not find method source" unless method_object.source
|
109
229
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
230
|
+
code = ""
|
231
|
+
code << make_header(method_object)
|
232
|
+
code << "#{text.bold("Owner:")} #{method_object.owner || "N/A"}\n"
|
233
|
+
code << "#{text.bold("Visibility:")} #{method_object.visibility}\n"
|
234
|
+
code << "\n"
|
114
235
|
|
115
|
-
code
|
116
|
-
with_line_numbers(use_line_numbers?)
|
236
|
+
code << Code.from_method(method_object, start_line).
|
237
|
+
with_line_numbers(use_line_numbers?).to_s
|
238
|
+
end
|
117
239
|
|
118
|
-
|
240
|
+
def process_module
|
241
|
+
if opts.present?(:all)
|
242
|
+
all_modules
|
243
|
+
else
|
244
|
+
normal_module
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def normal_module
|
249
|
+
mod = module_object
|
250
|
+
|
251
|
+
file_name, line = mod.source_location
|
252
|
+
set_file_and_dir_locals(file_name)
|
253
|
+
code = ""
|
254
|
+
code << "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} @ line #{line}:\n\n"
|
255
|
+
code << Code.from_module(mod, module_start_line(mod)).with_line_numbers(use_line_numbers?).to_s
|
256
|
+
end
|
257
|
+
|
258
|
+
def all_modules
|
259
|
+
mod = module_object
|
260
|
+
|
261
|
+
code = ""
|
262
|
+
code << "Found #{mod.number_of_candidates} candidates for `#{mod.name}` definition:\n"
|
263
|
+
mod.number_of_candidates.times do |v|
|
264
|
+
begin
|
265
|
+
code << "\nCandidate #{v+1}/#{mod.number_of_candidates}: #{mod.source_file_for_candidate(v)} @ line #{mod.source_line_for_candidate(v)}:\n\n"
|
266
|
+
code << Code.new(mod.source_for_candidate(v), module_start_line(mod, v)).with_line_numbers(use_line_numbers?).to_s
|
267
|
+
rescue Pry::RescuableException
|
268
|
+
next
|
269
|
+
end
|
270
|
+
end
|
271
|
+
code
|
119
272
|
end
|
120
273
|
|
121
274
|
def use_line_numbers?
|
@@ -131,8 +284,8 @@ class Pry
|
|
131
284
|
end
|
132
285
|
end
|
133
286
|
|
134
|
-
alias_command "show-
|
135
|
-
alias_command "$", "show-
|
287
|
+
alias_command "show-method", "show-source"
|
288
|
+
alias_command "$", "show-source"
|
136
289
|
|
137
290
|
command "show-command", "Show the source for CMD." do |*args|
|
138
291
|
target = target()
|
@@ -167,7 +320,7 @@ class Pry
|
|
167
320
|
output.puts make_header(block)
|
168
321
|
output.puts
|
169
322
|
|
170
|
-
code = Code.from_method(block).with_line_numbers(opts.present?(:'line-numbers'))
|
323
|
+
code = Code.from_method(block).with_line_numbers(opts.present?(:'line-numbers')).to_s
|
171
324
|
|
172
325
|
render_output(code, opts)
|
173
326
|
else
|
@@ -30,11 +30,15 @@ class Pry
|
|
30
30
|
opt.on :g, "globals", "Show global variables, including those builtin to Ruby (in cyan)"
|
31
31
|
opt.on :l, "locals", "Show locals, including those provided by Pry (in red)"
|
32
32
|
|
33
|
-
opt.on :c, "constants", "Show constants, highlighting classes (in blue), and exceptions (in purple)"
|
33
|
+
opt.on :c, "constants", "Show constants, highlighting classes (in blue), and exceptions (in purple).\n" +
|
34
|
+
" " * 32 + "Constants that are pending autoload? are also shown (in yellow)."
|
34
35
|
|
35
36
|
opt.on :i, "ivars", "Show instance variables (in blue) and class variables (in bright blue)"
|
36
37
|
|
37
38
|
opt.on :G, "grep", "Filter output by regular expression", :optional => false
|
39
|
+
if jruby?
|
40
|
+
opt.on :J, "all-java", "Show all the aliases for methods from java (default is to show only prettiest)"
|
41
|
+
end
|
38
42
|
end
|
39
43
|
|
40
44
|
def process
|
@@ -46,6 +50,7 @@ class Pry
|
|
46
50
|
opts.present?(:ivars))
|
47
51
|
|
48
52
|
show_methods = opts.present?(:methods) || opts.present?(:'instance-methods') || opts.present?(:ppp) || !has_opts
|
53
|
+
show_self_methods = (!has_opts && Module === obj)
|
49
54
|
show_constants = opts.present?(:constants) || (!has_opts && Module === obj)
|
50
55
|
show_ivars = opts.present?(:ivars) || !has_opts
|
51
56
|
show_locals = opts.present?(:locals) || (!has_opts && args.empty?)
|
@@ -72,7 +77,7 @@ class Pry
|
|
72
77
|
|
73
78
|
if show_methods
|
74
79
|
# methods is a hash {Module/Class => [Pry::Methods]}
|
75
|
-
methods = all_methods(obj).
|
80
|
+
methods = all_methods(obj).group_by(&:owner)
|
76
81
|
|
77
82
|
# reverse the resolution order so that the most useful information appears right by the prompt
|
78
83
|
resolution_order(obj).take_while(&below_ceiling(obj)).reverse.each do |klass|
|
@@ -81,10 +86,17 @@ class Pry
|
|
81
86
|
end
|
82
87
|
end
|
83
88
|
|
89
|
+
if show_self_methods
|
90
|
+
methods = all_methods(obj, true).select{ |m| m.owner == obj && m.name =~ grep_regex }
|
91
|
+
output_section "#{Pry::WrappedModule.new(obj).method_prefix}methods", format_methods(methods)
|
92
|
+
end
|
93
|
+
|
84
94
|
if show_ivars
|
85
95
|
klass = (Module === obj ? obj : obj.class)
|
86
|
-
|
87
|
-
|
96
|
+
ivars = Pry::Method.safe_send(obj, :instance_variables)
|
97
|
+
kvars = Pry::Method.safe_send(klass, :class_variables)
|
98
|
+
output_section("instance variables", format_variables(:instance_var, ivars))
|
99
|
+
output_section("class variables", format_variables(:class_var, kvars))
|
88
100
|
end
|
89
101
|
|
90
102
|
if show_locals
|
@@ -109,8 +121,64 @@ class Pry
|
|
109
121
|
$LAST_PAREN_MATCH $LAST_READ_LINE $MATCH $POSTMATCH $PREMATCH)
|
110
122
|
|
111
123
|
# Get all the methods that we'll want to output
|
112
|
-
def all_methods(obj)
|
113
|
-
opts.present?(:'instance-methods')
|
124
|
+
def all_methods(obj, instance_methods=false)
|
125
|
+
methods = if instance_methods || opts.present?(:'instance-methods')
|
126
|
+
Pry::Method.all_from_class(obj)
|
127
|
+
else
|
128
|
+
Pry::Method.all_from_obj(obj)
|
129
|
+
end
|
130
|
+
|
131
|
+
if jruby? && !opts.present?(:J)
|
132
|
+
methods = trim_jruby_aliases(methods)
|
133
|
+
end
|
134
|
+
|
135
|
+
methods.select{ |method| opts.present?(:ppp) || method.visibility == :public }
|
136
|
+
end
|
137
|
+
|
138
|
+
# JRuby creates lots of aliases for methods imported from java in an attempt to
|
139
|
+
# make life easier for ruby programmers.
|
140
|
+
# (e.g. getFooBar becomes get_foo_bar and foo_bar, and maybe foo_bar? if it
|
141
|
+
# returns a Boolean).
|
142
|
+
# The full transformations are in the assignAliases method of:
|
143
|
+
# https://github.com/jruby/jruby/blob/master/src/org/jruby/javasupport/JavaClass.java
|
144
|
+
#
|
145
|
+
# This has the unfortunate side-effect of making the output of ls even more
|
146
|
+
# incredibly verbose than it normally would be for these objects; and so we filter
|
147
|
+
# out all but the nicest of these aliases here.
|
148
|
+
#
|
149
|
+
# TODO: This is a little bit vague, better heuristics could be used.
|
150
|
+
# JRuby also has a lot of scala-specific logic, which we don't copy.
|
151
|
+
#
|
152
|
+
def trim_jruby_aliases(methods)
|
153
|
+
grouped = methods.group_by do |m|
|
154
|
+
m.name.sub(/\A(is|get|set)(?=[A-Z_])/, '').gsub(/[_?=]/, '').downcase
|
155
|
+
end
|
156
|
+
|
157
|
+
grouped.map do |key, values|
|
158
|
+
values = values.sort_by do |m|
|
159
|
+
rubbishness(m.name)
|
160
|
+
end
|
161
|
+
|
162
|
+
found = []
|
163
|
+
values.select do |x|
|
164
|
+
(!found.any?{ |y| x == y }) && found << x
|
165
|
+
end
|
166
|
+
end.flatten(1)
|
167
|
+
end
|
168
|
+
|
169
|
+
# When removing jruby aliases, we want to keep the alias that is "least rubbish"
|
170
|
+
# according to this metric.
|
171
|
+
def rubbishness(name)
|
172
|
+
name.each_char.map{ |x|
|
173
|
+
case x
|
174
|
+
when /[A-Z]/
|
175
|
+
1
|
176
|
+
when '?', '=', '!'
|
177
|
+
-2
|
178
|
+
else
|
179
|
+
0
|
180
|
+
end
|
181
|
+
}.inject(&:+) + (name.size / 100.0)
|
114
182
|
end
|
115
183
|
|
116
184
|
def resolution_order(obj)
|
@@ -152,7 +220,7 @@ class Pry
|
|
152
220
|
|
153
221
|
def format_constants(mod, constants)
|
154
222
|
constants.sort_by(&:downcase).map do |name|
|
155
|
-
if const = (!mod.autoload?(name) && mod.const_get(name) rescue nil)
|
223
|
+
if const = (!mod.autoload?(name) && (mod.const_get(name) || true) rescue nil)
|
156
224
|
if (const < Exception rescue false)
|
157
225
|
color(:exception_constant, name)
|
158
226
|
elsif (Module === mod.const_get(name) rescue false)
|
@@ -160,6 +228,8 @@ class Pry
|
|
160
228
|
else
|
161
229
|
color(:constant, name)
|
162
230
|
end
|
231
|
+
else
|
232
|
+
color(:unloaded_constant, name)
|
163
233
|
end
|
164
234
|
end
|
165
235
|
end
|