pry 0.9.8pre5-i386-mswin32 → 0.9.8pre6-i386-mswin32
Sign up to get free protection for your applications and to get access to all the features.
- 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
|