pry 0.9.11.4-i386-mingw32 → 0.9.12-i386-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +2 -0
- data/CHANGELOG +19 -0
- data/Rakefile +4 -0
- data/lib/pry.rb +1 -1
- data/lib/pry/cli.rb +14 -8
- data/lib/pry/code.rb +3 -3
- data/lib/pry/command.rb +20 -5
- data/lib/pry/command_set.rb +3 -3
- data/lib/pry/commands.rb +1 -1
- data/lib/pry/commands/disabled_commands.rb +2 -0
- data/lib/pry/commands/ls.rb +1 -2
- data/lib/pry/commands/reload_code.rb +8 -1
- data/lib/pry/commands/show_info.rb +66 -5
- data/lib/pry/commands/show_source.rb +2 -1
- data/lib/pry/commands/whereami.rb +87 -19
- data/lib/pry/completion.rb +13 -4
- data/lib/pry/helpers/base_helpers.rb +5 -2
- data/lib/pry/helpers/command_helpers.rb +3 -1
- data/lib/pry/helpers/documentation_helpers.rb +18 -7
- data/lib/pry/helpers/table.rb +4 -4
- data/lib/pry/indent.rb +2 -7
- data/lib/pry/method.rb +89 -129
- data/lib/pry/method/disowned.rb +53 -0
- data/lib/pry/method/weird_method_locator.rb +186 -0
- data/lib/pry/module_candidate.rb +13 -8
- data/lib/pry/pager.rb +12 -11
- data/lib/pry/plugins.rb +2 -0
- data/lib/pry/pry_class.rb +19 -3
- data/lib/pry/pry_instance.rb +3 -0
- data/lib/pry/terminal.rb +78 -0
- data/lib/pry/version.rb +1 -1
- data/lib/pry/wrapped_module.rb +63 -1
- data/spec/Procfile +3 -0
- data/spec/command_helpers_spec.rb +21 -1
- data/spec/commands/ls_spec.rb +4 -0
- data/spec/commands/show_doc_spec.rb +255 -123
- data/spec/commands/show_source_spec.rb +421 -236
- data/spec/commands/whereami_spec.rb +60 -11
- data/spec/completion_spec.rb +6 -0
- data/spec/documentation_helper_spec.rb +73 -0
- data/spec/fixtures/whereami_helper.rb +6 -0
- data/spec/helpers/table_spec.rb +19 -0
- data/spec/method_spec.rb +24 -7
- metadata +12 -5
- data/.gemtest +0 -0
- data/lib/pry/commands/deprecated_commands.rb +0 -2
- data/lib/pry/terminal_info.rb +0 -48
data/lib/pry/completion.rb
CHANGED
@@ -71,9 +71,18 @@ class Pry
|
|
71
71
|
# get new target for 1/2 and find candidates for 3
|
72
72
|
path, input = build_path(input)
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
# We silence warnings here or Ruby 1.8 cries about "multiple values for
|
75
|
+
# block 0 for 1".
|
76
|
+
Helpers::BaseHelpers.silence_warnings do
|
77
|
+
unless path.call.empty?
|
78
|
+
target = begin
|
79
|
+
ctx = Helpers::BaseHelpers.context_from_object_path(path.call, pry)
|
80
|
+
ctx.first
|
81
|
+
rescue Pry::CommandError
|
82
|
+
[]
|
83
|
+
end
|
84
|
+
target = target.last
|
85
|
+
end
|
77
86
|
end
|
78
87
|
|
79
88
|
begin
|
@@ -283,7 +292,7 @@ class Pry
|
|
283
292
|
contexts = input.chomp('/').split(/\//)
|
284
293
|
input = contexts[-1]
|
285
294
|
|
286
|
-
path =
|
295
|
+
path = Proc.new do |input|
|
287
296
|
p = contexts[0..-2].push(input).join('/')
|
288
297
|
p += '/' if trailing_slash && !input.nil?
|
289
298
|
p
|
@@ -83,12 +83,15 @@ class Pry
|
|
83
83
|
defined?(Win32::Console) || ENV['ANSICON']
|
84
84
|
end
|
85
85
|
|
86
|
-
# are we on Jruby platform?
|
87
86
|
def jruby?
|
88
87
|
RbConfig::CONFIG['ruby_install_name'] == 'jruby'
|
89
88
|
end
|
90
89
|
|
91
|
-
|
90
|
+
def jruby_19?
|
91
|
+
RbConfig::CONFIG['ruby_install_name'] == 'jruby' &&
|
92
|
+
RbConfig::CONFIG['ruby_version'] == '1.9'
|
93
|
+
end
|
94
|
+
|
92
95
|
def rbx?
|
93
96
|
RbConfig::CONFIG['ruby_install_name'] == 'rbx'
|
94
97
|
end
|
@@ -84,7 +84,9 @@ class Pry
|
|
84
84
|
text = text.sub(/^[ \t]+$/, '')
|
85
85
|
|
86
86
|
# Find the longest common whitespace to all indented lines
|
87
|
-
|
87
|
+
# Ignore lines containing just -- or ++ as these seem to be used by
|
88
|
+
# comment authors as delimeters.
|
89
|
+
margin = text.scan(/^[ \t]*(?!--\n|\+\+\n)(?=[^ \t\n])/).inject do |current_margin, next_indent|
|
88
90
|
if next_indent.start_with?(current_margin)
|
89
91
|
current_margin
|
90
92
|
elsif current_margin.start_with?(next_indent)
|
@@ -4,14 +4,18 @@ class Pry
|
|
4
4
|
# This class contains methods useful for extracting
|
5
5
|
# documentation from methods and classes.
|
6
6
|
module DocumentationHelpers
|
7
|
+
|
8
|
+
module_function
|
9
|
+
|
7
10
|
def process_rdoc(comment)
|
11
|
+
return comment unless Pry.color
|
8
12
|
comment = comment.dup
|
9
|
-
comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) {
|
10
|
-
gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) {
|
11
|
-
gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) {
|
12
|
-
gsub(/\B\+(\w
|
13
|
-
gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) {
|
14
|
-
gsub(/`(?:\s*\n)?([^\e]*?)\s*`/) { "`#{
|
13
|
+
comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { CodeRay.scan($1, :ruby).term }.
|
14
|
+
gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { "\e[1m#{$1}\e[0m" }.
|
15
|
+
gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { "\e[1m#{$1}\e[0m" }.
|
16
|
+
gsub(/\B\+(\w+?)\+\B/) { "\e[32m#{$1}\e[0m" }.
|
17
|
+
gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { CodeRay.scan($1, :ruby).term }.
|
18
|
+
gsub(/`(?:\s*\n)?([^\e]*?)\s*`/) { "`#{CodeRay.scan($1, :ruby).term}`" }
|
15
19
|
end
|
16
20
|
|
17
21
|
def process_yardoc_tag(comment, tag)
|
@@ -46,10 +50,17 @@ class Pry
|
|
46
50
|
code.sub(/\A\s*\/\*.*?\*\/\s*/m, '')
|
47
51
|
end
|
48
52
|
|
53
|
+
# Given a string that makes up a comment in a source-code file parse out the content
|
54
|
+
# that the user is intended to read. (i.e. without leading indentation, #-characters
|
55
|
+
# or shebangs)
|
56
|
+
#
|
49
57
|
# @param [String] comment
|
50
58
|
# @return [String]
|
51
|
-
def
|
59
|
+
def get_comment_content(comment)
|
52
60
|
comment = comment.dup
|
61
|
+
# Remove #!/usr/bin/ruby
|
62
|
+
comment.gsub!(/\A\#!.*$/, '')
|
63
|
+
# Remove leading empty comment lines
|
53
64
|
comment.gsub!(/\A\#+?$/, '')
|
54
65
|
comment.gsub!(/^\s*#/, '')
|
55
66
|
strip_leading_whitespace(comment)
|
data/lib/pry/helpers/table.rb
CHANGED
@@ -3,7 +3,7 @@ class Pry
|
|
3
3
|
def self.tablify_or_one_line(heading, things)
|
4
4
|
plain_heading = Pry::Helpers::Text.strip_color(heading)
|
5
5
|
attempt = Table.new(things, :column_count => things.size)
|
6
|
-
if attempt.fits_on_line?(
|
6
|
+
if attempt.fits_on_line?(Terminal.width! - plain_heading.size - 2)
|
7
7
|
"#{heading}: #{attempt}\n"
|
8
8
|
else
|
9
9
|
"#{heading}: \n#{tablify_to_screen_width(things, :indent => ' ')}\n"
|
@@ -13,16 +13,16 @@ class Pry
|
|
13
13
|
def self.tablify_to_screen_width(things, options = {})
|
14
14
|
things = things.compact
|
15
15
|
if indent = options[:indent]
|
16
|
-
usable_width =
|
16
|
+
usable_width = Terminal.width! - indent.size
|
17
17
|
tablify(things, usable_width).to_s.gsub(/^/, indent)
|
18
18
|
else
|
19
|
-
tablify(things,
|
19
|
+
tablify(things, Terminal.width!).to_s
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def self.tablify(things, line_length)
|
24
24
|
table = Table.new(things, :column_count => things.size)
|
25
|
-
table.column_count -= 1 until
|
25
|
+
table.column_count -= 1 until 1 == table.column_count or
|
26
26
|
table.fits_on_line?(line_length)
|
27
27
|
table
|
28
28
|
end
|
data/lib/pry/indent.rb
CHANGED
@@ -1,12 +1,6 @@
|
|
1
1
|
require 'coderay'
|
2
2
|
|
3
3
|
class Pry
|
4
|
-
# Load io-console if possible, so that we can use $stdout.winsize.
|
5
|
-
begin
|
6
|
-
require 'io/console'
|
7
|
-
rescue LoadError
|
8
|
-
end
|
9
|
-
|
10
4
|
##
|
11
5
|
# Pry::Indent is a class that can be used to indent a number of lines
|
12
6
|
# containing Ruby code similar as to how IRB does it (but better). The class
|
@@ -389,10 +383,11 @@ class Pry
|
|
389
383
|
# the difference in length between the old line and the new one).
|
390
384
|
# @return [String]
|
391
385
|
def correct_indentation(prompt, code, overhang=0)
|
386
|
+
prompt = prompt.delete("\001\002")
|
392
387
|
full_line = prompt + code
|
393
388
|
whitespace = ' ' * overhang
|
394
389
|
|
395
|
-
_, cols =
|
390
|
+
_, cols = Terminal.screen_size
|
396
391
|
|
397
392
|
cols = cols.to_i
|
398
393
|
lines = cols != 0 ? (full_line.length / cols + 1) : 1
|
data/lib/pry/method.rb
CHANGED
@@ -17,9 +17,12 @@ class Pry
|
|
17
17
|
# This class wraps the normal `Method` and `UnboundMethod` classes
|
18
18
|
# to provide extra functionality useful to Pry.
|
19
19
|
class Method
|
20
|
+
require 'pry/method/weird_method_locator'
|
21
|
+
require 'pry/method/disowned'
|
22
|
+
|
20
23
|
extend Helpers::BaseHelpers
|
21
24
|
include Helpers::BaseHelpers
|
22
|
-
include RbxMethod if
|
25
|
+
include RbxMethod if rbx?
|
23
26
|
include Helpers::DocumentationHelpers
|
24
27
|
include CodeObject::Helpers
|
25
28
|
|
@@ -82,37 +85,11 @@ class Pry
|
|
82
85
|
Disowned.new(b.eval('self'), meth_name.to_s)
|
83
86
|
end
|
84
87
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
# class B < A; def b; super; end; end
|
90
|
-
#
|
91
|
-
# Given that we can normally find the source_range of methods, and that we know which
|
92
|
-
# __FILE__ and __LINE__ the binding is at, we can hope to disambiguate these cases.
|
93
|
-
#
|
94
|
-
# This obviously won't work if the source is unavaiable for some reason, or if both
|
95
|
-
# methods have the same __FILE__ and __LINE__, or if we're in rbx where b.eval('__LINE__')
|
96
|
-
# is broken.
|
97
|
-
#
|
98
|
-
guess = method
|
99
|
-
|
100
|
-
while guess
|
101
|
-
# needs rescue if this is a Disowned method or a C method or something...
|
102
|
-
# TODO: Fix up the exception handling so we don't need a bare rescue
|
103
|
-
if (guess.source_file && guess.source_range rescue false) &&
|
104
|
-
File.expand_path(guess.source_file) == File.expand_path(b.eval('__FILE__')) &&
|
105
|
-
guess.source_range.include?(b.eval('__LINE__'))
|
106
|
-
return guess
|
107
|
-
else
|
108
|
-
guess = guess.super
|
109
|
-
end
|
88
|
+
if WeirdMethodLocator.weird_method?(method, b)
|
89
|
+
WeirdMethodLocator.new(method, b).get_method || method
|
90
|
+
else
|
91
|
+
method
|
110
92
|
end
|
111
|
-
|
112
|
-
# Uhoh... none of the methods in the chain had the right __FILE__ and __LINE__
|
113
|
-
# This may be caused by rbx https://github.com/rubinius/rubinius/issues/953,
|
114
|
-
# or other unknown circumstances (TODO: we should warn the user when this happens)
|
115
|
-
method
|
116
93
|
end
|
117
94
|
end
|
118
95
|
|
@@ -196,6 +173,19 @@ class Pry
|
|
196
173
|
([klass] + klass.ancestors).uniq
|
197
174
|
end
|
198
175
|
|
176
|
+
def method_definition?(name, definition_line)
|
177
|
+
singleton_method_definition?(name, definition_line) ||
|
178
|
+
instance_method_definition?(name, definition_line)
|
179
|
+
end
|
180
|
+
|
181
|
+
def singleton_method_definition?(name, definition_line)
|
182
|
+
/^define_singleton_method\(?\s*[:\"\']#{name}|^def\s*self\.#{name}/ =~ definition_line.strip
|
183
|
+
end
|
184
|
+
|
185
|
+
def instance_method_definition?(name, definition_line)
|
186
|
+
/^define_method\(?\s*[:\"\']#{name}|^def\s*#{name}/ =~ definition_line.strip
|
187
|
+
end
|
188
|
+
|
199
189
|
private
|
200
190
|
|
201
191
|
# See all_from_class and all_from_obj.
|
@@ -310,12 +300,12 @@ class Pry
|
|
310
300
|
info = pry_doc_info
|
311
301
|
info.docstring if info
|
312
302
|
when :ruby
|
313
|
-
if
|
314
|
-
|
303
|
+
if rbx? && !pry_method?
|
304
|
+
get_comment_content(core_doc)
|
315
305
|
elsif pry_method?
|
316
|
-
|
306
|
+
get_comment_content(doc_for_pry_method)
|
317
307
|
else
|
318
|
-
|
308
|
+
get_comment_content(@method.comment)
|
319
309
|
end
|
320
310
|
end
|
321
311
|
end
|
@@ -327,7 +317,7 @@ class Pry
|
|
327
317
|
end
|
328
318
|
|
329
319
|
def source_location
|
330
|
-
if @method.source_location &&
|
320
|
+
if @method.source_location && rbx?
|
331
321
|
file, line = @method.source_location
|
332
322
|
[RbxPath.convert_path_to_full(file), line]
|
333
323
|
else
|
@@ -339,7 +329,7 @@ class Pry
|
|
339
329
|
# `nil` if the filename is unavailable.
|
340
330
|
def source_file
|
341
331
|
if source_location.nil?
|
342
|
-
if !
|
332
|
+
if !rbx? and source_type == :c
|
343
333
|
info = pry_doc_info
|
344
334
|
info.file if info
|
345
335
|
end
|
@@ -423,6 +413,21 @@ class Pry
|
|
423
413
|
!!(source_file and source_file =~ /(\(.*\))|<.*>/)
|
424
414
|
end
|
425
415
|
|
416
|
+
# @return [Boolean] Whether the method is unbound.
|
417
|
+
def unbound_method?
|
418
|
+
is_a?(::UnboundMethod)
|
419
|
+
end
|
420
|
+
|
421
|
+
# @return [Boolean] Whether the method is bound.
|
422
|
+
def bound_method?
|
423
|
+
is_a?(::Method)
|
424
|
+
end
|
425
|
+
|
426
|
+
# @return [Boolean] Whether the method is a singleton method.
|
427
|
+
def singleton_method?
|
428
|
+
wrapped_owner.singleton_class?
|
429
|
+
end
|
430
|
+
|
426
431
|
# @return [Boolean] Was the method defined within the Pry REPL?
|
427
432
|
def pry_method?
|
428
433
|
source_file == Pry.eval_path
|
@@ -479,113 +484,68 @@ class Pry
|
|
479
484
|
end
|
480
485
|
|
481
486
|
private
|
482
|
-
# @return [YARD::CodeObjects::MethodObject]
|
483
|
-
# @raise [CommandError] Raises when the method can't be found or `pry-doc` isn't installed.
|
484
|
-
def pry_doc_info
|
485
|
-
if Pry.config.has_pry_doc
|
486
|
-
Pry::MethodInfo.info_for(@method) or raise CommandError, "Cannot locate this method: #{name}. (source_location returns nil)"
|
487
|
-
else
|
488
|
-
raise CommandError, "Cannot locate this method: #{name}. Try `gem install pry-doc` to get access to Ruby Core documentation."
|
489
|
-
end
|
490
|
-
end
|
491
|
-
|
492
|
-
# FIXME: a very similar method to this exists on WrappedModule: extract_doc_for_candidate
|
493
|
-
def doc_for_pry_method
|
494
|
-
_, line_num = source_location
|
495
|
-
|
496
|
-
buffer = ""
|
497
|
-
Pry.line_buffer[0..(line_num - 1)].each do |line|
|
498
|
-
# Add any line that is a valid ruby comment,
|
499
|
-
# but clear as soon as we hit a non comment line.
|
500
|
-
if (line =~ /^\s*#/) || (line =~ /^\s*$/)
|
501
|
-
buffer << line.lstrip
|
502
|
-
else
|
503
|
-
buffer.replace("")
|
504
|
-
end
|
505
|
-
end
|
506
487
|
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
while ancestors[i] && !(ancestors[i].method_defined?(name) || ancestors[i].private_method_defined?(name))
|
517
|
-
i += 1
|
518
|
-
end
|
519
|
-
next_owner = ancestors[i] or return nil
|
488
|
+
# @return [YARD::CodeObjects::MethodObject]
|
489
|
+
# @raise [CommandError] when the method can't be found or `pry-doc` isn't installed.
|
490
|
+
def pry_doc_info
|
491
|
+
if Pry.config.has_pry_doc
|
492
|
+
Pry::MethodInfo.info_for(@method) or raise CommandError, "Cannot locate this method: #{name}. (source_location returns nil)"
|
493
|
+
else
|
494
|
+
fail_msg = "Cannot locate this method: #{name}."
|
495
|
+
if mri_18? || mri_19?
|
496
|
+
fail_msg += ' Try `gem-install pry-doc` to get access to Ruby Core documentation.'
|
520
497
|
end
|
521
|
-
|
522
|
-
safe_send(next_owner, :instance_method, name) rescue nil
|
498
|
+
raise CommandError, fail_msg
|
523
499
|
end
|
500
|
+
end
|
524
501
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
return nil if first_ln.strip !~ /^def /
|
502
|
+
# FIXME: a very similar method to this exists on WrappedModule: extract_doc_for_candidate
|
503
|
+
def doc_for_pry_method
|
504
|
+
_, line_num = source_location
|
529
505
|
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
506
|
+
buffer = ""
|
507
|
+
Pry.line_buffer[0..(line_num - 1)].each do |line|
|
508
|
+
# Add any line that is a valid ruby comment,
|
509
|
+
# but clear as soon as we hit a non comment line.
|
510
|
+
if (line =~ /^\s*#/) || (line =~ /^\s*$/)
|
511
|
+
buffer << line.lstrip
|
512
|
+
else
|
513
|
+
buffer.replace("")
|
536
514
|
end
|
537
|
-
|
538
|
-
nil
|
539
515
|
end
|
540
516
|
|
541
|
-
|
542
|
-
|
543
|
-
# e.g.
|
544
|
-
# class C
|
545
|
-
# def foo
|
546
|
-
# C.send(:undefine_method, :foo)
|
547
|
-
# Pry::Method.from_binding(binding)
|
548
|
-
# end
|
549
|
-
# end
|
550
|
-
#
|
551
|
-
# In this case we assume that the "owner" is the singleton class of the receiver.
|
552
|
-
#
|
553
|
-
# This occurs mainly in Sinatra applications.
|
554
|
-
class Disowned < Method
|
555
|
-
attr_reader :receiver, :name
|
517
|
+
buffer
|
518
|
+
end
|
556
519
|
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
520
|
+
# @param [Class, Module] ancestors The ancestors to investigate
|
521
|
+
# @return [Method] The unwrapped super-method
|
522
|
+
def super_using_ancestors(ancestors, times=1)
|
523
|
+
next_owner = self.owner
|
524
|
+
times.times do
|
525
|
+
i = ancestors.index(next_owner) + 1
|
526
|
+
while ancestors[i] && !(ancestors[i].method_defined?(name) || ancestors[i].private_method_defined?(name))
|
527
|
+
i += 1
|
528
|
+
end
|
529
|
+
next_owner = ancestors[i] or return nil
|
563
530
|
end
|
564
531
|
|
565
|
-
|
566
|
-
|
567
|
-
def undefined?
|
568
|
-
true
|
569
|
-
end
|
532
|
+
safe_send(next_owner, :instance_method, name) rescue nil
|
533
|
+
end
|
570
534
|
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
end
|
535
|
+
# @param [String] first_ln The first line of a method definition.
|
536
|
+
# @return [String, nil]
|
537
|
+
def method_name_from_first_line(first_ln)
|
538
|
+
return nil if first_ln.strip !~ /^def /
|
576
539
|
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
540
|
+
tokens = CodeRay.scan(first_ln, :ruby)
|
541
|
+
tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens)
|
542
|
+
tokens.each_cons(2) do |t1, t2|
|
543
|
+
if t2.last == :method || t2.last == :ident && t1 == [".", :operator]
|
544
|
+
return t2.first
|
545
|
+
end
|
582
546
|
end
|
583
547
|
|
584
|
-
|
585
|
-
def method_missing(meth_name, *args, &block)
|
586
|
-
raise "Cannot call '#{meth_name}' on an undef'd method." if method(:name).respond_to?(meth_name)
|
587
|
-
Object.instance_method(:method_missing).bind(self).call(meth_name, *args, &block)
|
588
|
-
end
|
548
|
+
nil
|
589
549
|
end
|
590
550
|
end
|
591
551
|
end
|