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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +251 -16
- data/LICENSE +1 -1
- data/README.md +35 -51
- data/bin/pry +3 -11
- data/lib/pry/basic_object.rb +6 -0
- data/lib/pry/cli.rb +50 -52
- data/lib/pry/code/code_file.rb +13 -6
- data/lib/pry/code/code_range.rb +3 -3
- data/lib/pry/code/loc.rb +14 -8
- data/lib/pry/code.rb +12 -5
- data/lib/pry/code_object.rb +27 -4
- data/lib/pry/color_printer.rb +20 -10
- data/lib/pry/command.rb +76 -45
- data/lib/pry/command_set.rb +17 -45
- data/lib/pry/commands/amend_line.rb +3 -4
- data/lib/pry/commands/bang.rb +1 -1
- data/lib/pry/commands/cat/exception_formatter.rb +10 -8
- data/lib/pry/commands/cat/file_formatter.rb +7 -3
- data/lib/pry/commands/cat/input_expression_formatter.rb +1 -1
- data/lib/pry/commands/cat.rb +7 -6
- data/lib/pry/commands/change_prompt.rb +29 -9
- data/lib/pry/commands/clear_screen.rb +14 -0
- data/lib/pry/commands/code_collector.rb +25 -23
- data/lib/pry/commands/easter_eggs.rb +12 -12
- data/lib/pry/commands/edit/file_and_line_locator.rb +1 -1
- data/lib/pry/commands/edit.rb +15 -10
- data/lib/pry/commands/exit.rb +2 -1
- data/lib/pry/commands/find_method.rb +12 -14
- data/lib/pry/commands/gem_cd.rb +1 -1
- data/lib/pry/commands/gem_install.rb +2 -2
- data/lib/pry/commands/gem_list.rb +2 -2
- data/lib/pry/commands/gem_open.rb +2 -2
- data/lib/pry/commands/gem_readme.rb +25 -0
- data/lib/pry/commands/gem_search.rb +40 -0
- data/lib/pry/commands/gem_stats.rb +83 -0
- data/lib/pry/commands/gist.rb +7 -6
- data/lib/pry/commands/help.rb +3 -3
- data/lib/pry/commands/hist.rb +11 -10
- data/lib/pry/commands/import_set.rb +2 -1
- data/lib/pry/commands/install_command.rb +7 -6
- data/lib/pry/commands/jump_to.rb +7 -7
- data/lib/pry/commands/list_inspectors.rb +2 -2
- data/lib/pry/commands/ls/constants.rb +14 -3
- data/lib/pry/commands/ls/formatter.rb +4 -2
- data/lib/pry/commands/ls/globals.rb +0 -2
- data/lib/pry/commands/ls/grep.rb +0 -2
- data/lib/pry/commands/ls/instance_vars.rb +0 -1
- data/lib/pry/commands/ls/jruby_hacks.rb +2 -2
- data/lib/pry/commands/ls/local_names.rb +0 -2
- data/lib/pry/commands/ls/local_vars.rb +0 -2
- data/lib/pry/commands/ls/ls_entity.rb +0 -1
- data/lib/pry/commands/ls/methods.rb +0 -3
- data/lib/pry/commands/ls/methods_helper.rb +1 -1
- data/lib/pry/commands/ls/self_methods.rb +2 -1
- data/lib/pry/commands/ls.rb +30 -31
- data/lib/pry/commands/play.rb +3 -4
- data/lib/pry/commands/pry_backtrace.rb +1 -1
- data/lib/pry/commands/raise_up.rb +2 -1
- data/lib/pry/commands/reload_code.rb +2 -2
- data/lib/pry/commands/ri.rb +9 -4
- data/lib/pry/commands/shell_command.rb +36 -9
- data/lib/pry/commands/shell_mode.rb +6 -6
- data/lib/pry/commands/show_doc.rb +5 -7
- data/lib/pry/commands/show_info.rb +41 -20
- data/lib/pry/commands/show_source.rb +5 -2
- data/lib/pry/commands/stat.rb +1 -1
- data/lib/pry/commands/watch_expression/expression.rb +1 -1
- data/lib/pry/commands/watch_expression.rb +9 -7
- data/lib/pry/commands/whereami.rb +16 -9
- data/lib/pry/commands/wtf.rb +15 -2
- data/lib/pry/config/behavior.rb +230 -114
- data/lib/pry/config/convenience.rb +24 -21
- data/lib/pry/config/default.rb +151 -153
- data/lib/pry/config/memoization.rb +48 -0
- data/lib/pry/config.rb +30 -19
- data/lib/pry/core_extensions.rb +15 -4
- data/lib/pry/editor.rb +5 -12
- data/lib/pry/exceptions.rb +1 -3
- data/lib/pry/forwardable.rb +23 -0
- data/lib/pry/helpers/base_helpers.rb +197 -110
- data/lib/pry/helpers/command_helpers.rb +5 -4
- data/lib/pry/helpers/documentation_helpers.rb +3 -2
- data/lib/pry/helpers/options_helpers.rb +6 -6
- data/lib/pry/helpers/platform.rb +58 -0
- data/lib/pry/helpers/table.rb +20 -15
- data/lib/pry/helpers/text.rb +82 -74
- data/lib/pry/helpers.rb +1 -0
- data/lib/pry/history.rb +44 -10
- data/lib/pry/hooks.rb +50 -109
- data/lib/pry/indent.rb +21 -19
- data/lib/pry/input_completer.rb +146 -123
- data/lib/pry/input_lock.rb +0 -2
- data/lib/pry/last_exception.rb +2 -2
- data/lib/pry/method/disowned.rb +3 -1
- data/lib/pry/method/patcher.rb +2 -5
- data/lib/pry/method/weird_method_locator.rb +21 -11
- data/lib/pry/method.rb +44 -38
- data/lib/pry/object_path.rb +5 -4
- data/lib/pry/output.rb +37 -37
- data/lib/pry/pager.rb +195 -181
- data/lib/pry/platform.rb +91 -0
- data/lib/pry/plugins.rb +27 -8
- data/lib/pry/prompt.rb +144 -25
- data/lib/pry/pry_class.rb +83 -33
- data/lib/pry/pry_instance.rb +94 -59
- data/lib/pry/repl.rb +70 -11
- data/lib/pry/repl_file_loader.rb +2 -3
- data/lib/pry/ring.rb +84 -0
- data/lib/pry/rubygem.rb +9 -7
- data/lib/pry/slop/LICENSE +20 -0
- data/lib/pry/slop/commands.rb +195 -0
- data/lib/pry/slop/option.rb +206 -0
- data/lib/pry/slop.rb +661 -0
- data/lib/pry/terminal.rb +18 -6
- data/lib/pry/testable/evalable.rb +15 -0
- data/lib/pry/testable/mockable.rb +14 -0
- data/lib/pry/testable/pry_tester.rb +73 -0
- data/lib/pry/testable/utility.rb +26 -0
- data/lib/pry/testable/variables.rb +46 -0
- data/lib/pry/testable.rb +70 -0
- data/lib/pry/version.rb +1 -1
- data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +9 -14
- data/lib/pry/wrapped_module.rb +22 -21
- data/lib/pry.rb +21 -50
- metadata +35 -46
- data/lib/pry/commands/list_prompts.rb +0 -35
- data/lib/pry/commands/simple_prompt.rb +0 -22
- data/lib/pry/history_array.rb +0 -121
- data/lib/pry/rbx_path.rb +0 -22
- data/lib/pry/test/helper.rb +0 -170
@@ -0,0 +1,14 @@
|
|
1
|
+
class Pry::Command::ClearScreen < Pry::ClassCommand
|
2
|
+
match 'clear-screen'
|
3
|
+
group 'Input and Output'
|
4
|
+
description 'Clear the contents of the screen/window Pry is running in.'
|
5
|
+
|
6
|
+
def process
|
7
|
+
if Helpers::Platform.windows?
|
8
|
+
_pry_.config.system.call(_pry_.output, 'cls', _pry_)
|
9
|
+
else
|
10
|
+
_pry_.config.system.call(_pry_.output, 'clear', _pry_)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
Pry::Commands.add_command(self)
|
14
|
+
end
|
@@ -29,17 +29,17 @@ class Pry
|
|
29
29
|
@output_result_ranges = []
|
30
30
|
|
31
31
|
opt.on :l, :lines, "Restrict to a subset of lines. Takes a line number or range",
|
32
|
-
:
|
32
|
+
optional_argument: true, as: Range, default: 1..-1
|
33
33
|
opt.on :o, :out, "Select lines from Pry's output result history. Takes an index or range",
|
34
|
-
:
|
34
|
+
optional_argument: true, as: Range, default: -5..-1 do |r|
|
35
35
|
output_result_ranges << (r || (-5..-1))
|
36
36
|
end
|
37
37
|
opt.on :i, :in, "Select lines from Pry's input expression history. Takes an index or range",
|
38
|
-
:
|
38
|
+
optional_argument: true, as: Range, default: -5..-1 do |r|
|
39
39
|
input_expression_ranges << (r || (-5..-1))
|
40
40
|
end
|
41
41
|
opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors",
|
42
|
-
:
|
42
|
+
as: :count
|
43
43
|
opt.on :d, :doc, "Select lines from the code object's documentation"
|
44
44
|
end
|
45
45
|
|
@@ -51,28 +51,30 @@ class Pry
|
|
51
51
|
#
|
52
52
|
# @return [String]
|
53
53
|
def content
|
54
|
-
|
55
|
-
|
54
|
+
@content ||=
|
55
|
+
begin
|
56
|
+
raise CommandError, "Only one of --out, --in, --doc and CODE_OBJECT may be specified." if bad_option_combination?
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
58
|
+
content = case
|
59
|
+
when opts.present?(:o)
|
60
|
+
pry_output_content
|
61
|
+
when opts.present?(:i)
|
62
|
+
pry_input_content
|
63
|
+
when opts.present?(:d)
|
64
|
+
code_object_doc
|
65
|
+
else
|
66
|
+
code_object_source_or_file
|
67
|
+
end
|
67
68
|
|
68
|
-
|
69
|
+
restrict_to_lines(content, line_range)
|
70
|
+
end
|
69
71
|
end
|
70
72
|
|
71
73
|
# The code object
|
72
74
|
#
|
73
75
|
# @return [Pry::WrappedModule, Pry::Method, Pry::Command]
|
74
76
|
def code_object
|
75
|
-
Pry::CodeObject.lookup(obj_name, _pry_,
|
77
|
+
Pry::CodeObject.lookup(obj_name, _pry_, super: opts[:super])
|
76
78
|
end
|
77
79
|
|
78
80
|
# Given a string and a range, return the `range` lines of that
|
@@ -85,22 +87,22 @@ class Pry
|
|
85
87
|
Array(content.lines.to_a[range]).join
|
86
88
|
end
|
87
89
|
|
88
|
-
# The selected `_pry_.
|
90
|
+
# The selected `_pry_.output_ring` as a string, as specified by
|
89
91
|
# the `-o` switch.
|
90
92
|
#
|
91
93
|
# @return [String]
|
92
94
|
def pry_output_content
|
93
|
-
pry_array_content_as_string(_pry_.
|
95
|
+
pry_array_content_as_string(_pry_.output_ring, self.class.output_result_ranges) do |v|
|
94
96
|
_pry_.config.gist.inspecter.call(v)
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
98
|
-
# The selected `_pry_.
|
100
|
+
# The selected `_pry_.input_ring` as a string, as specified by
|
99
101
|
# the `-i` switch.
|
100
102
|
#
|
101
103
|
# @return [String]
|
102
104
|
def pry_input_content
|
103
|
-
pry_array_content_as_string(_pry_.
|
105
|
+
pry_array_content_as_string(_pry_.input_ring, self.class.input_expression_ranges) { |v| v }
|
104
106
|
end
|
105
107
|
|
106
108
|
# The line range passed to `--lines`, converted to a 0-indexed range.
|
@@ -141,7 +143,7 @@ class Pry
|
|
141
143
|
end
|
142
144
|
|
143
145
|
def file_content
|
144
|
-
if File.
|
146
|
+
if File.exist?(obj_name)
|
145
147
|
# Set the file accessor.
|
146
148
|
self.file = obj_name
|
147
149
|
File.read(obj_name)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Pry
|
2
2
|
Pry::Commands.instance_eval do
|
3
|
-
command "nyan-cat", "", :
|
3
|
+
command "nyan-cat", "", requires_gem: ["nyancat"] do
|
4
4
|
run ".nyancat"
|
5
5
|
end
|
6
6
|
|
@@ -10,17 +10,17 @@ class Pry
|
|
10
10
|
end
|
11
11
|
|
12
12
|
command "get-naked", "" do
|
13
|
-
|
13
|
+
txt = %{
|
14
14
|
--
|
15
15
|
We dont have to take our clothes off to have a good time.
|
16
16
|
We could dance & party all night And drink some cherry wine.
|
17
17
|
-- Jermaine Stewart }
|
18
|
-
output.puts
|
19
|
-
|
18
|
+
output.puts txt
|
19
|
+
txt
|
20
20
|
end
|
21
21
|
|
22
22
|
command "east-coker", "" do
|
23
|
-
|
23
|
+
txt = %{
|
24
24
|
--
|
25
25
|
Now the light falls
|
26
26
|
Across the open field, leaving the deep lane
|
@@ -34,12 +34,12 @@ class Pry
|
|
34
34
|
Wait for the early owl.
|
35
35
|
-- T.S Eliot
|
36
36
|
}
|
37
|
-
output.puts
|
38
|
-
|
37
|
+
output.puts txt
|
38
|
+
txt
|
39
39
|
end
|
40
40
|
|
41
41
|
command "cohen-poem", "" do
|
42
|
-
|
42
|
+
txt = %{
|
43
43
|
--
|
44
44
|
When this American woman,
|
45
45
|
whose thighs are bound in casual red cloth,
|
@@ -57,8 +57,8 @@ class Pry
|
|
57
57
|
they are lost for hours.
|
58
58
|
-- Leonard Cohen
|
59
59
|
}
|
60
|
-
output.puts
|
61
|
-
|
60
|
+
output.puts txt
|
61
|
+
txt
|
62
62
|
end
|
63
63
|
|
64
64
|
command "pessoa-poem", "" do
|
@@ -86,7 +86,7 @@ TEXT
|
|
86
86
|
prev_color = _pry_.config.color
|
87
87
|
_pry_.config.color = true
|
88
88
|
|
89
|
-
picture = unindent <<-'EOS'.gsub(/[[:alpha:]!]/) { |s|
|
89
|
+
picture = unindent <<-'EOS'.gsub(/[[:alpha:]!]/) { |s| red(s) }
|
90
90
|
____ _______________________
|
91
91
|
/ \ | A W G |
|
92
92
|
/ O O \ | N I O N ! |
|
@@ -95,7 +95,7 @@ TEXT
|
|
95
95
|
\____/ \________________________|
|
96
96
|
EOS
|
97
97
|
|
98
|
-
if windows_ansi?
|
98
|
+
if Helpers::Platform.windows_ansi?
|
99
99
|
move_up = proc { |n| "\e[#{n}F" }
|
100
100
|
else
|
101
101
|
move_up = proc { |n| "\e[#{n}A\e[0G" }
|
@@ -7,7 +7,7 @@ class Pry
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def from_code_object(code_object, filename_argument)
|
10
|
-
if File.
|
10
|
+
if File.exist?(code_object.source_file.to_s)
|
11
11
|
[code_object.source_file, code_object.source_line]
|
12
12
|
else
|
13
13
|
raise CommandError, "Cannot find a file for #{filename_argument}!"
|
data/lib/pry/commands/edit.rb
CHANGED
@@ -24,12 +24,12 @@ class Pry
|
|
24
24
|
|
25
25
|
def options(opt)
|
26
26
|
opt.on :e, :ex, "Open the file that raised the most recent exception (_ex_.file)",
|
27
|
-
:
|
27
|
+
optional_argument: true, as: Integer
|
28
28
|
opt.on :i, :in, "Open a temporary file containing the Nth input expression. N may be a range",
|
29
|
-
:
|
29
|
+
optional_argument: true, as: Range, default: -1..-1
|
30
30
|
opt.on :t, :temp, "Open an empty temporary file"
|
31
31
|
opt.on :l, :line, "Jump to this line in the opened file",
|
32
|
-
:
|
32
|
+
argument: true, as: Integer
|
33
33
|
opt.on :n, :"no-reload", "Don't automatically reload the edited file"
|
34
34
|
opt.on :c, :current, "Open the current __FILE__ and at __LINE__ (as returned by `whereami`)"
|
35
35
|
opt.on :r, :reload, "Reload the edited code immediately (default for ruby files)"
|
@@ -46,7 +46,7 @@ class Pry
|
|
46
46
|
# code defined in pry, eval'd within pry.
|
47
47
|
repl_edit
|
48
48
|
elsif runtime_patch?
|
49
|
-
# patch code without persisting changes
|
49
|
+
# patch code without persisting changes, implies future changes are patches
|
50
50
|
apply_runtime_patch
|
51
51
|
else
|
52
52
|
# code stored in actual files, eval'd at top-level
|
@@ -65,6 +65,7 @@ class Pry
|
|
65
65
|
silence_warnings do
|
66
66
|
eval_string.replace content
|
67
67
|
end
|
68
|
+
Pry.history.push(content)
|
68
69
|
end
|
69
70
|
|
70
71
|
def file_based_exception?
|
@@ -72,7 +73,7 @@ class Pry
|
|
72
73
|
end
|
73
74
|
|
74
75
|
def runtime_patch?
|
75
|
-
!file_based_exception? && (opts.present?(:patch) || pry_method?(code_object))
|
76
|
+
!file_based_exception? && (opts.present?(:patch) || previously_patched?(code_object) || pry_method?(code_object))
|
76
77
|
end
|
77
78
|
|
78
79
|
def apply_runtime_patch
|
@@ -140,6 +141,10 @@ class Pry
|
|
140
141
|
code_object.pry_method?
|
141
142
|
end
|
142
143
|
|
144
|
+
def previously_patched?(code_object)
|
145
|
+
code_object.is_a?(Pry::Method) && Pry::Method::Patcher.code_for(code_object.source_location.first)
|
146
|
+
end
|
147
|
+
|
143
148
|
def patch_exception?
|
144
149
|
opts.present?(:ex) && opts.present?(:patch)
|
145
150
|
end
|
@@ -152,9 +157,9 @@ class Pry
|
|
152
157
|
def input_expression
|
153
158
|
case opts[:i]
|
154
159
|
when Range
|
155
|
-
(_pry_.
|
156
|
-
when
|
157
|
-
_pry_.
|
160
|
+
(_pry_.input_ring[opts[:i]] || []).join
|
161
|
+
when Integer
|
162
|
+
_pry_.input_ring[opts[:i]] || ""
|
158
163
|
else
|
159
164
|
raise Pry::CommandError, "Not a valid range: #{opts[:i]}"
|
160
165
|
end
|
@@ -168,7 +173,7 @@ class Pry
|
|
168
173
|
opts.present?(:'no-reload') || _pry_.config.disable_auto_reload
|
169
174
|
end
|
170
175
|
|
171
|
-
def reload?(file_name="")
|
176
|
+
def reload?(file_name = "")
|
172
177
|
(reloadable? || file_name.end_with?(".rb")) && !never_reload?
|
173
178
|
end
|
174
179
|
|
@@ -181,7 +186,7 @@ class Pry
|
|
181
186
|
when eval_string.strip != ""
|
182
187
|
eval_string
|
183
188
|
else
|
184
|
-
_pry_.
|
189
|
+
_pry_.input_ring.to_a.reverse_each.find { |x| x && x.strip != "" } || ""
|
185
190
|
end
|
186
191
|
end
|
187
192
|
|
data/lib/pry/commands/exit.rb
CHANGED
@@ -3,7 +3,7 @@ class Pry
|
|
3
3
|
match 'exit'
|
4
4
|
group 'Navigating Pry'
|
5
5
|
description 'Pop the previous binding.'
|
6
|
-
command_options :
|
6
|
+
command_options keep_retval: true
|
7
7
|
|
8
8
|
banner <<-'BANNER'
|
9
9
|
Usage: exit [OPTIONS] [--help]
|
@@ -33,6 +33,7 @@ class Pry
|
|
33
33
|
|
34
34
|
# return a user-specified value if given otherwise return the object
|
35
35
|
return target.eval(arg_string) unless arg_string.empty?
|
36
|
+
|
36
37
|
popped_object
|
37
38
|
end
|
38
39
|
end
|
@@ -5,7 +5,7 @@ class Pry
|
|
5
5
|
match 'find-method'
|
6
6
|
group 'Context'
|
7
7
|
description 'Recursively search for a method within a Class/Module or the current namespace.'
|
8
|
-
command_options :
|
8
|
+
command_options shellwords: false
|
9
9
|
|
10
10
|
banner <<-'BANNER'
|
11
11
|
Usage: find-method [-n|-c] METHOD [NAMESPACE]
|
@@ -20,7 +20,7 @@ class Pry
|
|
20
20
|
find-method re Pry
|
21
21
|
|
22
22
|
# Find all methods that contain the code:
|
23
|
-
# output.puts inside the Pry
|
23
|
+
# output.puts inside the Pry namespace.
|
24
24
|
find-method -c 'output.puts' Pry
|
25
25
|
BANNER
|
26
26
|
|
@@ -31,14 +31,10 @@ class Pry
|
|
31
31
|
|
32
32
|
def process
|
33
33
|
return if args.size < 1
|
34
|
-
klass = search_class
|
35
34
|
|
36
|
-
|
37
|
-
content_search(klass)
|
38
|
-
else
|
39
|
-
name_search(klass)
|
40
|
-
end
|
35
|
+
klass = search_class
|
41
36
|
|
37
|
+
matches = opts.content? ? content_search(klass) : name_search(klass)
|
42
38
|
show_search_results(matches)
|
43
39
|
end
|
44
40
|
|
@@ -54,7 +50,7 @@ class Pry
|
|
54
50
|
# @param [Array] matches
|
55
51
|
def show_search_results(matches)
|
56
52
|
if matches.empty?
|
57
|
-
output.puts
|
53
|
+
output.puts bold("No Methods Matched")
|
58
54
|
else
|
59
55
|
print_matches(matches)
|
60
56
|
end
|
@@ -79,7 +75,7 @@ class Pry
|
|
79
75
|
# @param [Array<Method>] matches
|
80
76
|
def print_matches(matches)
|
81
77
|
grouped = matches.group_by(&:owner)
|
82
|
-
order = grouped.keys.sort_by{ |x| x.name || x.to_s }
|
78
|
+
order = grouped.keys.sort_by { |x| x.name || x.to_s }
|
83
79
|
|
84
80
|
order.each do |klass|
|
85
81
|
print_matches_for_class(klass, grouped)
|
@@ -88,7 +84,7 @@ class Pry
|
|
88
84
|
|
89
85
|
# Print matched methods for a class
|
90
86
|
def print_matches_for_class(klass, grouped)
|
91
|
-
output.puts
|
87
|
+
output.puts bold(klass.name)
|
92
88
|
grouped[klass].each do |method|
|
93
89
|
header = method.name_with_owner
|
94
90
|
output.puts header + additional_info(header, method)
|
@@ -106,7 +102,7 @@ class Pry
|
|
106
102
|
end
|
107
103
|
|
108
104
|
def matched_method_lines(header, method)
|
109
|
-
method.source.split(/\n/).select {|x| x =~ pattern }.join("\n#{' ' * header.length}")
|
105
|
+
method.source.split(/\n/).select { |x| x =~ pattern }.join("\n#{' ' * header.length}")
|
110
106
|
end
|
111
107
|
|
112
108
|
# Run the given block against every constant in the provided namespace.
|
@@ -115,7 +111,7 @@ class Pry
|
|
115
111
|
# @param [Hash<Module,Boolean>] done The namespaces we've already visited (private)
|
116
112
|
# @yieldparam klass Each class/module in the namespace.
|
117
113
|
#
|
118
|
-
def recurse_namespace(klass, done={}, &block)
|
114
|
+
def recurse_namespace(klass, done = {}, &block)
|
119
115
|
return if !(Module === klass) || done[klass]
|
120
116
|
|
121
117
|
done[klass] = true
|
@@ -124,6 +120,7 @@ class Pry
|
|
124
120
|
|
125
121
|
klass.constants.each do |name|
|
126
122
|
next if klass.autoload?(name)
|
123
|
+
|
127
124
|
begin
|
128
125
|
const = klass.const_get(name)
|
129
126
|
rescue RescuableException
|
@@ -145,12 +142,13 @@ class Pry
|
|
145
142
|
# @return [Array<Method>]
|
146
143
|
#
|
147
144
|
def search_all_methods(namespace)
|
148
|
-
done = Hash.new{ |h,k| h[k] = {} }
|
145
|
+
done = Hash.new { |h,k| h[k] = {} }
|
149
146
|
matches = []
|
150
147
|
|
151
148
|
recurse_namespace(namespace) do |klass|
|
152
149
|
(Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).each do |method|
|
153
150
|
next if done[method.owner][method.name]
|
151
|
+
|
154
152
|
done[method.owner][method.name] = true
|
155
153
|
|
156
154
|
matches << method if yield method
|
data/lib/pry/commands/gem_cd.rb
CHANGED
@@ -3,7 +3,7 @@ class Pry
|
|
3
3
|
match 'gem-install'
|
4
4
|
group 'Gems'
|
5
5
|
description 'Install a gem and refresh the gem cache.'
|
6
|
-
command_options :
|
6
|
+
command_options argument_required: true
|
7
7
|
|
8
8
|
banner <<-'BANNER'
|
9
9
|
Usage: gem-install GEM_NAME
|
@@ -20,7 +20,7 @@ class Pry
|
|
20
20
|
|
21
21
|
def process(gem)
|
22
22
|
Rubygem.install(gem)
|
23
|
-
output.puts "Gem `#{
|
23
|
+
output.puts "Gem `#{ green(gem) }` installed."
|
24
24
|
require gem
|
25
25
|
rescue LoadError
|
26
26
|
require_path = gem.split('-').join('/')
|
@@ -21,10 +21,10 @@ class Pry
|
|
21
21
|
end
|
22
22
|
|
23
23
|
versions = specs.each_with_index.map do |spec, index|
|
24
|
-
index == 0 ?
|
24
|
+
index == 0 ? bright_green(spec.version.to_s) : green(spec.version.to_s)
|
25
25
|
end
|
26
26
|
|
27
|
-
output.puts "#{
|
27
|
+
output.puts "#{default gem} (#{versions.join ', '})"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -3,7 +3,7 @@ class Pry
|
|
3
3
|
match 'gem-open'
|
4
4
|
group 'Gems'
|
5
5
|
description 'Opens the working directory of the gem in your editor.'
|
6
|
-
command_options :
|
6
|
+
command_options argument_required: true
|
7
7
|
|
8
8
|
banner <<-'BANNER'
|
9
9
|
Usage: gem-open GEM_NAME
|
@@ -16,7 +16,7 @@ class Pry
|
|
16
16
|
|
17
17
|
def process(gem)
|
18
18
|
Dir.chdir(Rubygem.spec(gem).full_gem_path) do
|
19
|
-
Pry::Editor.invoke_editor(".", 0, false)
|
19
|
+
Pry::Editor.new(_pry_).invoke_editor(".", 0, false)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Pry::Command::GemReadme < Pry::ClassCommand
|
2
|
+
match 'gem-readme'
|
3
|
+
description 'Show the readme bundled with a rubygem'
|
4
|
+
group 'Gems'
|
5
|
+
command_options argument_required: true
|
6
|
+
banner <<-BANNER
|
7
|
+
gem-readme gem
|
8
|
+
Show the readme bundled with a rubygem
|
9
|
+
BANNER
|
10
|
+
|
11
|
+
def process(name)
|
12
|
+
spec = Gem::Specification.find_by_name(name)
|
13
|
+
glob = File.join(spec.full_gem_path, 'README*')
|
14
|
+
readme = Dir[glob][0]
|
15
|
+
if File.exist?(readme.to_s)
|
16
|
+
_pry_.pager.page File.read(readme)
|
17
|
+
else
|
18
|
+
raise Pry::CommandError, "Gem '#{name}' doesn't appear to have a README"
|
19
|
+
end
|
20
|
+
rescue Gem::LoadError
|
21
|
+
raise Pry::CommandError, "Gem '#{name}' wasn't found. Are you sure it is installed?"
|
22
|
+
end
|
23
|
+
|
24
|
+
Pry::Commands.add_command(self)
|
25
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Pry::Command::GemSearch < Pry::ClassCommand
|
2
|
+
match 'gem-search'
|
3
|
+
description 'Search for a gem with the rubygems.org JSON API'
|
4
|
+
group 'Gems'
|
5
|
+
command_options argument_required: true
|
6
|
+
banner <<-BANNER
|
7
|
+
gem-search [options] gem
|
8
|
+
Search for a gem with the rubygems.org HTTP API
|
9
|
+
BANNER
|
10
|
+
|
11
|
+
API_ENDPOINT = 'https://rubygems.org/api/v1/search.json'
|
12
|
+
|
13
|
+
def setup
|
14
|
+
require 'json' unless defined?(JSON)
|
15
|
+
require 'net/http' unless defined?(Net::HTTP)
|
16
|
+
end
|
17
|
+
|
18
|
+
def options(opt)
|
19
|
+
opt.on :l, :limit, 'Limit the number of results (max: 30)',
|
20
|
+
default: 10,
|
21
|
+
as: Integer,
|
22
|
+
argument: true
|
23
|
+
end
|
24
|
+
|
25
|
+
def process(str)
|
26
|
+
uri = URI.parse(API_ENDPOINT)
|
27
|
+
uri.query = URI.encode_www_form(query: str)
|
28
|
+
gems = JSON.load Net::HTTP.get(uri)
|
29
|
+
_pry_.pager.page list_as_string(gems, opts[:limit])
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def list_as_string(gems, limit = 10)
|
34
|
+
gems[0..limit - 1].map do |gem|
|
35
|
+
name, version, info = gem.values_at 'name', 'version', 'info'
|
36
|
+
"#{bold(name)} #{bold('v' + version)} \n#{info}\n\n"
|
37
|
+
end.join
|
38
|
+
end
|
39
|
+
Pry::Commands.add_command(self)
|
40
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
class Pry::Command::GemStat < Pry::ClassCommand
|
2
|
+
require 'json'
|
3
|
+
require 'net/http'
|
4
|
+
STAT_HOST = "rubygems.org"
|
5
|
+
STAT_PORT = 443
|
6
|
+
STAT_PATH = "/api/v1/gems/%s.json"
|
7
|
+
FAIL_WHALE = <<-FAILWHALE
|
8
|
+
W W W
|
9
|
+
W W W W
|
10
|
+
'. W
|
11
|
+
.-""-._ \ \.--|
|
12
|
+
/ "-..__) .-'
|
13
|
+
| _ /
|
14
|
+
\'-.__, .__.,'
|
15
|
+
`'----'._\--'
|
16
|
+
VVVVVVVVVVVVVVVVVVVVV
|
17
|
+
FAILWHALE
|
18
|
+
|
19
|
+
match 'gem-stat'
|
20
|
+
description 'Show the statistics of a gem (requires internet connection)'
|
21
|
+
group 'Gems'
|
22
|
+
command_options argument_required: true
|
23
|
+
banner <<-BANNER
|
24
|
+
gem-stats name
|
25
|
+
|
26
|
+
Show the statistics of a gem.
|
27
|
+
Requires an internet connection.
|
28
|
+
BANNER
|
29
|
+
|
30
|
+
def process(name)
|
31
|
+
client = Net::HTTP.start STAT_HOST, STAT_PORT, use_ssl: true
|
32
|
+
res = client.get STAT_PATH % URI.encode_www_form_component(name)
|
33
|
+
case res
|
34
|
+
when Net::HTTPOK
|
35
|
+
_pry_.pager.page format_gem(JSON.parse(res.body))
|
36
|
+
when Net::HTTPServiceUnavailable
|
37
|
+
_pry_.pager.page <<-FAILURE
|
38
|
+
#{bright_blue(FAIL_WHALE)}
|
39
|
+
#{bright_red('Ruby On Rails')}
|
40
|
+
#{bright_red('Net::HTTPServiceUnavailable')}
|
41
|
+
FAILURE
|
42
|
+
else
|
43
|
+
raise Pry::CommandError, "Bad response (#{res.class})"
|
44
|
+
end
|
45
|
+
ensure
|
46
|
+
client.finish if client
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def format_gem(h)
|
51
|
+
h = Pry::Config.from_hash(h, nil)
|
52
|
+
format_str = unindent <<-FORMAT
|
53
|
+
%{name} %{version}
|
54
|
+
--
|
55
|
+
Total Downloads : %{downloads}
|
56
|
+
Version Downloads : %{version_downloads}
|
57
|
+
|
58
|
+
#{red('Dependencies')} (runtime)
|
59
|
+
--
|
60
|
+
%{rdependencies}
|
61
|
+
|
62
|
+
#{red('Dependencies')} (development)
|
63
|
+
%{ddependencies}
|
64
|
+
FORMAT
|
65
|
+
format_str % {name: green(h.name),
|
66
|
+
version: bold("v#{h.version}"),
|
67
|
+
downloads: h.downloads,
|
68
|
+
version_downloads: h.version_downloads,
|
69
|
+
rdependencies: format_dependencies(h.dependencies.runtime),
|
70
|
+
ddependencies: format_dependencies(h.dependencies.development)}
|
71
|
+
end
|
72
|
+
|
73
|
+
def format_dependencies(rdeps)
|
74
|
+
return bold('None') if rdeps.empty?
|
75
|
+
|
76
|
+
with_line_numbers(
|
77
|
+
rdeps.map { |h| "#{h['name']} (#{h['requirements']})" }.join("\n"),
|
78
|
+
1,
|
79
|
+
:bold
|
80
|
+
)
|
81
|
+
end
|
82
|
+
Pry::Commands.add_command(self)
|
83
|
+
end
|
data/lib/pry/commands/gist.rb
CHANGED
@@ -3,7 +3,7 @@ class Pry
|
|
3
3
|
match 'gist'
|
4
4
|
group 'Misc'
|
5
5
|
description 'Upload code, docs, history to https://gist.github.com/.'
|
6
|
-
command_options :
|
6
|
+
command_options requires_gem: "gist"
|
7
7
|
|
8
8
|
banner <<-'BANNER'
|
9
9
|
Usage: gist [OPTIONS] [--help]
|
@@ -22,12 +22,13 @@ class Pry
|
|
22
22
|
def options(opt)
|
23
23
|
CodeCollector.inject_options(opt)
|
24
24
|
opt.on :login, "Authenticate the gist gem with GitHub"
|
25
|
-
opt.on :p, :public, "Create a public gist (default: false)", :
|
26
|
-
opt.on :clip, "Copy the selected content to clipboard instead, do NOT gist it", :
|
25
|
+
opt.on :p, :public, "Create a public gist (default: false)", default: false
|
26
|
+
opt.on :clip, "Copy the selected content to clipboard instead, do NOT gist it", default: false
|
27
27
|
end
|
28
28
|
|
29
29
|
def process
|
30
30
|
return ::Gist.login! if opts.present?(:login)
|
31
|
+
|
31
32
|
cc = CodeCollector.new(args, opts, _pry_)
|
32
33
|
|
33
34
|
if cc.content =~ /\A\s*\z/
|
@@ -52,13 +53,13 @@ class Pry
|
|
52
53
|
def input_content
|
53
54
|
content = ""
|
54
55
|
CodeCollector.input_expression_ranges.each do |range|
|
55
|
-
input_expressions = _pry_.
|
56
|
+
input_expressions = _pry_.input_ring[range] || []
|
56
57
|
Array(input_expressions).each_with_index do |code, index|
|
57
58
|
corrected_index = index + range.first
|
58
59
|
if code && code != ""
|
59
60
|
content << code
|
60
61
|
if code !~ /;\Z/
|
61
|
-
content << "#{comment_expression_result_for_gist(_pry_.config.gist.inspecter.call(_pry_.
|
62
|
+
content << "#{comment_expression_result_for_gist(_pry_.config.gist.inspecter.call(_pry_.output_ring[corrected_index]))}"
|
62
63
|
end
|
63
64
|
end
|
64
65
|
end
|
@@ -81,7 +82,7 @@ class Pry
|
|
81
82
|
end
|
82
83
|
|
83
84
|
def gist_content(content, filename)
|
84
|
-
response = ::Gist.gist(content, :
|
85
|
+
response = ::Gist.gist(content, filename: filename || "pry_gist.rb", public: !!opts[:p])
|
85
86
|
if response
|
86
87
|
url = response['html_url']
|
87
88
|
message = "Gist created at URL #{url}"
|