pry 0.9.8pre5-i386-mswin32 → 0.9.8pre6-i386-mswin32
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 +36 -0
- data/Rakefile +2 -2
- data/lib/pry.rb +3 -2
- data/lib/pry/code.rb +344 -0
- data/lib/pry/command.rb +22 -21
- data/lib/pry/command_set.rb +28 -15
- data/lib/pry/commands.rb +0 -1
- data/lib/pry/config.rb +2 -2
- data/lib/pry/default_commands/context.rb +100 -86
- data/lib/pry/default_commands/documentation.rb +20 -1
- data/lib/pry/default_commands/gems.rb +65 -37
- data/lib/pry/default_commands/input.rb +107 -154
- data/lib/pry/default_commands/introspection.rb +154 -102
- data/lib/pry/default_commands/shell.rb +89 -91
- data/lib/pry/helpers/command_helpers.rb +14 -76
- data/lib/pry/hooks.rb +12 -1
- data/lib/pry/pry_class.rb +3 -3
- data/lib/pry/pry_instance.rb +40 -15
- data/lib/pry/version.rb +1 -1
- data/pry.gemspec +16 -16
- data/test/helper.rb +9 -23
- data/test/test_code.rb +201 -0
- data/test/test_command.rb +10 -0
- data/test/test_default_commands/test_input.rb +11 -11
- data/test/test_default_commands/test_introspection.rb +5 -5
- data/test/test_default_commands/test_shell.rb +10 -10
- data/test/test_hooks.rb +36 -0
- metadata +19 -17
- data/lib/pry/extended_commands/user_command_api.rb +0 -122
data/lib/pry/command_set.rb
CHANGED
@@ -331,23 +331,36 @@ class Pry
|
|
331
331
|
|
332
332
|
def define_default_commands
|
333
333
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
334
|
+
create_command "help" do |cmd|
|
335
|
+
description "Show a list of commands, or help for one command"
|
336
|
+
|
337
|
+
banner <<-BANNER
|
338
|
+
Usage: help [ COMMAND ]
|
339
|
+
|
340
|
+
With no arguments, help lists all the available commands in the current
|
341
|
+
command-set along with their description.
|
342
|
+
|
343
|
+
When given a command name as an argument, shows the help for that command.
|
344
|
+
BANNER
|
344
345
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
346
|
+
def process
|
347
|
+
if cmd = args.first
|
348
|
+
if command = find_command(cmd)
|
349
|
+
output.puts command.new.help
|
350
|
+
else
|
351
|
+
output.puts "No info for command: #{cmd}"
|
352
|
+
end
|
349
353
|
else
|
350
|
-
output.puts
|
354
|
+
output.puts
|
355
|
+
help_text = heading("Command List: ") + "\n"
|
356
|
+
|
357
|
+
help_text << commands.map do |key, command|
|
358
|
+
if command.description && !command.description.empty?
|
359
|
+
"#{command.options[:listing].to_s.ljust(18)} #{command.description}"
|
360
|
+
end
|
361
|
+
end.compact.sort.join("\n")
|
362
|
+
|
363
|
+
stagger_output(help_text)
|
351
364
|
end
|
352
365
|
end
|
353
366
|
end
|
data/lib/pry/commands.rb
CHANGED
data/lib/pry/config.rb
CHANGED
@@ -33,8 +33,8 @@ class Pry
|
|
33
33
|
attr_accessor :exception_whitelist
|
34
34
|
|
35
35
|
# @return [Fixnum] The number of lines of context to show before and after
|
36
|
-
#
|
37
|
-
attr_accessor :
|
36
|
+
# exceptions, etc.
|
37
|
+
attr_accessor :default_window_size
|
38
38
|
|
39
39
|
# Get/Set the Hash that defines Pry hooks used by default by all Pry
|
40
40
|
# instances.
|
@@ -6,42 +6,56 @@ class Pry
|
|
6
6
|
Context = Pry::CommandSet.new do
|
7
7
|
import Ls
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
9
|
+
command_class "cd" do
|
10
|
+
description "Move into a new context (object or scope). Type `cd --help` for more information."
|
11
|
+
|
12
|
+
banner <<-BANNER
|
13
|
+
Usage: cd [OPTIONS] [--help]
|
14
|
+
|
15
|
+
Move into new context (object or scope). As in unix shells use
|
16
|
+
`cd ..` to go back and `cd /` to return to Pry top-level).
|
17
|
+
Complex syntax (e.g cd ../@x/y) also supported.
|
18
|
+
|
19
|
+
e.g: `cd @x`
|
20
|
+
e.g: `cd ..
|
21
|
+
e.g: `cd /`
|
22
|
+
|
23
|
+
https://github.com/pry/pry/wiki/State-navigation#wiki-Changing_scope
|
24
|
+
BANNER
|
25
|
+
|
26
|
+
def process
|
27
|
+
path = arg_string.split(/\//)
|
28
|
+
stack = _pry_.binding_stack.dup
|
29
|
+
|
30
|
+
# special case when we only get a single "/", return to root
|
31
|
+
stack = [stack.first] if path.empty?
|
32
|
+
|
33
|
+
path.each do |context|
|
34
|
+
begin
|
35
|
+
case context.chomp
|
36
|
+
when ""
|
37
|
+
stack = [stack.first]
|
38
|
+
when "::"
|
39
|
+
stack.push(TOPLEVEL_BINDING)
|
40
|
+
when "."
|
41
|
+
next
|
42
|
+
when ".."
|
43
|
+
unless stack.size == 1
|
44
|
+
stack.pop
|
45
|
+
end
|
46
|
+
else
|
47
|
+
stack.push(Pry.binding_for(stack.last.eval(context)))
|
29
48
|
end
|
30
|
-
else
|
31
|
-
stack.push(Pry.binding_for(stack.last.eval(context)))
|
32
|
-
end
|
33
49
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
50
|
+
rescue RescuableException => e
|
51
|
+
output.puts "Bad object path: #{arg_string.chomp}. Failed trying to resolve: #{context}"
|
52
|
+
output.puts e.inspect
|
53
|
+
return
|
54
|
+
end
|
39
55
|
end
|
40
|
-
end
|
41
56
|
|
42
|
-
|
43
|
-
|
44
|
-
_pry_.binding_stack = stack
|
57
|
+
_pry_.binding_stack = stack
|
58
|
+
end
|
45
59
|
end
|
46
60
|
|
47
61
|
command "switch-to", "Start a new sub-session on a binding in the current stack (numbered by nesting)." do |selection|
|
@@ -92,21 +106,47 @@ class Pry
|
|
92
106
|
|
93
107
|
alias_command "!!@", "exit-all"
|
94
108
|
|
95
|
-
|
96
|
-
|
97
|
-
|
109
|
+
command_class "exit" do
|
110
|
+
description "Pop the previous binding (does NOT exit program). Type `exit --help` for more information. Aliases: quit"
|
111
|
+
|
112
|
+
banner <<-BANNER
|
113
|
+
Usage: exit [OPTIONS] [--help]
|
114
|
+
Aliases: quit
|
115
|
+
|
116
|
+
It can be useful to exit a context with a user-provided value. For
|
117
|
+
instance an exit value can be used to determine program flow.
|
118
|
+
|
119
|
+
e.g: `exit "pry this"`
|
120
|
+
e.g: `exit`
|
121
|
+
|
122
|
+
https://github.com/pry/pry/wiki/State-navigation#wiki-Exit_with_value
|
123
|
+
BANNER
|
124
|
+
|
125
|
+
command_options(
|
126
|
+
:keep_retval => true
|
127
|
+
)
|
128
|
+
|
129
|
+
def process
|
130
|
+
if _pry_.binding_stack.one?
|
131
|
+
# when breaking out of top-level then behave like `exit-all`
|
132
|
+
process_exit_all
|
133
|
+
else
|
134
|
+
# otherwise just pop a binding and return user supplied value
|
135
|
+
process_pop_and_return
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def process_exit_all
|
98
140
|
_pry_.binding_stack.clear
|
99
141
|
throw(:breakout, target.eval(arg_string))
|
100
|
-
|
101
|
-
|
142
|
+
end
|
143
|
+
|
144
|
+
def process_pop_and_return
|
102
145
|
popped_object = _pry_.binding_stack.pop.eval('self')
|
103
146
|
|
104
|
-
# return a user-specified value if given
|
105
|
-
|
106
|
-
|
107
|
-
else
|
108
|
-
popped_object
|
109
|
-
end
|
147
|
+
# return a user-specified value if given otherwise return the object
|
148
|
+
return target.eval(arg_string) unless arg_string.empty?
|
149
|
+
popped_object
|
110
150
|
end
|
111
151
|
end
|
112
152
|
|
@@ -124,20 +164,25 @@ class Pry
|
|
124
164
|
target.pry
|
125
165
|
end
|
126
166
|
|
127
|
-
|
128
|
-
|
129
|
-
|
167
|
+
command_class "pry-backtrace", "Show the backtrace for the Pry session." do
|
168
|
+
banner <<-BANNER
|
169
|
+
Usage: pry-backtrace [OPTIONS] [--help]
|
170
|
+
|
171
|
+
Show the backtrace for the Pry session.
|
172
|
+
|
173
|
+
e.g: pry-backtrace
|
174
|
+
BANNER
|
175
|
+
|
176
|
+
def process
|
177
|
+
output.puts "\n#{text.bold('Backtrace:')}\n--\n"
|
178
|
+
stagger_output _pry_.backtrace.join("\n")
|
179
|
+
end
|
130
180
|
end
|
131
181
|
|
132
182
|
command "whereami", "Show the code context for the session. (whereami <n> shows <n> extra lines of code around the invocation line. Default: 5)" do |num|
|
133
183
|
file = target.eval('__FILE__')
|
134
184
|
line_num = target.eval('__LINE__')
|
135
|
-
|
136
|
-
if num
|
137
|
-
i_num = num.to_i
|
138
|
-
else
|
139
|
-
i_num = 5
|
140
|
-
end
|
185
|
+
i_num = num ? num.to_i : 5
|
141
186
|
|
142
187
|
if file != Pry.eval_path && (file =~ /(\(.*\))|<.*>/ || file == "" || file == "-e")
|
143
188
|
raise CommandError, "Cannot find local context. Did you use `binding.pry`?"
|
@@ -149,40 +194,9 @@ class Pry
|
|
149
194
|
method_description = method ? " in #{method.name_with_owner}" : ""
|
150
195
|
output.puts "\n#{text.bold('From:')} #{file} @ line #{line_num}#{method_description}:\n\n"
|
151
196
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
unless File.readable?(file)
|
156
|
-
raise CommandError, "Cannot open #{file.inspect} for reading."
|
157
|
-
end
|
158
|
-
f = File.open(file)
|
159
|
-
end
|
160
|
-
|
161
|
-
# This method inspired by http://rubygems.org/gems/ir_b
|
162
|
-
begin
|
163
|
-
f.each_with_index do |line, index|
|
164
|
-
line_n = index + 1
|
165
|
-
next unless line_n > (line_num - i_num - 1)
|
166
|
-
break if line_n > (line_num + i_num)
|
167
|
-
if line_n == line_num
|
168
|
-
code =" =>#{line_n.to_s.rjust(3)}: #{line.chomp}"
|
169
|
-
if Pry.color
|
170
|
-
code = CodeRay.scan(code, :ruby).term
|
171
|
-
end
|
172
|
-
output.puts code
|
173
|
-
code
|
174
|
-
else
|
175
|
-
code = "#{line_n.to_s.rjust(6)}: #{line.chomp}"
|
176
|
-
if Pry.color
|
177
|
-
code = CodeRay.scan(code, :ruby).term
|
178
|
-
end
|
179
|
-
output.puts code
|
180
|
-
code
|
181
|
-
end
|
182
|
-
end
|
183
|
-
ensure
|
184
|
-
f.close if f.respond_to?(:close)
|
185
|
-
end
|
197
|
+
code = Pry::Code.from_file(file).around(line_num, i_num)
|
198
|
+
output.puts code.with_line_numbers.with_marker(line_num)
|
199
|
+
output.puts
|
186
200
|
end
|
187
201
|
|
188
202
|
end
|
@@ -38,7 +38,8 @@ class Pry
|
|
38
38
|
output.puts "#{text.bold("Visibility:")} #{meth.visibility}"
|
39
39
|
output.puts "#{text.bold("Signature:")} #{meth.signature}"
|
40
40
|
output.puts
|
41
|
-
|
41
|
+
|
42
|
+
render_output(doc, opts)
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
@@ -88,10 +89,12 @@ class Pry
|
|
88
89
|
e.g: gist -m my_method
|
89
90
|
e.g: gist -d my_method
|
90
91
|
e.g: gist -i 1..10
|
92
|
+
e.g: gist -c show-method
|
91
93
|
USAGE
|
92
94
|
|
93
95
|
opt.on :d, :doc, "Gist a method's documentation.", true
|
94
96
|
opt.on :m, :method, "Gist a method's source.", true
|
97
|
+
opt.on :c, :command, "Gist a command's source.", true
|
95
98
|
opt.on :f, :file, "Gist a file.", true
|
96
99
|
opt.on :p, :public, "Create a public gist (default: false)", :default => false
|
97
100
|
opt.on :l, :lines, "Only gist a subset of lines (only works with -m and -f)", :optional => true, :as => Range, :default => 1..-1
|
@@ -117,6 +120,9 @@ USAGE
|
|
117
120
|
if opts.present?(:method)
|
118
121
|
method_option
|
119
122
|
end
|
123
|
+
if opts.present?(:command)
|
124
|
+
command_option
|
125
|
+
end
|
120
126
|
|
121
127
|
perform_gist
|
122
128
|
end
|
@@ -170,6 +176,19 @@ USAGE
|
|
170
176
|
self.code_type = meth.source_type
|
171
177
|
end
|
172
178
|
|
179
|
+
def command_option
|
180
|
+
command = find_command(opts[:c])
|
181
|
+
command_source = command.block.source
|
182
|
+
|
183
|
+
if opts.present?(:lines)
|
184
|
+
self.content << restrict_to_lines(command_source, opts[:l])
|
185
|
+
else
|
186
|
+
self.content << command_source
|
187
|
+
end
|
188
|
+
|
189
|
+
self.code_type = :ruby
|
190
|
+
end
|
191
|
+
|
173
192
|
def perform_gist
|
174
193
|
type_map = { :ruby => "rb", :c => "c", :plain => "plain" }
|
175
194
|
|
@@ -3,53 +3,81 @@ class Pry
|
|
3
3
|
|
4
4
|
Gems = Pry::CommandSet.new do
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
else
|
17
|
-
Gem.refresh
|
18
|
-
output.puts "Gem `#{text.green gem}` installed."
|
6
|
+
create_command "gem-install", "Install a gem and refresh the gem cache.", :argument_required => true do |gem|
|
7
|
+
|
8
|
+
banner <<-BANNER
|
9
|
+
Usage: gem-install GEM_NAME
|
10
|
+
|
11
|
+
Installs the given gem and refreshes the gem cache so that you can immediately 'require GEM_FILE'
|
12
|
+
BANNER
|
13
|
+
|
14
|
+
def setup
|
15
|
+
require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller
|
19
16
|
end
|
20
|
-
end
|
21
17
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
18
|
+
def process(gem)
|
19
|
+
begin
|
20
|
+
destination = File.writable?(Gem.dir) ? Gem.dir : Gem.user_dir
|
21
|
+
installer = Gem::DependencyInstaller.new :install_dir => destination
|
22
|
+
installer.install gem
|
23
|
+
rescue Errno::EACCES
|
24
|
+
raise CommandError, "Insufficient permissions to install `#{text.green gem}`."
|
25
|
+
rescue Gem::GemNotFoundException
|
26
|
+
raise CommandError, "Gem `#{text.green gem}` not found."
|
27
|
+
else
|
28
|
+
Gem.refresh
|
29
|
+
output.puts "Gem `#{text.green gem}` installed."
|
30
|
+
end
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
Gem::Specification.select{|spec| spec.name =~ pattern }.group_by(&:name)
|
36
|
-
else
|
37
|
-
Gem.source_index.gems.values.group_by(&:name).select { |gemname, specs| gemname =~ pattern }
|
38
|
-
end
|
39
|
-
|
40
|
-
gems.each do |gem, specs|
|
41
|
-
specs.sort! do |a,b|
|
42
|
-
Gem::Version.new(b.version) <=> Gem::Version.new(a.version)
|
43
|
-
end
|
34
|
+
create_command "gem-cd", "Change working directory to specified gem's directory.", :argument_required => true do |gem|
|
35
|
+
banner <<-BANNER
|
36
|
+
Usage: gem-cd GEM_NAME
|
44
37
|
|
45
|
-
|
46
|
-
|
47
|
-
end
|
38
|
+
Change the current working directory to that in which the given gem is installed.
|
39
|
+
BANNER
|
48
40
|
|
49
|
-
|
41
|
+
def process(gem)
|
42
|
+
specs = Gem::Specification.respond_to?(:each) ? Gem::Specification.find_all_by_name(gem) : Gem.source_index.find_name(gem)
|
43
|
+
spec = specs.sort { |a,b| Gem::Version.new(b.version) <=> Gem::Version.new(a.version) }.first
|
44
|
+
if spec
|
45
|
+
Dir.chdir(spec.full_gem_path)
|
46
|
+
output.puts(Dir.pwd)
|
47
|
+
else
|
48
|
+
raise CommandError, "Gem `#{gem}` not found."
|
49
|
+
end
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
create_command "gem-list", "List and search installed gems." do |pattern|
|
54
|
+
banner <<-BANNER
|
55
|
+
Usage: gem-list [REGEX]
|
56
|
+
|
57
|
+
List all installed gems, when a regex is provided, limit the output to those that
|
58
|
+
match the regex.
|
59
|
+
BANNER
|
60
|
+
|
61
|
+
def process(pattern=nil)
|
62
|
+
gems = if Gem::Specification.respond_to?(:each)
|
63
|
+
Gem::Specification.select{|spec| spec.name =~ pattern }.group_by(&:name)
|
64
|
+
else
|
65
|
+
Gem.source_index.gems.values.group_by(&:name).select { |gemname, specs| gemname =~ pattern }
|
66
|
+
end
|
67
|
+
|
68
|
+
gems.each do |gem, specs|
|
69
|
+
specs.sort! do |a,b|
|
70
|
+
Gem::Version.new(b.version) <=> Gem::Version.new(a.version)
|
71
|
+
end
|
72
|
+
|
73
|
+
versions = specs.each_with_index.map do |spec, index|
|
74
|
+
index == 0 ? text.bright_green(spec.version.to_s) : text.green(spec.version.to_s)
|
75
|
+
end
|
76
|
+
|
77
|
+
output.puts "#{text.default gem} (#{versions.join ', '})"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
53
81
|
end
|
54
82
|
end
|
55
83
|
end
|