pry 0.8.3-java → 0.8.4pre1-java
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/.document +2 -0
- data/.gitignore +8 -0
- data/.yardopts +1 -0
- data/README.markdown +10 -6
- data/Rakefile +15 -23
- data/TODO +62 -0
- data/bin/pry +3 -1
- data/lib/pry.rb +6 -7
- data/lib/pry/command_context.rb +29 -0
- data/lib/pry/command_processor.rb +15 -28
- data/lib/pry/command_set.rb +234 -0
- data/lib/pry/commands.rb +15 -861
- data/lib/pry/core_extensions.rb +40 -48
- data/lib/pry/default_commands/context.rb +127 -0
- data/lib/pry/default_commands/documentation.rb +145 -0
- data/lib/pry/default_commands/easter_eggs.rb +71 -0
- data/lib/pry/default_commands/gems.rb +59 -0
- data/lib/pry/default_commands/input.rb +38 -0
- data/lib/pry/default_commands/introspection.rb +190 -0
- data/lib/pry/default_commands/ls.rb +199 -0
- data/lib/pry/default_commands/shell.rb +90 -0
- data/lib/pry/helpers.rb +2 -0
- data/lib/pry/{command_base_helpers.rb → helpers/base_helpers.rb} +46 -21
- data/lib/pry/{command_helpers.rb → helpers/command_helpers.rb} +34 -36
- data/lib/pry/pry_class.rb +17 -11
- data/lib/pry/pry_instance.rb +59 -2
- data/lib/pry/version.rb +1 -1
- data/test/{test_helper.rb → helper.rb} +8 -2
- data/test/test_command_helpers.rb +77 -0
- data/test/test_commandset.rb +184 -0
- data/test/{test.rb → test_pry.rb} +164 -132
- data/wiki/Customizing-pry.md +397 -0
- data/wiki/Home.md +4 -0
- metadata +61 -41
- data/lib/pry/command_base.rb +0 -202
data/lib/pry/commands.rb
CHANGED
@@ -1,257 +1,23 @@
|
|
1
|
-
require "
|
2
|
-
require "
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require "pry/
|
6
|
-
require "pry/
|
7
|
-
require "pry/
|
1
|
+
require "pry/default_commands/documentation"
|
2
|
+
require "pry/default_commands/gems"
|
3
|
+
require "pry/default_commands/context"
|
4
|
+
require "pry/default_commands/input"
|
5
|
+
require "pry/default_commands/shell"
|
6
|
+
require "pry/default_commands/introspection"
|
7
|
+
require "pry/default_commands/easter_eggs"
|
8
8
|
|
9
9
|
class Pry
|
10
10
|
|
11
11
|
# Default commands used by Pry.
|
12
|
-
|
13
|
-
|
12
|
+
Commands = Pry::CommandSet.new :default do
|
13
|
+
import DefaultCommands::Documentation
|
14
|
+
import DefaultCommands::Gems
|
15
|
+
import DefaultCommands::Context
|
16
|
+
import DefaultCommands::Input, DefaultCommands::Shell
|
17
|
+
import DefaultCommands::Introspection
|
18
|
+
import DefaultCommands::EasterEggs
|
14
19
|
|
15
|
-
try_to_load_pry_doc
|
16
|
-
|
17
|
-
command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
|
18
|
-
output.puts "Input buffer cleared!"
|
19
|
-
opts[:eval_string].clear
|
20
|
-
end
|
21
|
-
|
22
|
-
command "!pry", "Start a Pry session on current self; this even works mid-expression." do
|
23
|
-
Pry.start(target)
|
24
|
-
end
|
25
|
-
|
26
|
-
# this cannot be accessed, it's just for help purposes.
|
27
|
-
command ".<shell command>", "All text following a '.' is forwarded to the shell." do
|
28
|
-
end
|
29
|
-
|
30
|
-
command "hist", "Show and replay Readline history. Type `hist --help` for more info." do |*args|
|
31
|
-
hist_array = Readline::HISTORY.to_a
|
32
|
-
|
33
|
-
if args.empty?
|
34
|
-
text = add_line_numbers(hist_array.join("\n"), 0)
|
35
|
-
stagger_output(text)
|
36
|
-
next
|
37
|
-
end
|
38
|
-
|
39
|
-
opts = Slop.parse(args) do |opt|
|
40
|
-
opt.banner "Usage: hist [--replay START..END]\nView and replay history\ne.g hist --replay 2..8"
|
41
|
-
opt.on :r, :replay, 'The line (or range of lines) to replay.', true, :as => Range
|
42
|
-
opt.on :h, :help, 'Show this message.', :tail => true do
|
43
|
-
output.puts opt.help
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
next if opts.h?
|
48
|
-
|
49
|
-
actions = Array(hist_array[opts[:replay]]).join("\n") + "\n"
|
50
|
-
Pry.active_instance.input = StringIO.new(actions)
|
51
|
-
end
|
52
|
-
|
53
|
-
command "edit-method", "Edit a method. Type `edit-method --help` for more info." do |*args|
|
54
|
-
target = target()
|
55
|
-
|
56
|
-
opts = Slop.parse!(args) do |opts|
|
57
|
-
opts.banner %{Usage: edit-method [OPTIONS] [METH]
|
58
|
-
Edit the method METH in an editor.
|
59
|
-
Ensure #{bold("Pry.editor")} is set to your editor of choice.
|
60
|
-
e.g: edit-method hello_method
|
61
|
-
--
|
62
|
-
}
|
63
|
-
opts.on :M, "instance-methods", "Operate on instance methods."
|
64
|
-
opts.on :m, :methods, "Operate on methods."
|
65
|
-
opts.on "no-reload", "Do not automatically reload the method's file after editting."
|
66
|
-
opts.on :c, :context, "Select object context to run under.", true do |context|
|
67
|
-
target = Pry.binding_for(target.eval(context))
|
68
|
-
end
|
69
|
-
opts.on :h, :help, "This message." do
|
70
|
-
output.puts opts
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
next if opts.help?
|
75
|
-
|
76
|
-
meth_name = args.shift
|
77
|
-
if meth_name
|
78
|
-
if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context?
|
79
|
-
context, meth_name = $1, $2
|
80
|
-
target = Pry.binding_for(target.eval(context))
|
81
|
-
end
|
82
|
-
else
|
83
|
-
meth_name = meth_name_from_binding(target)
|
84
|
-
end
|
85
|
-
|
86
|
-
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
87
|
-
output.puts "Invalid method name: #{meth_name}."
|
88
|
-
next
|
89
|
-
end
|
90
|
-
|
91
|
-
next output.puts "Error: No editor set!\nEnsure that #{bold("Pry.editor")} is set to your editor of choice." if !Pry.editor
|
92
|
-
|
93
|
-
if is_a_c_method?(meth)
|
94
|
-
output.puts "Error: Can't edit a C method."
|
95
|
-
elsif is_a_dynamically_defined_method?(meth)
|
96
|
-
output.puts "Error: Can't edit an eval method."
|
97
|
-
else
|
98
|
-
file, line = meth.source_location
|
99
|
-
run ".#{editor_with_start_line(line)}", file
|
100
|
-
load file if !opts["no-reload"]
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
command "exit-program", "End the current program. Aliases: quit-program, !!!" do
|
105
|
-
exit
|
106
|
-
end
|
107
|
-
|
108
|
-
alias_command "quit-program", "exit-program", ""
|
109
|
-
alias_command "!!!", "exit-program", ""
|
110
|
-
|
111
|
-
command "gem-install", "Install a gem and refresh the gem cache." do |gem_name|
|
112
|
-
gem_home = Gem.instance_variable_get(:@gem_home)
|
113
|
-
output.puts "Attempting to install gem: #{bold(gem_name)}"
|
114
|
-
|
115
|
-
begin
|
116
|
-
if File.writable?(gem_home)
|
117
|
-
Gem::DependencyInstaller.new.install(gem_name)
|
118
|
-
output.puts "Gem #{bold(gem_name)} successfully installed."
|
119
|
-
else
|
120
|
-
if system("sudo gem install #{gem_name}")
|
121
|
-
output.puts "Gem #{bold(gem_name)} successfully installed."
|
122
|
-
else
|
123
|
-
output.puts "Gem #{bold(gem_name)} could not be installed."
|
124
|
-
next
|
125
|
-
end
|
126
|
-
end
|
127
|
-
rescue Gem::GemNotFoundException
|
128
|
-
output.puts "Required Gem: #{bold(gem_name)} not found."
|
129
|
-
next
|
130
|
-
end
|
131
|
-
|
132
|
-
Gem.refresh
|
133
|
-
output.puts "Refreshed gem cache."
|
134
|
-
end
|
135
|
-
|
136
|
-
command "ri", "View ri documentation. e.g `ri Array#each`" do |*args|
|
137
|
-
run ".ri", *args
|
138
|
-
end
|
139
|
-
|
140
|
-
command "stat", "View method information and set _file_ and _dir_ locals. Type `stat --help` for more info." do |*args|
|
141
|
-
target = target()
|
142
|
-
|
143
|
-
opts = Slop.parse!(args) do |opts|
|
144
|
-
opts.banner %{Usage: stat [OPTIONS] [METH]
|
145
|
-
Show method information for method METH and set _file_ and _dir_ locals.
|
146
|
-
e.g: stat hello_method
|
147
|
-
--
|
148
|
-
}
|
149
|
-
opts.on :M, "instance-methods", "Operate on instance methods."
|
150
|
-
opts.on :m, :methods, "Operate on methods."
|
151
|
-
opts.on :c, :context, "Select object context to run under.", true do |context|
|
152
|
-
target = Pry.binding_for(target.eval(context))
|
153
|
-
end
|
154
|
-
opts.on :h, :help, "This message" do
|
155
|
-
output.puts opts
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
next if opts.help?
|
160
|
-
|
161
|
-
meth_name = args.shift
|
162
|
-
if meth_name
|
163
|
-
if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context?
|
164
|
-
context, meth_name = $1, $2
|
165
|
-
target = Pry.binding_for(target.eval(context))
|
166
|
-
end
|
167
|
-
else
|
168
|
-
meth_name = meth_name_from_binding(target)
|
169
|
-
end
|
170
|
-
|
171
|
-
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
172
|
-
output.puts "Invalid method name: #{meth_name}. Type `stat --help` for help"
|
173
|
-
next
|
174
|
-
end
|
175
|
-
|
176
|
-
code, code_type = code_and_code_type_for(meth)
|
177
|
-
next if !code
|
178
|
-
doc, code_type = doc_and_code_type_for(meth)
|
179
|
-
|
180
|
-
output.puts make_header(meth, code_type, code)
|
181
|
-
output.puts bold("Method Name: ") + meth_name
|
182
|
-
output.puts bold("Method Owner: ") + (meth.owner.to_s ? meth.owner.to_s : "Unknown")
|
183
|
-
output.puts bold("Method Language: ") + code_type.to_s.capitalize
|
184
|
-
output.puts bold("Method Type: ") + (meth.is_a?(Method) ? "Bound" : "Unbound")
|
185
|
-
output.puts bold("Method Arity: ") + meth.arity.to_s
|
186
|
-
|
187
|
-
name_map = { :req => "Required:", :opt => "Optional:", :rest => "Rest:" }
|
188
|
-
if meth.respond_to?(:parameters)
|
189
|
-
output.puts bold("Method Parameters: ") + meth.parameters.group_by(&:first).
|
190
|
-
map { |k, v| "#{name_map[k]} #{v.map { |kk, vv| vv ? vv.to_s : "noname" }.join(", ")}" }.join(". ")
|
191
|
-
end
|
192
|
-
output.puts bold("Comment length: ") + (doc.empty? ? 'No comment.' : (doc.lines.count.to_s + ' lines.'))
|
193
|
-
end
|
194
|
-
|
195
|
-
command "gist-method", "Gist a method to github. Type `gist-method --help` for more info.", :requires_gem => "gist" do |*args|
|
196
|
-
target = target()
|
197
|
-
|
198
|
-
opts = Slop.parse!(args) do |opts|
|
199
|
-
opts.banner = %{Usage: gist-method [OPTIONS] [METH]
|
200
|
-
Gist the method (doc or source) to github.
|
201
|
-
Ensure the `gist` gem is properly working before use. http://github.com/defunkt/gist for instructions.
|
202
|
-
e.g: gist -m my_method
|
203
|
-
e.g: gist -d my_method
|
204
|
-
--
|
205
|
-
}
|
206
|
-
opts.on :m, :method, "Gist a method's source."
|
207
|
-
opts.on :d, :doc, "Gist a method's documentation."
|
208
|
-
opts.on :p, :private, "Create a private gist (default: true)", :default => true
|
209
|
-
opts.on :h, :help, "This message" do
|
210
|
-
output.puts opts
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
next if opts.help?
|
215
|
-
|
216
|
-
# This needs to be extracted into its own method as it's shared
|
217
|
-
# by show-method and show-doc and stat commands
|
218
|
-
meth_name = args.shift
|
219
|
-
if meth_name
|
220
|
-
if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/
|
221
|
-
context, meth_name = $1, $2
|
222
|
-
target = Pry.binding_for(target.eval(context))
|
223
|
-
end
|
224
|
-
else
|
225
|
-
meth_name = meth_name_from_binding(target)
|
226
|
-
end
|
227
|
-
|
228
|
-
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
229
|
-
output.puts "Invalid method name: #{meth_name}. Type `gist-method --help` for help"
|
230
|
-
next
|
231
|
-
end
|
232
|
-
|
233
|
-
type_map = { :ruby => "rb", :c => "c", :plain => "plain" }
|
234
|
-
if !opts.doc?
|
235
|
-
content, code_type = code_and_code_type_for(meth)
|
236
|
-
else
|
237
|
-
content, code_type = doc_and_code_type_for(meth)
|
238
|
-
no_color do
|
239
|
-
content = process_comment_markup(content, code_type)
|
240
|
-
end
|
241
|
-
code_type = :plain
|
242
|
-
end
|
243
|
-
|
244
|
-
IO.popen("gist#{' -p' if opts.p?} -t #{type_map[code_type]} -", "w") do |gist|
|
245
|
-
gist.puts content
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
command "gem-cd", "Change working directory to specified gem's directory." do |gem_name|
|
250
|
-
require 'rubygems'
|
251
|
-
gem_spec = Gem.source_index.find_name(gem_name).first
|
252
|
-
next output.puts("Gem `#{gem_name}` not found.") if !gem_spec
|
253
|
-
Dir.chdir(File.expand_path(gem_spec.full_gem_path))
|
254
|
-
end
|
20
|
+
Helpers::CommandHelpers.try_to_load_pry_doc
|
255
21
|
|
256
22
|
command "toggle-color", "Toggle syntax highlighting." do
|
257
23
|
Pry.color = !Pry.color
|
@@ -267,35 +33,6 @@ e.g: gist -d my_method
|
|
267
33
|
end
|
268
34
|
end
|
269
35
|
|
270
|
-
command "shell-mode", "Toggle shell mode. Bring in pwd prompt and file completion." do
|
271
|
-
case Pry.active_instance.prompt
|
272
|
-
when Pry::SHELL_PROMPT
|
273
|
-
Pry.active_instance.prompt = Pry::DEFAULT_PROMPT
|
274
|
-
Pry.active_instance.custom_completions = Pry::DEFAULT_CUSTOM_COMPLETIONS
|
275
|
-
else
|
276
|
-
Pry.active_instance.prompt = Pry::SHELL_PROMPT
|
277
|
-
Pry.active_instance.custom_completions = Pry::FILE_COMPLETIONS
|
278
|
-
Readline.completion_proc = Pry::InputCompleter.build_completion_proc target,
|
279
|
-
Pry.active_instance.instance_eval(&Pry::FILE_COMPLETIONS)
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
alias_command "file-mode", "shell-mode", ""
|
284
|
-
|
285
|
-
command "nesting", "Show nesting information." do
|
286
|
-
nesting = opts[:nesting]
|
287
|
-
|
288
|
-
output.puts "Nesting status:"
|
289
|
-
output.puts "--"
|
290
|
-
nesting.each do |level, obj|
|
291
|
-
if level == 0
|
292
|
-
output.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)"
|
293
|
-
else
|
294
|
-
output.puts "#{level}. #{Pry.view_clip(obj)}"
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
36
|
command "status", "Show status information." do
|
300
37
|
nesting = opts[:nesting]
|
301
38
|
|
@@ -338,271 +75,10 @@ e.g: gist -d my_method
|
|
338
75
|
end # gems.each
|
339
76
|
end
|
340
77
|
|
341
|
-
|
342
|
-
command "gem-list", "List/search installed gems. (Optional parameter: a regexp to limit the search)" do |arg|
|
343
|
-
gems = Gem.source_index.gems.values.group_by(&:name)
|
344
|
-
if arg
|
345
|
-
query = Regexp.new(arg, Regexp::IGNORECASE)
|
346
|
-
gems = gems.select { |gemname, specs| gemname =~ query }
|
347
|
-
end
|
348
|
-
|
349
|
-
gems.each do |gemname, specs|
|
350
|
-
versions = specs.map(&:version).sort.reverse.map(&:to_s)
|
351
|
-
versions = ["<bright_green>#{versions.first}</bright_green>"] +
|
352
|
-
versions[1..-1].map{|v| "<green>#{v}</green>" }
|
353
|
-
|
354
|
-
gemname = highlight(gemname, query) if query
|
355
|
-
result = "<white>#{gemname} <grey>(#{versions.join ', '})</grey>"
|
356
|
-
output.puts colorize(result)
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
|
361
|
-
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|
|
362
|
-
file = target.eval('__FILE__')
|
363
|
-
line_num = target.eval('__LINE__')
|
364
|
-
klass = target.eval('self.class')
|
365
|
-
|
366
|
-
if num
|
367
|
-
i_num = num.to_i
|
368
|
-
else
|
369
|
-
i_num = 5
|
370
|
-
end
|
371
|
-
|
372
|
-
meth_name = meth_name_from_binding(target)
|
373
|
-
meth_name = "N/A" if !meth_name
|
374
|
-
|
375
|
-
if file =~ /(\(.*\))|<.*>/ || file == "" || file == "-e"
|
376
|
-
output.puts "Cannot find local context. Did you use `binding.pry` ?"
|
377
|
-
next
|
378
|
-
end
|
379
|
-
|
380
|
-
set_file_and_dir_locals(file)
|
381
|
-
output.puts "\n#{bold('From:')} #{file} @ line #{line_num} in #{klass}##{meth_name}:\n\n"
|
382
|
-
|
383
|
-
# This method inspired by http://rubygems.org/gems/ir_b
|
384
|
-
File.open(file).each_with_index do |line, index|
|
385
|
-
line_n = index + 1
|
386
|
-
next unless line_n > (line_num - i_num - 1)
|
387
|
-
break if line_n > (line_num + i_num)
|
388
|
-
if line_n == line_num
|
389
|
-
code =" =>#{line_n.to_s.rjust(3)}: #{line.chomp}"
|
390
|
-
if Pry.color
|
391
|
-
code = CodeRay.scan(code, :ruby).term
|
392
|
-
end
|
393
|
-
output.puts code
|
394
|
-
code
|
395
|
-
else
|
396
|
-
code = "#{line_n.to_s.rjust(6)}: #{line.chomp}"
|
397
|
-
if Pry.color
|
398
|
-
code = CodeRay.scan(code, :ruby).term
|
399
|
-
end
|
400
|
-
output.puts code
|
401
|
-
code
|
402
|
-
end
|
403
|
-
end
|
404
|
-
end
|
405
|
-
|
406
78
|
command "version", "Show Pry version." do
|
407
79
|
output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}."
|
408
80
|
end
|
409
81
|
|
410
|
-
command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !!@" do
|
411
|
-
str = remove_first_word(opts[:val])
|
412
|
-
throw(:breakout, [0, target.eval(str)])
|
413
|
-
end
|
414
|
-
|
415
|
-
alias_command "!!@", "exit-all", ""
|
416
|
-
|
417
|
-
command "ls", "Show the list of vars and methods in the current scope. Type `ls --help` for more info." do |*args|
|
418
|
-
options = {}
|
419
|
-
# Set target local to the default -- note that we can set a different target for
|
420
|
-
# ls if we like: e.g ls my_var
|
421
|
-
target = target()
|
422
|
-
|
423
|
-
OptionParser.new do |opts|
|
424
|
-
opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\
|
425
|
-
List information about VAR (the current context by default).
|
426
|
-
Shows local and instance variables by default.
|
427
|
-
--
|
428
|
-
}
|
429
|
-
opts.on("-g", "--globals", "Display global variables.") do
|
430
|
-
options[:g] = true
|
431
|
-
end
|
432
|
-
|
433
|
-
opts.on("-c", "--constants", "Display constants.") do
|
434
|
-
options[:c] = true
|
435
|
-
end
|
436
|
-
|
437
|
-
opts.on("-l", "--locals", "Display locals.") do
|
438
|
-
options[:l] = true
|
439
|
-
end
|
440
|
-
|
441
|
-
opts.on("-i", "--ivars", "Display instance variables.") do
|
442
|
-
options[:i] = true
|
443
|
-
end
|
444
|
-
|
445
|
-
opts.on("-k", "--class-vars", "Display class variables.") do
|
446
|
-
options[:k] = true
|
447
|
-
end
|
448
|
-
|
449
|
-
opts.on("-m", "--methods", "Display methods (public methods by default).") do
|
450
|
-
options[:m] = true
|
451
|
-
end
|
452
|
-
|
453
|
-
opts.on("-M", "--instance-methods", "Display instance methods (only relevant to classes and modules).") do
|
454
|
-
options[:M] = true
|
455
|
-
end
|
456
|
-
|
457
|
-
opts.on("-P", "--public", "Display public methods (with -m).") do
|
458
|
-
options[:P] = true
|
459
|
-
end
|
460
|
-
|
461
|
-
opts.on("-r", "--protected", "Display protected methods (with -m).") do
|
462
|
-
options[:r] = true
|
463
|
-
end
|
464
|
-
|
465
|
-
opts.on("-p", "--private", "Display private methods (with -m).") do
|
466
|
-
options[:p] = true
|
467
|
-
end
|
468
|
-
|
469
|
-
opts.on("-j", "--just-singletons", "Display just the singleton methods (with -m).") do
|
470
|
-
options[:j] = true
|
471
|
-
end
|
472
|
-
|
473
|
-
opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
|
474
|
-
options[:s] = true
|
475
|
-
end
|
476
|
-
|
477
|
-
opts.on("-a", "--all", "Display all types of entries.") do
|
478
|
-
options[:a] = true
|
479
|
-
end
|
480
|
-
|
481
|
-
opts.on("-v", "--verbose", "Verbose ouput.") do
|
482
|
-
options[:v] = true
|
483
|
-
end
|
484
|
-
|
485
|
-
opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
|
486
|
-
options[:f] = true
|
487
|
-
end
|
488
|
-
|
489
|
-
opts.on("--grep REG", "Regular expression to be used.") do |reg|
|
490
|
-
options[:grep] = Regexp.new(reg)
|
491
|
-
end
|
492
|
-
|
493
|
-
opts.on_tail("-h", "--help", "Show this message.") do
|
494
|
-
output.puts opts
|
495
|
-
options[:h] = true
|
496
|
-
end
|
497
|
-
end.order(args) do |new_target|
|
498
|
-
target = Pry.binding_for(target.eval("#{new_target}")) if !options[:h]
|
499
|
-
end
|
500
|
-
|
501
|
-
# exit if we've displayed help
|
502
|
-
next if options[:h]
|
503
|
-
|
504
|
-
# default is locals/ivars/class vars.
|
505
|
-
# Only occurs when no options or when only option is verbose
|
506
|
-
options.merge!({
|
507
|
-
:l => true,
|
508
|
-
:i => true,
|
509
|
-
:k => true
|
510
|
-
}) if options.empty? || (options.size == 1 && options[:v]) || (options.size == 1 && options[:grep])
|
511
|
-
|
512
|
-
options[:grep] = // if !options[:grep]
|
513
|
-
|
514
|
-
|
515
|
-
# Display public methods by default if -m or -M switch is used.
|
516
|
-
options[:P] = true if (options[:m] || options[:M]) && !(options[:p] || options[:r] || options[:j])
|
517
|
-
|
518
|
-
info = {}
|
519
|
-
target_self = target.eval('self')
|
520
|
-
|
521
|
-
# ensure we have a real boolean and not a `nil` (important when
|
522
|
-
# interpolating in the string)
|
523
|
-
options[:s] = !!options[:s]
|
524
|
-
|
525
|
-
# Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8
|
526
|
-
i = -1
|
527
|
-
|
528
|
-
# Start collecting the entries selected by the user
|
529
|
-
info["local variables"] = [Array(target.eval("local_variables")).sort, i += 1] if options[:l] || options[:a]
|
530
|
-
info["instance variables"] = [Array(target.eval("instance_variables")).sort, i += 1] if options[:i] || options[:a]
|
531
|
-
|
532
|
-
info["class variables"] = [if target_self.is_a?(Module)
|
533
|
-
Array(target.eval("class_variables")).sort
|
534
|
-
else
|
535
|
-
Array(target.eval("self.class.class_variables")).sort
|
536
|
-
end, i += 1] if options[:k] || options[:a]
|
537
|
-
|
538
|
-
info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a]
|
539
|
-
|
540
|
-
info["public methods"] = [Array(target.eval("public_methods(#{options[:s]})")).uniq.sort, i += 1] if (options[:m] && options[:P]) || options[:a]
|
541
|
-
|
542
|
-
info["protected methods"] = [Array(target.eval("protected_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:r]) || options[:a]
|
543
|
-
|
544
|
-
info["private methods"] = [Array(target.eval("private_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:p]) || options[:a]
|
545
|
-
|
546
|
-
info["just singleton methods"] = [Array(target.eval("methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:j]) || options[:a]
|
547
|
-
|
548
|
-
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])
|
549
|
-
|
550
|
-
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])
|
551
|
-
|
552
|
-
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])
|
553
|
-
|
554
|
-
# dealing with 1.8/1.9 compatibility issues :/
|
555
|
-
csuper = options[:s]
|
556
|
-
if Module.method(:constants).arity == 0
|
557
|
-
csuper = nil
|
558
|
-
end
|
559
|
-
|
560
|
-
info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") :
|
561
|
-
target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a]
|
562
|
-
|
563
|
-
text = ""
|
564
|
-
|
565
|
-
# verbose output?
|
566
|
-
if options[:v]
|
567
|
-
# verbose
|
568
|
-
|
569
|
-
info.sort_by { |k, v| v.last }.each do |k, v|
|
570
|
-
if !v.first.empty?
|
571
|
-
text << "#{k}:\n--\n"
|
572
|
-
filtered_list = v.first.grep options[:grep]
|
573
|
-
if Pry.color
|
574
|
-
text << CodeRay.scan(Pry.view(filtered_list), :ruby).term + "\n"
|
575
|
-
else
|
576
|
-
text << Pry.view(filtered_list) + "\n"
|
577
|
-
end
|
578
|
-
text << "\n\n"
|
579
|
-
end
|
580
|
-
end
|
581
|
-
|
582
|
-
if !options[:f]
|
583
|
-
stagger_output(text)
|
584
|
-
else
|
585
|
-
output.puts text
|
586
|
-
end
|
587
|
-
|
588
|
-
# plain
|
589
|
-
else
|
590
|
-
list = info.values.sort_by(&:last).map(&:first).inject(&:+)
|
591
|
-
list = list.grep(options[:grep]) if list
|
592
|
-
list.uniq! if list
|
593
|
-
if Pry.color
|
594
|
-
text << CodeRay.scan(Pry.view(list), :ruby).term + "\n"
|
595
|
-
else
|
596
|
-
text << Pry.view(list) + "\n"
|
597
|
-
end
|
598
|
-
if !options[:f]
|
599
|
-
stagger_output(text)
|
600
|
-
else
|
601
|
-
output.puts text
|
602
|
-
end
|
603
|
-
list
|
604
|
-
end
|
605
|
-
end
|
606
82
|
|
607
83
|
command "lls", "List local files using 'ls'" do |*args|
|
608
84
|
cmd = ".ls"
|
@@ -613,64 +89,6 @@ Shows local and instance variables by default.
|
|
613
89
|
run ".cd", *args
|
614
90
|
end
|
615
91
|
|
616
|
-
command "cat", "Show output of file FILE. Type `cat --help` for more information." do |*args|
|
617
|
-
options= {}
|
618
|
-
file_name = nil
|
619
|
-
start_line = 0
|
620
|
-
end_line = -1
|
621
|
-
file_type = nil
|
622
|
-
|
623
|
-
OptionParser.new do |opts|
|
624
|
-
opts.banner = %{Usage: cat [OPTIONS] FILE
|
625
|
-
Cat a file. Defaults to displaying whole file. Syntax highlights file if type is recognized.
|
626
|
-
e.g: cat hello.rb
|
627
|
-
--
|
628
|
-
}
|
629
|
-
opts.on("-l", "--line-numbers", "Show line numbers.") do |line|
|
630
|
-
options[:l] = true
|
631
|
-
end
|
632
|
-
|
633
|
-
opts.on("-s", "--start LINE", "Start line (defaults to start of file). Line 1 is the first line.") do |line|
|
634
|
-
start_line = line.to_i - 1
|
635
|
-
end
|
636
|
-
|
637
|
-
opts.on("-e", "--end LINE", "End line (defaults to end of file). Line -1 is the last line.") do |line|
|
638
|
-
end_line = line.to_i - 1
|
639
|
-
end
|
640
|
-
|
641
|
-
opts.on("-t", "--type TYPE", "The specific file type for syntax higlighting (e.g ruby, python, cpp, java)") do |type|
|
642
|
-
file_type = type.to_sym
|
643
|
-
end
|
644
|
-
|
645
|
-
opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
|
646
|
-
options[:f] = true
|
647
|
-
end
|
648
|
-
|
649
|
-
opts.on_tail("-h", "--help", "This message.") do
|
650
|
-
output.puts opts
|
651
|
-
options[:h] = true
|
652
|
-
end
|
653
|
-
end.order(args) do |v|
|
654
|
-
file_name = v
|
655
|
-
end
|
656
|
-
|
657
|
-
next if options[:h]
|
658
|
-
|
659
|
-
if !file_name
|
660
|
-
output.puts "Must provide a file name."
|
661
|
-
next
|
662
|
-
end
|
663
|
-
|
664
|
-
contents, normalized_start_line, _ = read_between_the_lines(file_name, start_line, end_line)
|
665
|
-
|
666
|
-
if Pry.color
|
667
|
-
contents = syntax_highlight_by_file_type_or_specified(contents, file_name, file_type)
|
668
|
-
end
|
669
|
-
|
670
|
-
set_file_and_dir_locals(file_name)
|
671
|
-
render_output(options[:f], options[:l] ? normalized_start_line + 1 : false, contents)
|
672
|
-
contents
|
673
|
-
end
|
674
92
|
|
675
93
|
command "eval-file", "Eval a Ruby script. Type `eval-file --help` for more info." do |*args|
|
676
94
|
options = {}
|
@@ -718,269 +136,5 @@ e.g: eval-file -c self "hello.rb"
|
|
718
136
|
output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty?
|
719
137
|
end
|
720
138
|
|
721
|
-
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|
|
722
|
-
if !obj
|
723
|
-
output.puts "Must provide an object."
|
724
|
-
next
|
725
|
-
end
|
726
|
-
|
727
|
-
throw(:breakout, opts[:nesting].level) if obj == ".."
|
728
|
-
|
729
|
-
if obj == "/"
|
730
|
-
throw(:breakout, 1) if opts[:nesting].level > 0
|
731
|
-
next
|
732
|
-
end
|
733
|
-
|
734
|
-
Pry.start target.eval("#{obj}")
|
735
|
-
end
|
736
|
-
|
737
|
-
command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info. Aliases: \?" do |*args|
|
738
|
-
target = target()
|
739
|
-
|
740
|
-
opts = Slop.parse!(args) do |opts|
|
741
|
-
opts.banner %{Usage: show-doc [OPTIONS] [METH]
|
742
|
-
Show the comments above method METH. Tries instance methods first and then methods by default.
|
743
|
-
e.g show-doc hello_method
|
744
|
-
--
|
745
|
-
}
|
746
|
-
opts.on :M, "instance-methods", "Operate on instance methods."
|
747
|
-
opts.on :m, :methods, "Operate on methods."
|
748
|
-
opts.on :c, :context, "Select object context to run under.", true do |context|
|
749
|
-
target = Pry.binding_for(target.eval(context))
|
750
|
-
end
|
751
|
-
opts.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
752
|
-
opts.on :h, :help, "This message." do
|
753
|
-
output.puts opts
|
754
|
-
end
|
755
|
-
end
|
756
|
-
|
757
|
-
next if opts.help?
|
758
|
-
|
759
|
-
meth_name = args.shift
|
760
|
-
if meth_name
|
761
|
-
if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context?
|
762
|
-
context, meth_name = $1, $2
|
763
|
-
target = Pry.binding_for(target.eval(context))
|
764
|
-
end
|
765
|
-
else
|
766
|
-
meth_name = meth_name_from_binding(target)
|
767
|
-
end
|
768
|
-
|
769
|
-
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
770
|
-
output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
|
771
|
-
next
|
772
|
-
end
|
773
|
-
|
774
|
-
doc, code_type = doc_and_code_type_for(meth)
|
775
|
-
next if !doc
|
776
|
-
|
777
|
-
next output.puts("No documentation found.") if doc.empty?
|
778
|
-
|
779
|
-
doc = process_comment_markup(doc, code_type)
|
780
|
-
|
781
|
-
output.puts make_header(meth, code_type, doc)
|
782
|
-
|
783
|
-
render_output(opts.flood?, false, doc)
|
784
|
-
doc
|
785
|
-
end
|
786
|
-
|
787
|
-
alias_command "?", "show-doc", ""
|
788
|
-
|
789
|
-
command "show-method", "Show the source for METH. Type `show-method --help` for more info. Aliases: $, show-source" do |*args|
|
790
|
-
target = target()
|
791
|
-
|
792
|
-
opts = Slop.parse!(args) do |opts|
|
793
|
-
opts.banner %{Usage: show-method [OPTIONS] [METH]
|
794
|
-
Show the source for method METH. Tries instance methods first and then methods by default.
|
795
|
-
e.g: show-method hello_method
|
796
|
-
--
|
797
|
-
}
|
798
|
-
opts.on :l, "line-numbers", "Show line numbers."
|
799
|
-
opts.on :M, "instance-methods", "Operate on instance methods."
|
800
|
-
opts.on :m, :methods, "Operate on methods."
|
801
|
-
opts.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
802
|
-
opts.on :c, :context, "Select object context to run under.", true do |context|
|
803
|
-
target = Pry.binding_for(target.eval(context))
|
804
|
-
end
|
805
|
-
opts.on :h, :help, "This message." do
|
806
|
-
output.puts opts
|
807
|
-
end
|
808
|
-
end
|
809
|
-
|
810
|
-
next if opts.help?
|
811
|
-
|
812
|
-
meth_name = args.shift
|
813
|
-
if meth_name
|
814
|
-
if meth_name =~ /\A([^\.\#]+)[\.\#](.+)\z/ && !opts.context?
|
815
|
-
context, meth_name = $1, $2
|
816
|
-
target = Pry.binding_for(target.eval(context))
|
817
|
-
end
|
818
|
-
else
|
819
|
-
meth_name = meth_name_from_binding(target)
|
820
|
-
end
|
821
|
-
|
822
|
-
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
823
|
-
output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
|
824
|
-
next
|
825
|
-
end
|
826
|
-
|
827
|
-
code, code_type = code_and_code_type_for(meth)
|
828
|
-
next if !code
|
829
|
-
|
830
|
-
output.puts make_header(meth, code_type, code)
|
831
|
-
if Pry.color
|
832
|
-
code = CodeRay.scan(code, code_type).term
|
833
|
-
end
|
834
|
-
|
835
|
-
start_line = false
|
836
|
-
if opts.l?
|
837
|
-
start_line = meth.source_location ? meth.source_location.last : 1
|
838
|
-
end
|
839
|
-
|
840
|
-
render_output(opts.flood?, start_line, code)
|
841
|
-
code
|
842
|
-
end
|
843
|
-
|
844
|
-
alias_command "show-source", "show-method", ""
|
845
|
-
alias_command "$", "show-method", ""
|
846
|
-
|
847
|
-
command "show-command", "Show the source for CMD. Type `show-command --help` for more info." do |*args|
|
848
|
-
options = {}
|
849
|
-
target = target()
|
850
|
-
command_name = nil
|
851
|
-
|
852
|
-
OptionParser.new do |opts|
|
853
|
-
opts.banner = %{Usage: show-command [OPTIONS] [CMD]
|
854
|
-
Show the source for command CMD.
|
855
|
-
e.g: show-command show-method
|
856
|
-
--
|
857
|
-
}
|
858
|
-
opts.on("-l", "--line-numbers", "Show line numbers.") do |line|
|
859
|
-
options[:l] = true
|
860
|
-
end
|
861
|
-
|
862
|
-
opts.on("-f", "--flood", "Do not use a pager to view text longer than one screen.") do
|
863
|
-
options[:f] = true
|
864
|
-
end
|
865
|
-
|
866
|
-
opts.on_tail("-h", "--help", "This message.") do
|
867
|
-
output.puts opts
|
868
|
-
options[:h] = true
|
869
|
-
end
|
870
|
-
end.order(args) do |v|
|
871
|
-
command_name = v
|
872
|
-
end
|
873
|
-
|
874
|
-
next if options[:h]
|
875
|
-
|
876
|
-
if !command_name
|
877
|
-
output.puts "You must provide a command name."
|
878
|
-
next
|
879
|
-
end
|
880
|
-
|
881
|
-
if commands[command_name]
|
882
|
-
meth = commands[command_name][:action]
|
883
|
-
|
884
|
-
code = strip_leading_whitespace(meth.source)
|
885
|
-
file, line = meth.source_location
|
886
|
-
set_file_and_dir_locals(file)
|
887
|
-
check_for_dynamically_defined_method(meth)
|
888
|
-
|
889
|
-
output.puts make_header(meth, :ruby, code)
|
890
|
-
|
891
|
-
if Pry.color
|
892
|
-
code = CodeRay.scan(code, :ruby).term
|
893
|
-
end
|
894
|
-
|
895
|
-
render_output(options[:f], options[:l] ? meth.source_location.last : false, code)
|
896
|
-
code
|
897
|
-
else
|
898
|
-
output.puts "No such command: #{command_name}."
|
899
|
-
end
|
900
|
-
end
|
901
|
-
|
902
|
-
command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
|
903
|
-
break_level = break_level.to_i
|
904
|
-
nesting = opts[:nesting]
|
905
|
-
|
906
|
-
case break_level
|
907
|
-
when nesting.level
|
908
|
-
output.puts "Already at nesting level #{nesting.level}"
|
909
|
-
when (0...nesting.level)
|
910
|
-
throw(:breakout, break_level + 1)
|
911
|
-
else
|
912
|
-
max_nest_level = nesting.level - 1
|
913
|
-
output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
|
914
|
-
end
|
915
|
-
end
|
916
|
-
|
917
|
-
command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
|
918
|
-
str = remove_first_word(opts[:val])
|
919
|
-
throw(:breakout, [opts[:nesting].level, target.eval(str)])
|
920
|
-
end
|
921
|
-
|
922
|
-
alias_command "quit", "exit", ""
|
923
|
-
alias_command "back", "exit", ""
|
924
|
-
|
925
|
-
command "game", "" do |highest|
|
926
|
-
highest = highest ? highest.to_i : 100
|
927
|
-
num = rand(highest)
|
928
|
-
output.puts "Guess the number between 0-#{highest}: ('.' to quit)"
|
929
|
-
count = 0
|
930
|
-
while(true)
|
931
|
-
count += 1
|
932
|
-
str = Readline.readline("game > ", true)
|
933
|
-
break if str == "." || !str
|
934
|
-
val = str.to_i
|
935
|
-
output.puts "Too large!" if val > num
|
936
|
-
output.puts "Too small!" if val < num
|
937
|
-
if val == num
|
938
|
-
output.puts "Well done! You guessed right! It took you #{count} guesses."
|
939
|
-
break
|
940
|
-
end
|
941
|
-
end
|
942
|
-
end
|
943
|
-
|
944
|
-
command "east-coker", "" do
|
945
|
-
text = %{
|
946
|
-
--
|
947
|
-
Now the light falls
|
948
|
-
Across the open field, leaving the deep lane
|
949
|
-
Shuttered with branches, dark in the afternoon,
|
950
|
-
Where you lean against a bank while a van passes,
|
951
|
-
And the deep lane insists on the direction
|
952
|
-
Into the village, in the electric heat
|
953
|
-
Hypnotised. In a warm haze the sultry light
|
954
|
-
Is absorbed, not refracted, by grey stone.
|
955
|
-
The dahlias sleep in the empty silence.
|
956
|
-
Wait for the early owl.
|
957
|
-
-- T.S Eliot
|
958
|
-
}
|
959
|
-
output.puts text
|
960
|
-
text
|
961
|
-
end
|
962
|
-
|
963
|
-
command "cohen-poem", "" do
|
964
|
-
text = %{
|
965
|
-
--
|
966
|
-
When this American woman,
|
967
|
-
whose thighs are bound in casual red cloth,
|
968
|
-
comes thundering past my sitting place
|
969
|
-
like a forest-burning Mongol tribe,
|
970
|
-
the city is ravished
|
971
|
-
and brittle buildings of a hundred years
|
972
|
-
splash into the street;
|
973
|
-
and my eyes are burnt
|
974
|
-
for the embroidered Chinese girls,
|
975
|
-
already old,
|
976
|
-
and so small between the thin pines
|
977
|
-
on these enormous landscapes,
|
978
|
-
that if you turn your head
|
979
|
-
they are lost for hours.
|
980
|
-
-- Leonard Cohen
|
981
|
-
}
|
982
|
-
output.puts text
|
983
|
-
text
|
984
|
-
end
|
985
139
|
end
|
986
140
|
end
|