pry 0.7.2 → 0.8.0
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/CHANGELOG +9 -0
- data/README.markdown +393 -197
- data/Rakefile +5 -4
- data/bin/pry +31 -39
- data/examples/example_basic.rb +1 -1
- data/lib/pry/command_base.rb +74 -21
- data/lib/pry/command_base_helpers.rb +241 -0
- data/lib/pry/command_helpers.rb +303 -0
- data/lib/pry/command_processor.rb +174 -0
- data/lib/pry/commands.rb +495 -257
- data/lib/pry/completion.rb +1 -1
- data/lib/pry/custom_completions.rb +6 -0
- data/lib/pry/hooks.rb +5 -7
- data/lib/pry/print.rb +10 -13
- data/lib/pry/prompts.rb +7 -2
- data/lib/pry/pry_class.rb +34 -11
- data/lib/pry/pry_instance.rb +112 -97
- data/lib/pry/version.rb +1 -1
- data/lib/pry.rb +18 -12
- data/test/test.rb +126 -59
- data/test/test_helper.rb +6 -0
- metadata +34 -43
data/lib/pry/commands.rb
CHANGED
|
@@ -1,70 +1,55 @@
|
|
|
1
|
+
direc = File.dirname(__FILE__)
|
|
2
|
+
|
|
1
3
|
require "optparse"
|
|
2
4
|
require "method_source"
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
rescue LoadError
|
|
9
|
-
end
|
|
5
|
+
require 'slop'
|
|
6
|
+
require 'rubygems/dependency_installer'
|
|
7
|
+
require "#{direc}/command_base"
|
|
8
|
+
require "#{direc}/pry_instance"
|
|
9
|
+
require "#{direc}/command_helpers"
|
|
10
10
|
|
|
11
11
|
class Pry
|
|
12
12
|
|
|
13
13
|
# Default commands used by Pry.
|
|
14
14
|
class Commands < CommandBase
|
|
15
|
+
extend CommandHelpers
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
meth_name_from_binding = lambda do |b|
|
|
18
|
-
meth_name = b.eval('__method__')
|
|
17
|
+
try_to_load_pry_doc
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
else
|
|
24
|
-
meth_name
|
|
25
|
-
end
|
|
19
|
+
command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
|
|
20
|
+
output.puts "Input buffer cleared!"
|
|
21
|
+
opts[:eval_string].clear
|
|
26
22
|
end
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
raise "Cannot retrieve source for dynamically defined method."
|
|
31
|
-
end
|
|
24
|
+
command "!pry", "Start a Pry session on current self; this even works mid-expression." do
|
|
25
|
+
Pry.start(target)
|
|
32
26
|
end
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
# this cannot be accessed, it's just for help purposes.
|
|
29
|
+
command ".<shell command>", "All text following a '.' is forwarded to the shell." do
|
|
36
30
|
end
|
|
37
31
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
target.eval("instance_method(:#{meth_name})")
|
|
46
|
-
rescue
|
|
47
|
-
target.eval("method(:#{meth_name})")
|
|
48
|
-
end
|
|
32
|
+
command "hist", "Show and replay Readline history. Type `hist --help` for more info." do |*args|
|
|
33
|
+
hist_array = Readline::HISTORY.to_a
|
|
34
|
+
|
|
35
|
+
if args.empty?
|
|
36
|
+
text = add_line_numbers(hist_array.join("\n"), 0)
|
|
37
|
+
stagger_output(text)
|
|
38
|
+
next
|
|
49
39
|
end
|
|
50
|
-
end
|
|
51
40
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
end
|
|
41
|
+
opts = Slop.parse(args) do |opt|
|
|
42
|
+
opt.banner "Usage: hist [--replay START..END]\nView and replay history\ne.g hist --replay 2..8"
|
|
43
|
+
opt.on :r, :replay, 'The line (or range of lines) to replay.', true, :as => Range
|
|
44
|
+
opt.on :h, :help, 'Show this message.', :tail => true do
|
|
45
|
+
output.puts opt.help
|
|
46
|
+
end
|
|
47
|
+
end
|
|
60
48
|
|
|
61
|
-
|
|
62
|
-
output.puts "Input buffer cleared!"
|
|
63
|
-
opts[:eval_string].clear
|
|
64
|
-
end
|
|
49
|
+
next if opts.h?
|
|
65
50
|
|
|
66
|
-
|
|
67
|
-
Pry.
|
|
51
|
+
actions = Array(hist_array[opts[:replay]]).join("\n") + "\n"
|
|
52
|
+
Pry.active_instance.input = StringIO.new(actions)
|
|
68
53
|
end
|
|
69
54
|
|
|
70
55
|
command "exit-program", "End the current program. Aliases: quit-program, !!!" do
|
|
@@ -74,6 +59,150 @@ class Pry
|
|
|
74
59
|
alias_command "quit-program", "exit-program", ""
|
|
75
60
|
alias_command "!!!", "exit-program", ""
|
|
76
61
|
|
|
62
|
+
command "gem-install", "Install a gem" do |gem_name|
|
|
63
|
+
gem_home = Gem.instance_variable_get(:@gem_home)
|
|
64
|
+
output.puts "Attempting to install gem: #{bold(gem_name)}"
|
|
65
|
+
|
|
66
|
+
begin
|
|
67
|
+
if File.writable?(gem_home)
|
|
68
|
+
Gem::DependencyInstaller.new.install(gem_name)
|
|
69
|
+
output.puts "Gem #{bold(gem_name)} successfully installed."
|
|
70
|
+
else
|
|
71
|
+
if system("sudo gem install #{gem_name}")
|
|
72
|
+
output.puts "Gem #{bold(gem_name)} successfully installed."
|
|
73
|
+
else
|
|
74
|
+
output.puts "Gem #{bold(gem_name)} could not be installed."
|
|
75
|
+
next
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
rescue Gem::GemNotFoundException
|
|
79
|
+
output.puts "Required Gem: #{bold(gem_name)} not found."
|
|
80
|
+
next
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
Gem.refresh
|
|
84
|
+
output.puts "Refreshed gem cache."
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
command "ri", "View ri documentation. e.g `ri Array#each`" do |*args|
|
|
88
|
+
run ".ri", *args
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
command "stat", "View method information and set _file_ and _dir_ locals. Type `stat --help` for more info." do |*args|
|
|
92
|
+
target = target()
|
|
93
|
+
|
|
94
|
+
opts = Slop.parse!(args) do |opts|
|
|
95
|
+
opts.banner %{Usage: stat [OPTIONS] [METH]
|
|
96
|
+
Show method information for method METH and set _file_ and _dir_ locals.
|
|
97
|
+
e.g: stat hello_method
|
|
98
|
+
--
|
|
99
|
+
}
|
|
100
|
+
opts.on :M, "instance-methods", "Operate on instance methods."
|
|
101
|
+
opts.on :m, :methods, "Operate on methods."
|
|
102
|
+
opts.on :c, :context, "Select object context to run under.", true do |context|
|
|
103
|
+
target = Pry.binding_for(target.eval(context))
|
|
104
|
+
end
|
|
105
|
+
opts.on :h, :help, "This message" do
|
|
106
|
+
output.puts opts
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
next if opts.help?
|
|
111
|
+
|
|
112
|
+
meth_name = args.shift
|
|
113
|
+
if meth_name
|
|
114
|
+
if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context?
|
|
115
|
+
context, meth_name = $1, $2
|
|
116
|
+
target = Pry.binding_for(target.eval(context))
|
|
117
|
+
end
|
|
118
|
+
else
|
|
119
|
+
meth_name = meth_name_from_binding(target)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
|
123
|
+
output.puts "Invalid method name: #{meth_name}. Type `stat --help` for help"
|
|
124
|
+
next
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
code, code_type = code_and_code_type_for(meth)
|
|
128
|
+
next if !code
|
|
129
|
+
doc, code_type = doc_and_code_type_for(meth)
|
|
130
|
+
|
|
131
|
+
output.puts make_header(meth, code_type, code)
|
|
132
|
+
output.puts bold("Method Name: ") + meth_name
|
|
133
|
+
output.puts bold("Method Owner: ") + (meth.owner.to_s ? meth.owner.to_s : "Unknown")
|
|
134
|
+
output.puts bold("Method Language: ") + code_type.to_s.capitalize
|
|
135
|
+
output.puts bold("Method Type: ") + (meth.is_a?(Method) ? "Bound" : "Unbound")
|
|
136
|
+
output.puts bold("Method Arity: ") + meth.arity.to_s
|
|
137
|
+
|
|
138
|
+
name_map = { :req => "Required:", :opt => "Optional:", :rest => "Rest:" }
|
|
139
|
+
if meth.respond_to?(:parameters)
|
|
140
|
+
output.puts bold("Method Parameters: ") + meth.parameters.group_by(&:first).
|
|
141
|
+
map { |k, v| "#{name_map[k]} #{v.map { |kk, vv| vv ? vv.to_s : "noname" }.join(", ")}" }.join(". ")
|
|
142
|
+
end
|
|
143
|
+
output.puts bold("Comment length: ") + (doc.empty? ? 'No comment.' : (doc.lines.count.to_s + ' lines.'))
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
command "gist-method", "Gist a method to github. Type `gist-method --help` for more info.", :requires_gem => "gist" do |*args|
|
|
147
|
+
target = target()
|
|
148
|
+
|
|
149
|
+
opts = Slop.parse!(args) do |opts|
|
|
150
|
+
opts.banner = %{Usage: gist-method [OPTIONS] [METH]
|
|
151
|
+
Gist the method (doc or source) to github.
|
|
152
|
+
e.g: gist -m my_method
|
|
153
|
+
e.g: gist -d my_method
|
|
154
|
+
--
|
|
155
|
+
}
|
|
156
|
+
opts.on :m, :method, "Gist a method's source."
|
|
157
|
+
opts.on :d, :doc, "Gist a method's documentation."
|
|
158
|
+
opts.on :p, :private, "Create a private gist (default: true)", :default => true
|
|
159
|
+
opts.on :h, :help, "This message" do
|
|
160
|
+
output.puts opts
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
next if opts.help?
|
|
165
|
+
|
|
166
|
+
# This needs to be extracted into its own method as it's shared
|
|
167
|
+
# by show-method and show-doc and stat commands
|
|
168
|
+
meth_name = args.shift
|
|
169
|
+
if meth_name
|
|
170
|
+
if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/
|
|
171
|
+
context, meth_name = $1, $2
|
|
172
|
+
target = Pry.binding_for(target.eval(context))
|
|
173
|
+
end
|
|
174
|
+
else
|
|
175
|
+
meth_name = meth_name_from_binding(target)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
|
179
|
+
output.puts "Invalid method name: #{meth_name}. Type `gist-method --help` for help"
|
|
180
|
+
next
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
type_map = { :ruby => "rb", :c => "c", :plain => "plain" }
|
|
184
|
+
if !opts.doc?
|
|
185
|
+
content, code_type = code_and_code_type_for(meth)
|
|
186
|
+
else
|
|
187
|
+
content, code_type = doc_and_code_type_for(meth)
|
|
188
|
+
no_color do
|
|
189
|
+
content = process_comment_markup(content, code_type)
|
|
190
|
+
end
|
|
191
|
+
code_type = :plain
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
IO.popen("gist#{' -p' if opts.p?} -t #{type_map[code_type]} -", "w") do |gist|
|
|
195
|
+
gist.puts content
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
command "gem-cd", "Change working directory to specified gem's directory." do |gem_name|
|
|
200
|
+
require 'rubygems'
|
|
201
|
+
gem_spec = Gem.source_index.find_name(gem_name).first
|
|
202
|
+
next output.puts("Gem `#{gem_name}` not found.") if !gem_spec
|
|
203
|
+
Dir.chdir(File.expand_path(gem_spec.full_gem_path))
|
|
204
|
+
end
|
|
205
|
+
|
|
77
206
|
command "toggle-color", "Toggle syntax highlighting." do
|
|
78
207
|
Pry.color = !Pry.color
|
|
79
208
|
output.puts "Syntax highlighting #{Pry.color ? "on" : "off"}"
|
|
@@ -88,9 +217,24 @@ class Pry
|
|
|
88
217
|
end
|
|
89
218
|
end
|
|
90
219
|
|
|
91
|
-
command "
|
|
220
|
+
command "shell-mode", "Toggle shell mode. Bring in pwd prompt and file completion." do
|
|
221
|
+
case Pry.active_instance.prompt
|
|
222
|
+
when Pry::SHELL_PROMPT
|
|
223
|
+
Pry.active_instance.prompt = Pry::DEFAULT_PROMPT
|
|
224
|
+
Pry.active_instance.custom_completions = Pry::DEFAULT_CUSTOM_COMPLETIONS
|
|
225
|
+
else
|
|
226
|
+
Pry.active_instance.prompt = Pry::SHELL_PROMPT
|
|
227
|
+
Pry.active_instance.custom_completions = Pry::FILE_COMPLETIONS
|
|
228
|
+
Readline.completion_proc = Pry::InputCompleter.build_completion_proc target,
|
|
229
|
+
Pry.active_instance.instance_eval(&Pry::FILE_COMPLETIONS)
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
alias_command "file-mode", "shell-mode", ""
|
|
234
|
+
|
|
235
|
+
command "nesting", "Show nesting information." do
|
|
92
236
|
nesting = opts[:nesting]
|
|
93
|
-
|
|
237
|
+
|
|
94
238
|
output.puts "Nesting status:"
|
|
95
239
|
output.puts "--"
|
|
96
240
|
nesting.each do |level, obj|
|
|
@@ -104,7 +248,7 @@ class Pry
|
|
|
104
248
|
|
|
105
249
|
command "status", "Show status information." do
|
|
106
250
|
nesting = opts[:nesting]
|
|
107
|
-
|
|
251
|
+
|
|
108
252
|
output.puts "Status:"
|
|
109
253
|
output.puts "--"
|
|
110
254
|
output.puts "Receiver: #{Pry.view_clip(target.eval('self'))}"
|
|
@@ -112,32 +256,85 @@ class Pry
|
|
|
112
256
|
output.puts "Pry version: #{Pry::VERSION}"
|
|
113
257
|
output.puts "Ruby version: #{RUBY_VERSION}"
|
|
114
258
|
|
|
115
|
-
mn = meth_name_from_binding
|
|
259
|
+
mn = meth_name_from_binding(target)
|
|
116
260
|
output.puts "Current method: #{mn ? mn : "N/A"}"
|
|
117
261
|
output.puts "Pry instance: #{Pry.active_instance}"
|
|
118
262
|
output.puts "Last result: #{Pry.view(Pry.last_result)}"
|
|
119
263
|
end
|
|
120
264
|
|
|
121
|
-
|
|
265
|
+
|
|
266
|
+
command "req", "Requires gem(s). No need for quotes! (If the gem isn't installed, it will ask if you want to install it.)" do |*gems|
|
|
267
|
+
gems = gems.join(' ').gsub(',', '').split(/\s+/)
|
|
268
|
+
gems.each do |gem|
|
|
269
|
+
begin
|
|
270
|
+
if require gem
|
|
271
|
+
output.puts "#{bright_yellow(gem)} loaded"
|
|
272
|
+
else
|
|
273
|
+
output.puts "#{bright_white(gem)} already loaded"
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
rescue LoadError => e
|
|
277
|
+
|
|
278
|
+
if gem_installed? gem
|
|
279
|
+
output.puts e.inspect
|
|
280
|
+
else
|
|
281
|
+
output.puts "#{bright_red(gem)} not found"
|
|
282
|
+
if prompt("Install the gem?") == "y"
|
|
283
|
+
run "gem-install", gem
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
end # rescue
|
|
288
|
+
end # gems.each
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
command "gem-list", "List/search installed gems. (Optional parameter: a regexp to limit the search)" do |arg|
|
|
293
|
+
gems = Gem.source_index.gems.values.group_by(&:name)
|
|
294
|
+
if arg
|
|
295
|
+
query = Regexp.new(arg, Regexp::IGNORECASE)
|
|
296
|
+
gems = gems.select { |gemname, specs| gemname =~ query }
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
gems.each do |gemname, specs|
|
|
300
|
+
versions = specs.map(&:version).sort.reverse.map(&:to_s)
|
|
301
|
+
versions = ["<bright_green>#{versions.first}</bright_green>"] +
|
|
302
|
+
versions[1..-1].map{|v| "<green>#{v}</green>" }
|
|
303
|
+
|
|
304
|
+
gemname = highlight(gemname, query) if query
|
|
305
|
+
result = "<white>#{gemname} <grey>(#{versions.join ', '})</grey>"
|
|
306
|
+
output.puts colorize(result)
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
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|
|
|
122
312
|
file = target.eval('__FILE__')
|
|
123
313
|
line_num = target.eval('__LINE__')
|
|
124
314
|
klass = target.eval('self.class')
|
|
125
315
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
316
|
+
if num
|
|
317
|
+
i_num = num.to_i
|
|
318
|
+
else
|
|
319
|
+
i_num = 5
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
meth_name = meth_name_from_binding(target)
|
|
323
|
+
meth_name = "N/A" if !meth_name
|
|
324
|
+
|
|
325
|
+
if file =~ /(\(.*\))|<.*>/ || file == "" || file == "-e"
|
|
326
|
+
output.puts "Cannot find local context. Did you use `binding.pry` ?"
|
|
129
327
|
next
|
|
130
328
|
end
|
|
131
329
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
330
|
+
set_file_and_dir_locals(file)
|
|
331
|
+
output.puts "\n#{bold('From:')} #{file} @ line #{line_num} in #{klass}##{meth_name}:\n\n"
|
|
332
|
+
|
|
136
333
|
# This method inspired by http://rubygems.org/gems/ir_b
|
|
137
334
|
File.open(file).each_with_index do |line, index|
|
|
138
335
|
line_n = index + 1
|
|
139
|
-
next unless line_n > (line_num -
|
|
140
|
-
break if line_n > (line_num +
|
|
336
|
+
next unless line_n > (line_num - i_num - 1)
|
|
337
|
+
break if line_n > (line_num + i_num)
|
|
141
338
|
if line_n == line_num
|
|
142
339
|
code =" =>#{line_n.to_s.rjust(3)}: #{line.chomp}"
|
|
143
340
|
if Pry.color
|
|
@@ -155,25 +352,24 @@ class Pry
|
|
|
155
352
|
end
|
|
156
353
|
end
|
|
157
354
|
end
|
|
158
|
-
|
|
355
|
+
|
|
159
356
|
command "version", "Show Pry version." do
|
|
160
357
|
output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}."
|
|
161
358
|
end
|
|
162
|
-
|
|
163
|
-
command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases:
|
|
164
|
-
str = remove_first_word
|
|
359
|
+
|
|
360
|
+
command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !!@" do
|
|
361
|
+
str = remove_first_word(opts[:val])
|
|
165
362
|
throw(:breakout, [0, target.eval(str)])
|
|
166
363
|
end
|
|
167
364
|
|
|
168
|
-
alias_command "
|
|
365
|
+
alias_command "!!@", "exit-all", ""
|
|
169
366
|
|
|
170
|
-
command "ls", "Show the list of vars in the current scope. Type `ls --help` for more info." do |*args|
|
|
367
|
+
command "ls", "Show the list of vars and methods in the current scope. Type `ls --help` for more info." do |*args|
|
|
171
368
|
options = {}
|
|
172
|
-
|
|
173
369
|
# Set target local to the default -- note that we can set a different target for
|
|
174
370
|
# ls if we like: e.g ls my_var
|
|
175
371
|
target = target()
|
|
176
|
-
|
|
372
|
+
|
|
177
373
|
OptionParser.new do |opts|
|
|
178
374
|
opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\
|
|
179
375
|
List information about VAR (the current context by default).
|
|
@@ -183,7 +379,7 @@ Shows local and instance variables by default.
|
|
|
183
379
|
opts.on("-g", "--globals", "Display global variables.") do
|
|
184
380
|
options[:g] = true
|
|
185
381
|
end
|
|
186
|
-
|
|
382
|
+
|
|
187
383
|
opts.on("-c", "--constants", "Display constants.") do
|
|
188
384
|
options[:c] = true
|
|
189
385
|
end
|
|
@@ -192,15 +388,15 @@ Shows local and instance variables by default.
|
|
|
192
388
|
options[:l] = true
|
|
193
389
|
end
|
|
194
390
|
|
|
195
|
-
opts.on("-i", "--ivars", "Display instance variables.") do
|
|
391
|
+
opts.on("-i", "--ivars", "Display instance variables.") do
|
|
196
392
|
options[:i] = true
|
|
197
393
|
end
|
|
198
394
|
|
|
199
|
-
opts.on("-k", "--class-vars", "Display class variables.") do
|
|
395
|
+
opts.on("-k", "--class-vars", "Display class variables.") do
|
|
200
396
|
options[:k] = true
|
|
201
|
-
end
|
|
397
|
+
end
|
|
202
398
|
|
|
203
|
-
opts.on("-m", "--methods", "Display methods (public methods by default).") do
|
|
399
|
+
opts.on("-m", "--methods", "Display methods (public methods by default).") do
|
|
204
400
|
options[:m] = true
|
|
205
401
|
end
|
|
206
402
|
|
|
@@ -208,34 +404,42 @@ Shows local and instance variables by default.
|
|
|
208
404
|
options[:M] = true
|
|
209
405
|
end
|
|
210
406
|
|
|
211
|
-
opts.on("-P", "--public", "Display public methods (with -m).") do
|
|
407
|
+
opts.on("-P", "--public", "Display public methods (with -m).") do
|
|
212
408
|
options[:P] = true
|
|
213
409
|
end
|
|
214
410
|
|
|
215
|
-
opts.on("-r", "--protected", "Display protected methods (with -m).") do
|
|
411
|
+
opts.on("-r", "--protected", "Display protected methods (with -m).") do
|
|
216
412
|
options[:r] = true
|
|
217
|
-
end
|
|
413
|
+
end
|
|
218
414
|
|
|
219
|
-
opts.on("-p", "--private", "Display private methods (with -m).") do
|
|
415
|
+
opts.on("-p", "--private", "Display private methods (with -m).") do
|
|
220
416
|
options[:p] = true
|
|
221
417
|
end
|
|
222
418
|
|
|
223
|
-
opts.on("-j", "--just-singletons", "Display just the singleton methods (with -m).") do
|
|
419
|
+
opts.on("-j", "--just-singletons", "Display just the singleton methods (with -m).") do
|
|
224
420
|
options[:j] = true
|
|
225
|
-
end
|
|
421
|
+
end
|
|
226
422
|
|
|
227
|
-
opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
|
|
423
|
+
opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
|
|
228
424
|
options[:s] = true
|
|
229
425
|
end
|
|
230
|
-
|
|
426
|
+
|
|
231
427
|
opts.on("-a", "--all", "Display all types of entries.") do
|
|
232
428
|
options[:a] = true
|
|
233
429
|
end
|
|
234
430
|
|
|
235
|
-
opts.on("-v", "--verbose", "Verbose ouput.") do
|
|
431
|
+
opts.on("-v", "--verbose", "Verbose ouput.") do
|
|
236
432
|
options[:v] = true
|
|
237
433
|
end
|
|
238
434
|
|
|
435
|
+
opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
|
|
436
|
+
options[:f] = true
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
opts.on("--grep REG", "Regular expression to be used.") do |reg|
|
|
440
|
+
options[:grep] = Regexp.new(reg)
|
|
441
|
+
end
|
|
442
|
+
|
|
239
443
|
opts.on_tail("-h", "--help", "Show this message.") do
|
|
240
444
|
output.puts opts
|
|
241
445
|
options[:h] = true
|
|
@@ -253,18 +457,21 @@ Shows local and instance variables by default.
|
|
|
253
457
|
:l => true,
|
|
254
458
|
:i => true,
|
|
255
459
|
:k => true
|
|
256
|
-
}) if options.empty? || (options.size == 1 && options[:v])
|
|
460
|
+
}) if options.empty? || (options.size == 1 && options[:v]) || (options.size == 1 && options[:grep])
|
|
461
|
+
|
|
462
|
+
options[:grep] = // if !options[:grep]
|
|
463
|
+
|
|
257
464
|
|
|
258
465
|
# Display public methods by default if -m or -M switch is used.
|
|
259
466
|
options[:P] = true if (options[:m] || options[:M]) && !(options[:p] || options[:r] || options[:j])
|
|
260
|
-
|
|
467
|
+
|
|
261
468
|
info = {}
|
|
262
469
|
target_self = target.eval('self')
|
|
263
470
|
|
|
264
471
|
# ensure we have a real boolean and not a `nil` (important when
|
|
265
472
|
# interpolating in the string)
|
|
266
473
|
options[:s] = !!options[:s]
|
|
267
|
-
|
|
474
|
+
|
|
268
475
|
# Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8
|
|
269
476
|
i = -1
|
|
270
477
|
|
|
@@ -279,7 +486,7 @@ Shows local and instance variables by default.
|
|
|
279
486
|
end, i += 1] if options[:k] || options[:a]
|
|
280
487
|
|
|
281
488
|
info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a]
|
|
282
|
-
|
|
489
|
+
|
|
283
490
|
info["public methods"] = [Array(target.eval("public_methods(#{options[:s]})")).uniq.sort, i += 1] if (options[:m] && options[:P]) || options[:a]
|
|
284
491
|
|
|
285
492
|
info["protected methods"] = [Array(target.eval("protected_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:r]) || options[:a]
|
|
@@ -287,59 +494,132 @@ Shows local and instance variables by default.
|
|
|
287
494
|
info["private methods"] = [Array(target.eval("private_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:p]) || options[:a]
|
|
288
495
|
|
|
289
496
|
info["just singleton methods"] = [Array(target.eval("methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:j]) || options[:a]
|
|
290
|
-
|
|
497
|
+
|
|
291
498
|
info["public instance methods"] = [Array(target.eval("public_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:P]) || options[:a])
|
|
292
499
|
|
|
293
500
|
info["protected instance methods"] = [Array(target.eval("protected_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:r]) || options[:a])
|
|
294
501
|
|
|
295
502
|
info["private instance methods"] = [Array(target.eval("private_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:p]) || options[:a])
|
|
296
|
-
|
|
503
|
+
|
|
297
504
|
# dealing with 1.8/1.9 compatibility issues :/
|
|
298
505
|
csuper = options[:s]
|
|
299
506
|
if Module.method(:constants).arity == 0
|
|
300
507
|
csuper = nil
|
|
301
508
|
end
|
|
302
|
-
|
|
509
|
+
|
|
303
510
|
info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") :
|
|
304
511
|
target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a]
|
|
305
512
|
|
|
513
|
+
text = ""
|
|
514
|
+
|
|
306
515
|
# verbose output?
|
|
307
516
|
if options[:v]
|
|
308
|
-
|
|
309
517
|
# verbose
|
|
518
|
+
|
|
310
519
|
info.sort_by { |k, v| v.last }.each do |k, v|
|
|
311
520
|
if !v.first.empty?
|
|
312
|
-
|
|
521
|
+
text << "#{k}:\n--\n"
|
|
522
|
+
filtered_list = v.first.grep options[:grep]
|
|
313
523
|
if Pry.color
|
|
314
|
-
|
|
524
|
+
text << CodeRay.scan(Pry.view(filtered_list), :ruby).term + "\n"
|
|
315
525
|
else
|
|
316
|
-
|
|
526
|
+
text << Pry.view(filtered_list) + "\n"
|
|
317
527
|
end
|
|
318
|
-
|
|
528
|
+
text << "\n\n"
|
|
319
529
|
end
|
|
320
530
|
end
|
|
321
531
|
|
|
532
|
+
if !options[:f]
|
|
533
|
+
stagger_output(text)
|
|
534
|
+
else
|
|
535
|
+
output.puts text
|
|
536
|
+
end
|
|
537
|
+
|
|
322
538
|
# plain
|
|
323
539
|
else
|
|
324
540
|
list = info.values.sort_by(&:last).map(&:first).inject(&:+)
|
|
541
|
+
list = list.grep(options[:grep]) if list
|
|
325
542
|
list.uniq! if list
|
|
326
543
|
if Pry.color
|
|
327
|
-
|
|
544
|
+
text << CodeRay.scan(Pry.view(list), :ruby).term + "\n"
|
|
328
545
|
else
|
|
329
|
-
|
|
546
|
+
text << Pry.view(list) + "\n"
|
|
547
|
+
end
|
|
548
|
+
if !options[:f]
|
|
549
|
+
stagger_output(text)
|
|
550
|
+
else
|
|
551
|
+
output.puts text
|
|
330
552
|
end
|
|
331
553
|
list
|
|
332
554
|
end
|
|
333
555
|
end
|
|
334
556
|
|
|
335
|
-
command "
|
|
557
|
+
command "lls", "List local files using 'ls'" do |*args|
|
|
558
|
+
cmd = ".ls"
|
|
559
|
+
cmd << " --color=always" if Pry.color
|
|
560
|
+
run cmd, *args
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
command "lcd", "Change the current (working) directory" do |*args|
|
|
564
|
+
run ".cd", *args
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
command "cat", "Show output of file FILE. Type `cat --help` for more information." do |*args|
|
|
568
|
+
options= {}
|
|
569
|
+
file_name = nil
|
|
570
|
+
start_line = 0
|
|
571
|
+
end_line = -1
|
|
572
|
+
file_type = nil
|
|
573
|
+
|
|
574
|
+
OptionParser.new do |opts|
|
|
575
|
+
opts.banner = %{Usage: cat [OPTIONS] FILE
|
|
576
|
+
Cat a file. Defaults to displaying whole file. Syntax highlights file if type is recognized.
|
|
577
|
+
e.g: cat hello.rb
|
|
578
|
+
--
|
|
579
|
+
}
|
|
580
|
+
opts.on("-l", "--line-numbers", "Show line numbers.") do |line|
|
|
581
|
+
options[:l] = true
|
|
582
|
+
end
|
|
583
|
+
|
|
584
|
+
opts.on("-s", "--start LINE", "Start line (defaults to start of file). Line 1 is the first line.") do |line|
|
|
585
|
+
start_line = line.to_i - 1
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
opts.on("-e", "--end LINE", "End line (defaults to end of file). Line -1 is the last line.") do |line|
|
|
589
|
+
end_line = line.to_i - 1
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
opts.on("-t", "--type TYPE", "The specific file type for syntax higlighting (e.g ruby, python, cpp, java)") do |type|
|
|
593
|
+
file_type = type.to_sym
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
|
|
597
|
+
options[:f] = true
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
opts.on_tail("-h", "--help", "This message.") do
|
|
601
|
+
output.puts opts
|
|
602
|
+
options[:h] = true
|
|
603
|
+
end
|
|
604
|
+
end.order(args) do |v|
|
|
605
|
+
file_name = v
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
next if options[:h]
|
|
609
|
+
|
|
336
610
|
if !file_name
|
|
337
611
|
output.puts "Must provide a file name."
|
|
338
612
|
next
|
|
339
613
|
end
|
|
340
614
|
|
|
341
|
-
contents =
|
|
342
|
-
|
|
615
|
+
contents, normalized_start_line, _ = read_between_the_lines(file_name, start_line, end_line)
|
|
616
|
+
|
|
617
|
+
if Pry.color
|
|
618
|
+
contents = syntax_highlight_by_file_type_or_specified(contents, file_name, file_type)
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
set_file_and_dir_locals(file_name)
|
|
622
|
+
render_output(options[:f], options[:l] ? normalized_start_line + 1 : false, contents)
|
|
343
623
|
contents
|
|
344
624
|
end
|
|
345
625
|
|
|
@@ -347,7 +627,7 @@ Shows local and instance variables by default.
|
|
|
347
627
|
options = {}
|
|
348
628
|
target = target()
|
|
349
629
|
file_name = nil
|
|
350
|
-
|
|
630
|
+
|
|
351
631
|
OptionParser.new do |opts|
|
|
352
632
|
opts.banner = %{Usage: eval-file [OPTIONS] FILE
|
|
353
633
|
Eval a Ruby script at top-level or in the specified context. Defaults to top-level.
|
|
@@ -359,7 +639,7 @@ e.g: eval-file -c self "hello.rb"
|
|
|
359
639
|
target = Pry.binding_for(target.eval(context))
|
|
360
640
|
end
|
|
361
641
|
|
|
362
|
-
opts.on_tail("-h", "--help", "This message.") do
|
|
642
|
+
opts.on_tail("-h", "--help", "This message.") do
|
|
363
643
|
output.puts opts
|
|
364
644
|
options[:h] = true
|
|
365
645
|
end
|
|
@@ -383,235 +663,193 @@ e.g: eval-file -c self "hello.rb"
|
|
|
383
663
|
TOPLEVEL_BINDING.eval(File.read(File.expand_path(file_name)))
|
|
384
664
|
output.puts "--\nEval'd '#{file_name}' at top-level."
|
|
385
665
|
end
|
|
666
|
+
set_file_and_dir_locals(file_name)
|
|
667
|
+
|
|
386
668
|
new_constants = Object.constants - old_constants
|
|
387
669
|
output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty?
|
|
388
|
-
end
|
|
389
|
-
|
|
390
|
-
command "cat", "Show output of VAR.inspect. Aliases: inspect" do |obj|
|
|
391
|
-
if !obj
|
|
392
|
-
output.puts "Must provide an object to inspect."
|
|
393
|
-
next
|
|
394
|
-
end
|
|
395
|
-
|
|
396
|
-
output.puts Pry.view(target.eval("#{obj}"))
|
|
397
670
|
end
|
|
398
671
|
|
|
399
|
-
alias_command "inspect", "cat", ""
|
|
400
|
-
|
|
401
672
|
command "cd", "Start a Pry session on VAR (use `cd ..` to go back and `cd /` to return to Pry top-level)", :keep_retval => true do |obj|
|
|
402
673
|
if !obj
|
|
403
674
|
output.puts "Must provide an object."
|
|
404
675
|
next
|
|
405
676
|
end
|
|
406
|
-
|
|
677
|
+
|
|
407
678
|
throw(:breakout, opts[:nesting].level) if obj == ".."
|
|
408
679
|
|
|
409
|
-
if obj == "/"
|
|
680
|
+
if obj == "/"
|
|
410
681
|
throw(:breakout, 1) if opts[:nesting].level > 0
|
|
411
682
|
next
|
|
412
|
-
end
|
|
413
|
-
|
|
414
|
-
target.eval("#{obj}.pry")
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
process_comment_markup = lambda do |comment, code_type|
|
|
418
|
-
comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
|
|
419
|
-
gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
|
|
420
|
-
gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { Pry.color ? "\e[34m#{$1}\e[0m" : $1 }.
|
|
421
|
-
gsub(/\B\+(\w*?)\+\B/) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
|
|
422
|
-
gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }
|
|
423
|
-
end
|
|
683
|
+
end
|
|
424
684
|
|
|
425
|
-
|
|
426
|
-
comment.gsub /^\s*#\s*/, ''
|
|
685
|
+
Pry.start target.eval("#{obj}")
|
|
427
686
|
end
|
|
428
687
|
|
|
429
|
-
command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info." do |*args|
|
|
430
|
-
options = {}
|
|
688
|
+
command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info. Aliases: \?" do |*args|
|
|
431
689
|
target = target()
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
opts.banner = %{Usage: show-doc [OPTIONS] [METH]
|
|
690
|
+
|
|
691
|
+
opts = Slop.parse!(args) do |opts|
|
|
692
|
+
opts.banner %{Usage: show-doc [OPTIONS] [METH]
|
|
436
693
|
Show the comments above method METH. Tries instance methods first and then methods by default.
|
|
437
694
|
e.g show-doc hello_method
|
|
438
695
|
--
|
|
439
696
|
}
|
|
440
|
-
opts.on
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
opts.on("-m", "--methods", "Operate on methods.") do
|
|
445
|
-
options[:m] = true
|
|
446
|
-
end
|
|
447
|
-
|
|
448
|
-
opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
|
|
697
|
+
opts.on :M, "instance-methods", "Operate on instance methods."
|
|
698
|
+
opts.on :m, :methods, "Operate on methods."
|
|
699
|
+
opts.on :c, :context, "Select object context to run under.", true do |context|
|
|
449
700
|
target = Pry.binding_for(target.eval(context))
|
|
450
701
|
end
|
|
451
|
-
|
|
452
|
-
opts.
|
|
702
|
+
opts.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
|
703
|
+
opts.on :h, :help, "This message." do
|
|
453
704
|
output.puts opts
|
|
454
|
-
options[:h] = true
|
|
455
705
|
end
|
|
456
|
-
end.order(args) do |v|
|
|
457
|
-
meth_name = v
|
|
458
706
|
end
|
|
459
707
|
|
|
460
|
-
next if
|
|
708
|
+
next if opts.help?
|
|
461
709
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
710
|
+
meth_name = args.shift
|
|
711
|
+
if meth_name
|
|
712
|
+
if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context?
|
|
713
|
+
context, meth_name = $1, $2
|
|
714
|
+
target = Pry.binding_for(target.eval(context))
|
|
715
|
+
end
|
|
716
|
+
else
|
|
717
|
+
meth_name = meth_name_from_binding(target)
|
|
465
718
|
end
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
meth = get_method_object.call(meth_name, target, options)
|
|
469
|
-
rescue
|
|
719
|
+
|
|
720
|
+
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
|
470
721
|
output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
|
|
471
722
|
next
|
|
472
723
|
end
|
|
473
724
|
|
|
474
|
-
code_type =
|
|
475
|
-
if
|
|
476
|
-
info = Pry::MethodInfo.info_for(meth)
|
|
477
|
-
if !info
|
|
478
|
-
output.puts "Cannot find docs for C method: #{meth_name}"
|
|
479
|
-
next
|
|
480
|
-
end
|
|
481
|
-
doc = info.docstring
|
|
482
|
-
code_type = info.source_type
|
|
483
|
-
else
|
|
484
|
-
begin
|
|
485
|
-
doc = meth.comment
|
|
486
|
-
rescue
|
|
487
|
-
output.puts "Cannot locate source for this method: #{meth_name}. Try `gem install pry-doc` to get access to Ruby Core documentation."
|
|
488
|
-
next
|
|
489
|
-
end
|
|
490
|
-
doc = strip_leading_hash_from_ruby_comments.call(doc)
|
|
491
|
-
end
|
|
725
|
+
doc, code_type = doc_and_code_type_for(meth)
|
|
726
|
+
next if !doc
|
|
492
727
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
file, line = meth.source_location
|
|
496
|
-
check_for_dynamically_defined_method.call(file)
|
|
728
|
+
next output.puts("No documentation found.") if doc.empty?
|
|
497
729
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
output.puts doc
|
|
730
|
+
doc = process_comment_markup(doc, code_type)
|
|
731
|
+
|
|
732
|
+
output.puts make_header(meth, code_type, doc)
|
|
733
|
+
|
|
734
|
+
render_output(opts.flood?, false, doc)
|
|
501
735
|
doc
|
|
502
736
|
end
|
|
503
737
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
command "show-method", "Show the source for METH. Type `show-method --help` for more info." do |*args|
|
|
509
|
-
options = {}
|
|
738
|
+
alias_command "?", "show-doc", ""
|
|
739
|
+
|
|
740
|
+
command "show-method", "Show the source for METH. Type `show-method --help` for more info. Aliases: $, show-source" do |*args|
|
|
510
741
|
target = target()
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
opts.banner = %{Usage: show-method [OPTIONS] [METH]
|
|
742
|
+
|
|
743
|
+
opts = Slop.parse!(args) do |opts|
|
|
744
|
+
opts.banner %{Usage: show-method [OPTIONS] [METH]
|
|
515
745
|
Show the source for method METH. Tries instance methods first and then methods by default.
|
|
516
746
|
e.g: show-method hello_method
|
|
517
747
|
--
|
|
518
748
|
}
|
|
519
|
-
opts.on
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
opts.on
|
|
524
|
-
options[:m] = true
|
|
525
|
-
end
|
|
526
|
-
|
|
527
|
-
opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
|
|
749
|
+
opts.on :l, "line-numbers", "Show line numbers."
|
|
750
|
+
opts.on :M, "instance-methods", "Operate on instance methods."
|
|
751
|
+
opts.on :m, :methods, "Operate on methods."
|
|
752
|
+
opts.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
|
753
|
+
opts.on :c, :context, "Select object context to run under.", true do |context|
|
|
528
754
|
target = Pry.binding_for(target.eval(context))
|
|
529
755
|
end
|
|
530
|
-
|
|
531
|
-
opts.on_tail("-h", "--help", "This message.") do
|
|
756
|
+
opts.on :h, :help, "This message." do
|
|
532
757
|
output.puts opts
|
|
533
|
-
options[:h] = true
|
|
534
758
|
end
|
|
535
|
-
end.order(args) do |v|
|
|
536
|
-
meth_name = v
|
|
537
759
|
end
|
|
538
760
|
|
|
539
|
-
next if
|
|
761
|
+
next if opts.help?
|
|
540
762
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
763
|
+
meth_name = args.shift
|
|
764
|
+
if meth_name
|
|
765
|
+
if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context?
|
|
766
|
+
context, meth_name = $1, $2
|
|
767
|
+
target = Pry.binding_for(target.eval(context))
|
|
768
|
+
end
|
|
769
|
+
else
|
|
770
|
+
meth_name = meth_name_from_binding(target)
|
|
546
771
|
end
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
meth = get_method_object.call(meth_name, target, options)
|
|
550
|
-
rescue
|
|
772
|
+
|
|
773
|
+
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
|
551
774
|
output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
|
|
552
775
|
next
|
|
553
776
|
end
|
|
554
777
|
|
|
555
|
-
code_type =
|
|
556
|
-
|
|
557
|
-
# Try to find source for C methods using MethodInfo (if possible)
|
|
558
|
-
if Pry.has_pry_doc && meth.source_location.nil?
|
|
559
|
-
info = Pry::MethodInfo.info_for(meth)
|
|
560
|
-
if !info || !info.source
|
|
561
|
-
output.puts "Cannot find source for C method: #{meth_name}"
|
|
562
|
-
next
|
|
563
|
-
end
|
|
564
|
-
code = info.source
|
|
565
|
-
code = strip_comments_from_c_code.call(code)
|
|
566
|
-
code_type = info.source_type
|
|
567
|
-
else
|
|
568
|
-
begin
|
|
569
|
-
code = meth.source
|
|
570
|
-
rescue
|
|
571
|
-
output.puts "Cannot locate source for this method: #{meth_name}. Try `gem install pry-doc` to get access to Ruby Core documentation."
|
|
572
|
-
next
|
|
573
|
-
end
|
|
574
|
-
end
|
|
575
|
-
|
|
576
|
-
file, line = meth.source_location
|
|
577
|
-
check_for_dynamically_defined_method.call(file)
|
|
578
|
-
|
|
579
|
-
output.puts make_header.call(file, line, code_type)
|
|
778
|
+
code, code_type = code_and_code_type_for(meth)
|
|
779
|
+
next if !code
|
|
580
780
|
|
|
781
|
+
output.puts make_header(meth, code_type, code)
|
|
581
782
|
if Pry.color
|
|
582
783
|
code = CodeRay.scan(code, code_type).term
|
|
583
784
|
end
|
|
584
|
-
|
|
585
|
-
|
|
785
|
+
|
|
786
|
+
start_line = false
|
|
787
|
+
if opts.l?
|
|
788
|
+
start_line = meth.source_location ? meth.source_location.last : 1
|
|
789
|
+
end
|
|
790
|
+
|
|
791
|
+
render_output(opts.flood?, start_line, code)
|
|
586
792
|
code
|
|
587
793
|
end
|
|
588
|
-
|
|
589
|
-
|
|
794
|
+
|
|
795
|
+
alias_command "show-source", "show-method", ""
|
|
796
|
+
alias_command "$", "show-method", ""
|
|
797
|
+
|
|
798
|
+
command "show-command", "Show the source for CMD. Type `show-command --help` for more info." do |*args|
|
|
799
|
+
options = {}
|
|
800
|
+
target = target()
|
|
801
|
+
command_name = nil
|
|
802
|
+
|
|
803
|
+
OptionParser.new do |opts|
|
|
804
|
+
opts.banner = %{Usage: show-command [OPTIONS] [CMD]
|
|
805
|
+
Show the source for command CMD.
|
|
806
|
+
e.g: show-command show-method
|
|
807
|
+
--
|
|
808
|
+
}
|
|
809
|
+
opts.on("-l", "--line-numbers", "Show line numbers.") do |line|
|
|
810
|
+
options[:l] = true
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
|
|
814
|
+
options[:f] = true
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
opts.on_tail("-h", "--help", "This message.") do
|
|
818
|
+
output.puts opts
|
|
819
|
+
options[:h] = true
|
|
820
|
+
end
|
|
821
|
+
end.order(args) do |v|
|
|
822
|
+
command_name = v
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
next if options[:h]
|
|
826
|
+
|
|
590
827
|
if !command_name
|
|
591
828
|
output.puts "You must provide a command name."
|
|
592
829
|
next
|
|
593
830
|
end
|
|
594
|
-
|
|
831
|
+
|
|
595
832
|
if commands[command_name]
|
|
596
833
|
meth = commands[command_name][:action]
|
|
597
834
|
|
|
598
|
-
code = meth.source
|
|
835
|
+
code = strip_leading_whitespace(meth.source)
|
|
599
836
|
file, line = meth.source_location
|
|
600
|
-
|
|
837
|
+
set_file_and_dir_locals(file)
|
|
838
|
+
check_for_dynamically_defined_method(meth)
|
|
601
839
|
|
|
602
|
-
output.puts
|
|
840
|
+
output.puts make_header(meth, :ruby, code)
|
|
603
841
|
|
|
604
842
|
if Pry.color
|
|
605
843
|
code = CodeRay.scan(code, :ruby).term
|
|
606
844
|
end
|
|
607
845
|
|
|
608
|
-
|
|
846
|
+
render_output(options[:f], options[:l] ? meth.source_location.last : false, code)
|
|
609
847
|
code
|
|
610
848
|
else
|
|
611
849
|
output.puts "No such command: #{command_name}."
|
|
612
850
|
end
|
|
613
851
|
end
|
|
614
|
-
|
|
852
|
+
|
|
615
853
|
command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
|
|
616
854
|
break_level = break_level.to_i
|
|
617
855
|
nesting = opts[:nesting]
|
|
@@ -627,8 +865,8 @@ e.g: show-method hello_method
|
|
|
627
865
|
end
|
|
628
866
|
end
|
|
629
867
|
|
|
630
|
-
command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
|
|
631
|
-
str = remove_first_word
|
|
868
|
+
command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
|
|
869
|
+
str = remove_first_word(opts[:val])
|
|
632
870
|
throw(:breakout, [opts[:nesting].level, target.eval(str)])
|
|
633
871
|
end
|
|
634
872
|
|
|
@@ -668,11 +906,11 @@ Is absorbed, not refracted, by grey stone.
|
|
|
668
906
|
The dahlias sleep in the empty silence.
|
|
669
907
|
Wait for the early owl.
|
|
670
908
|
-- T.S Eliot
|
|
671
|
-
}
|
|
909
|
+
}
|
|
672
910
|
output.puts text
|
|
673
911
|
text
|
|
674
912
|
end
|
|
675
|
-
|
|
913
|
+
|
|
676
914
|
command "cohen-poem", "" do
|
|
677
915
|
text = %{
|
|
678
916
|
--
|
|
@@ -690,7 +928,7 @@ and so small between the thin pines
|
|
|
690
928
|
on these enormous landscapes,
|
|
691
929
|
that if you turn your head
|
|
692
930
|
they are lost for hours.
|
|
693
|
-
-- Leonard Cohen
|
|
931
|
+
-- Leonard Cohen
|
|
694
932
|
}
|
|
695
933
|
output.puts text
|
|
696
934
|
text
|