2011-02-16 16:27:55 +00:00
|
|
|
require "optparse"
|
2011-02-25 02:42:17 +00:00
|
|
|
require "method_source"
|
2011-03-02 11:18:26 +00:00
|
|
|
require "pry/command_base"
|
|
|
|
require "pry/pry_instance"
|
2011-01-11 00:01:48 +00:00
|
|
|
|
2011-01-12 01:16:04 +00:00
|
|
|
class Pry
|
2011-01-18 03:40:28 +00:00
|
|
|
|
2010-12-30 15:01:11 +00:00
|
|
|
# Default commands used by Pry.
|
2011-01-12 01:16:04 +00:00
|
|
|
class Commands < CommandBase
|
2011-02-14 09:48:19 +00:00
|
|
|
|
|
|
|
# We make this a lambda to avoid documenting it
|
|
|
|
meth_name_from_binding = lambda do |b|
|
|
|
|
meth_name = b.eval('__method__')
|
2011-03-06 06:46:44 +00:00
|
|
|
|
|
|
|
# :__script__ for rubinius
|
|
|
|
if [:__script__, nil, :__binding__, :__binding_impl__].include?(meth_name)
|
2011-02-14 09:48:19 +00:00
|
|
|
nil
|
|
|
|
else
|
|
|
|
meth_name
|
|
|
|
end
|
|
|
|
end
|
2011-02-18 17:01:21 +00:00
|
|
|
|
|
|
|
check_for_dynamically_defined_method = lambda do |file|
|
|
|
|
if file =~ /(\(.*\))|<.*>/
|
|
|
|
raise "Cannot retrieve source for dynamically defined method."
|
|
|
|
end
|
|
|
|
end
|
2011-03-02 11:18:26 +00:00
|
|
|
|
|
|
|
remove_first_word = lambda do |text|
|
|
|
|
text.split.drop(1).join(' ')
|
|
|
|
end
|
2011-03-05 04:29:25 +00:00
|
|
|
|
2011-03-05 14:17:54 +00:00
|
|
|
command "whereami", "Show the code context for the session." do
|
|
|
|
file = target.eval('__FILE__')
|
|
|
|
line_num = target.eval('__LINE__')
|
|
|
|
klass = target.eval('self.class')
|
|
|
|
|
|
|
|
meth_name = meth_name_from_binding.call(target)
|
|
|
|
if !meth_name
|
|
|
|
output.puts "Cannot find containing method. Did you remember to use \`binding.pry\` ?"
|
|
|
|
next
|
|
|
|
end
|
2011-03-05 04:29:25 +00:00
|
|
|
|
2011-03-05 14:17:54 +00:00
|
|
|
check_for_dynamically_defined_method.call(file)
|
|
|
|
|
|
|
|
output.puts "--\nFrom #{file} @ line #{line_num} in #{klass}##{meth_name}:\n--"
|
|
|
|
|
|
|
|
# This method inspired by http://rubygems.org/gems/ir_b
|
2011-03-05 04:29:25 +00:00
|
|
|
File.open(file).each_with_index do |line, index|
|
|
|
|
line_n = index + 1
|
2011-03-05 14:17:54 +00:00
|
|
|
next unless line_n > (line_num - 6)
|
|
|
|
break if line_n > (line_num + 5)
|
|
|
|
if line_n == line_num
|
|
|
|
code =" =>#{line_n.to_s.rjust(3)}: #{line.chomp}"
|
|
|
|
if Pry.color
|
|
|
|
code = CodeRay.scan(code, :ruby).term
|
|
|
|
end
|
|
|
|
output.puts code
|
|
|
|
code
|
2011-03-05 04:29:25 +00:00
|
|
|
else
|
2011-03-05 14:17:54 +00:00
|
|
|
code = "#{line_n.to_s.rjust(6)}: #{line.chomp}"
|
|
|
|
if Pry.color
|
|
|
|
code = CodeRay.scan(code, :ruby).term
|
|
|
|
end
|
|
|
|
output.puts code
|
|
|
|
code
|
2011-03-05 04:29:25 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2010-12-26 13:39:46 +00:00
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
|
2011-02-13 15:49:53 +00:00
|
|
|
output.puts "Input buffer cleared!"
|
2011-01-17 14:38:09 +00:00
|
|
|
opts[:eval_string].clear
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-01-17 14:38:09 +00:00
|
|
|
command "!pry", "Start a Pry session on current self; this even works mid-expression." do
|
2011-01-20 14:41:41 +00:00
|
|
|
Pry.start(target)
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
2011-01-10 13:54:17 +00:00
|
|
|
|
2011-03-05 14:17:54 +00:00
|
|
|
command "exit-program", "End the current program. Aliases: quit-program, !!!" do
|
2011-01-17 14:38:09 +00:00
|
|
|
exit
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
alias_command "quit-program", "exit-program", ""
|
2011-03-05 14:17:54 +00:00
|
|
|
alias_command "!!!", "exit-program", ""
|
2011-02-16 16:27:55 +00:00
|
|
|
|
2011-03-02 11:18:26 +00:00
|
|
|
command "toggle-color", "Toggle syntax highlighting." do
|
|
|
|
Pry.color = !Pry.color
|
|
|
|
output.puts "Syntax highlighting #{Pry.color ? "on" : "off"}"
|
|
|
|
end
|
|
|
|
|
2011-03-03 11:50:04 +00:00
|
|
|
command "simple-prompt", "Toggle the simple prompt." do
|
2011-03-03 06:16:20 +00:00
|
|
|
case Pry.active_instance.prompt
|
|
|
|
when Pry::SIMPLE_PROMPT
|
|
|
|
Pry.active_instance.prompt = Pry::DEFAULT_PROMPT
|
|
|
|
else
|
|
|
|
Pry.active_instance.prompt = Pry::SIMPLE_PROMPT
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-01-17 14:38:09 +00:00
|
|
|
command "nesting", "Show nesting information." do
|
|
|
|
nesting = opts[:nesting]
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "Nesting status:"
|
|
|
|
output.puts "--"
|
2011-01-17 14:38:09 +00:00
|
|
|
nesting.each do |level, obj|
|
|
|
|
if level == 0
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)"
|
2011-01-17 14:38:09 +00:00
|
|
|
else
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "#{level}. #{Pry.view_clip(obj)}"
|
2010-12-26 13:39:46 +00:00
|
|
|
end
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
2010-12-26 13:39:46 +00:00
|
|
|
end
|
|
|
|
|
2011-01-17 14:38:09 +00:00
|
|
|
command "status", "Show status information." do
|
|
|
|
nesting = opts[:nesting]
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "Status:"
|
|
|
|
output.puts "--"
|
|
|
|
output.puts "Receiver: #{Pry.view_clip(target.eval('self'))}"
|
|
|
|
output.puts "Nesting level: #{nesting.level}"
|
|
|
|
output.puts "Pry version: #{Pry::VERSION}"
|
|
|
|
output.puts "Ruby version: #{RUBY_VERSION}"
|
2011-02-14 09:48:19 +00:00
|
|
|
|
|
|
|
mn = meth_name_from_binding.call(target)
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "Current method: #{mn ? mn : "N/A"}"
|
|
|
|
output.puts "Pry instance: #{Pry.active_instance}"
|
|
|
|
output.puts "Last result: #{Pry.view(Pry.last_result)}"
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-02-14 09:48:19 +00:00
|
|
|
command "version", "Show Pry version." do
|
2011-02-19 05:21:13 +00:00
|
|
|
output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}."
|
2011-02-14 09:48:19 +00:00
|
|
|
end
|
|
|
|
|
2011-02-25 15:32:54 +00:00
|
|
|
command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !@" do
|
2011-03-02 11:18:26 +00:00
|
|
|
str = remove_first_word.call(opts[:val])
|
2011-02-25 07:31:38 +00:00
|
|
|
throw(:breakout, [0, target.eval(str)])
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-02-25 15:32:54 +00:00
|
|
|
alias_command "!@", "exit-all", ""
|
2011-02-25 02:42:17 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "ls", "Show the list of vars in the current scope. Type `ls --help` for more info." do |*args|
|
|
|
|
options = {}
|
2011-02-18 17:01:21 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
# Set target local to the default -- note that we can set a different target for
|
|
|
|
# ls if we like: e.g ls my_var
|
|
|
|
target = target()
|
|
|
|
|
|
|
|
OptionParser.new do |opts|
|
|
|
|
opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\
|
|
|
|
List information about VAR (the current context by default).
|
2011-02-16 21:22:59 +00:00
|
|
|
Shows local and instance variables by default.
|
2011-02-16 16:27:55 +00:00
|
|
|
--
|
|
|
|
}
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-g", "--globals", "Display global variables.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:g] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-c", "--constants", "Display constants.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:c] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-l", "--locals", "Display locals.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:l] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-i", "--ivars", "Display instance variables.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:i] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-k", "--class-vars", "Display class variables.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:k] = true
|
|
|
|
end
|
|
|
|
|
2011-02-17 07:23:58 +00:00
|
|
|
opts.on("-m", "--methods", "Display methods (public methods by default).") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:m] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-M", "--instance-methods", "Display instance methods (only relevant to classes and modules).") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:M] = true
|
|
|
|
end
|
|
|
|
|
2011-02-18 05:06:14 +00:00
|
|
|
opts.on("-P", "--public", "Display public methods (with -m).") do
|
2011-02-17 03:59:08 +00:00
|
|
|
options[:P] = true
|
|
|
|
end
|
|
|
|
|
2011-02-18 05:06:14 +00:00
|
|
|
opts.on("-r", "--protected", "Display protected methods (with -m).") do
|
2011-02-17 03:59:08 +00:00
|
|
|
options[:r] = true
|
|
|
|
end
|
|
|
|
|
2011-02-18 05:06:14 +00:00
|
|
|
opts.on("-p", "--private", "Display private methods (with -m).") do
|
2011-02-17 03:59:08 +00:00
|
|
|
options[:p] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:s] = true
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-a", "--all", "Display all types of entries.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:a] = true
|
2011-02-13 15:49:53 +00:00
|
|
|
end
|
2011-02-16 16:27:55 +00:00
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-v", "--verbose", "Verbose ouput.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:v] = true
|
|
|
|
end
|
|
|
|
|
|
|
|
opts.on_tail("-h", "--help", "Show this message.") do
|
|
|
|
output.puts opts
|
|
|
|
options[:h] = true
|
|
|
|
end
|
|
|
|
end.order(args) do |new_target|
|
|
|
|
target = Pry.binding_for(target.eval("#{new_target}")) if !options[:h]
|
2011-02-13 15:49:53 +00:00
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
# exit if we've displayed help
|
|
|
|
next if options[:h]
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
# default is locals/ivars/class vars.
|
|
|
|
# Only occurs when no options or when only option is verbose
|
|
|
|
options.merge!({
|
2011-02-17 03:59:08 +00:00
|
|
|
:l => true,
|
|
|
|
:i => true,
|
|
|
|
:k => true
|
|
|
|
}) if options.empty? || (options.size == 1 && options[:v])
|
|
|
|
|
|
|
|
# Display public methods by default if -m or -M switch is used.
|
|
|
|
options[:P] = true if (options[:m] || options[:M]) && !(options[:p] || options[:r])
|
2011-02-16 21:22:59 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
info = {}
|
2011-02-02 10:43:21 +00:00
|
|
|
target_self = target.eval('self')
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
# ensure we have a real boolean and not a `nil` (important when
|
|
|
|
# interpolating in the string)
|
|
|
|
options[:s] = !!options[:s]
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
# Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8
|
2011-02-16 16:27:55 +00:00
|
|
|
i = -1
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
# Start collecting the entries selected by the user
|
|
|
|
info["local variables"] = [Array(target.eval("local_variables")).sort, i += 1] if options[:l] || options[:a]
|
|
|
|
info["instance variables"] = [Array(target.eval("instance_variables")).sort, i += 1] if options[:i] || options[:a]
|
|
|
|
|
|
|
|
info["class variables"] = [if target_self.is_a?(Module)
|
2011-02-18 17:01:21 +00:00
|
|
|
Array(target.eval("class_variables")).sort
|
|
|
|
else
|
|
|
|
Array(target.eval("self.class.class_variables")).sort
|
|
|
|
end, i += 1] if options[:k] || options[:a]
|
2011-02-16 21:22:59 +00:00
|
|
|
|
|
|
|
info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a]
|
2011-02-16 16:27:55 +00:00
|
|
|
|
2011-02-17 03:59:08 +00:00
|
|
|
info["public methods"] = [Array(target.eval("public_methods(#{options[:s]})")).uniq.sort, i += 1] if (options[:m] && options[:P]) || options[:a]
|
|
|
|
|
|
|
|
info["protected methods"] = [Array(target.eval("protected_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:r]) || options[:a]
|
|
|
|
|
|
|
|
info["private methods"] = [Array(target.eval("private_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:p]) || options[:a]
|
|
|
|
|
|
|
|
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])
|
|
|
|
|
|
|
|
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])
|
|
|
|
|
|
|
|
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])
|
2011-02-16 16:27:55 +00:00
|
|
|
|
|
|
|
# dealing with 1.8/1.9 compatibility issues :/
|
|
|
|
csuper = options[:s]
|
|
|
|
if Module.method(:constants).arity == 0
|
|
|
|
csuper = nil
|
|
|
|
end
|
2011-02-18 17:01:21 +00:00
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") :
|
2011-02-18 17:01:21 +00:00
|
|
|
target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a]
|
2011-02-16 16:27:55 +00:00
|
|
|
|
|
|
|
# verbose output?
|
|
|
|
if options[:v]
|
|
|
|
|
|
|
|
# verbose
|
2011-02-25 02:42:17 +00:00
|
|
|
info.sort_by { |k, v| v.last }.each do |k, v|
|
2011-02-16 16:27:55 +00:00
|
|
|
if !v.first.empty?
|
|
|
|
output.puts "#{k}:\n--"
|
2011-03-02 11:18:26 +00:00
|
|
|
if Pry.color
|
|
|
|
output.puts CodeRay.scan(Pry.view(v.first), :ruby).term
|
|
|
|
else
|
|
|
|
output.puts Pry.view(v.first)
|
|
|
|
end
|
2011-02-16 16:27:55 +00:00
|
|
|
output.puts
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-25 02:42:17 +00:00
|
|
|
# plain
|
2011-02-02 10:43:21 +00:00
|
|
|
else
|
2011-02-18 17:01:21 +00:00
|
|
|
list = info.values.sort_by { |v| v.last }.map { |v| v.first }.inject(&:+)
|
2011-03-02 11:18:26 +00:00
|
|
|
if Pry.color
|
|
|
|
output.puts CodeRay.scan(Pry.view(list), :ruby).term
|
|
|
|
else
|
|
|
|
output.puts Pry.view(list)
|
|
|
|
end
|
2011-02-18 17:01:21 +00:00
|
|
|
list
|
2011-02-02 10:43:21 +00:00
|
|
|
end
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
command "cat-file", "Show output of file FILE" do |file_name|
|
|
|
|
if !file_name
|
|
|
|
output.puts "Must provide a file name."
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2011-03-05 14:17:54 +00:00
|
|
|
contents = File.read(File.expand_path(file_name))
|
2011-02-25 02:42:17 +00:00
|
|
|
output.puts contents
|
|
|
|
contents
|
2011-02-16 21:22:59 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
command "eval-file", "Eval a Ruby script. Type `eval-file --help` for more info." do |*args|
|
|
|
|
options = {}
|
2011-02-21 00:46:29 +00:00
|
|
|
target = target()
|
2011-02-16 21:22:59 +00:00
|
|
|
file_name = nil
|
|
|
|
|
|
|
|
OptionParser.new do |opts|
|
|
|
|
opts.banner = %{Usage: eval-file [OPTIONS] FILE
|
2011-02-21 00:46:29 +00:00
|
|
|
Eval a Ruby script at top-level or in the specified context. Defaults to top-level.
|
|
|
|
e.g: eval-file -c self "hello.rb"
|
2011-02-16 21:22:59 +00:00
|
|
|
--
|
|
|
|
}
|
2011-02-21 00:46:29 +00:00
|
|
|
opts.on("-c", "--context CONTEXT", "Eval the script in the specified context.") do |context|
|
2011-02-16 21:22:59 +00:00
|
|
|
options[:c] = true
|
2011-02-21 00:46:29 +00:00
|
|
|
target = Pry.binding_for(target.eval(context))
|
2011-02-16 21:22:59 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
opts.on_tail("-h", "--help", "This message.") do
|
|
|
|
output.puts opts
|
|
|
|
options[:h] = true
|
|
|
|
end
|
|
|
|
end.order(args) do |v|
|
|
|
|
file_name = v
|
|
|
|
end
|
|
|
|
|
|
|
|
next if options[:h]
|
|
|
|
|
|
|
|
if !file_name
|
2011-02-17 07:23:58 +00:00
|
|
|
output.puts "You need to specify a file name. Type `eval-file --help` for help"
|
2011-02-16 21:22:59 +00:00
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
old_constants = Object.constants
|
|
|
|
if options[:c]
|
2011-02-21 00:46:29 +00:00
|
|
|
target_self = target.eval('self')
|
2011-03-05 14:17:54 +00:00
|
|
|
target.eval(File.read(File.expand_path(file_name)))
|
2011-02-21 00:46:29 +00:00
|
|
|
output.puts "--\nEval'd '#{file_name}' in the `#{target_self}` context."
|
2011-02-16 21:22:59 +00:00
|
|
|
else
|
2011-03-05 14:17:54 +00:00
|
|
|
TOPLEVEL_BINDING.eval(File.read(File.expand_path(file_name)))
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts "--\nEval'd '#{file_name}' at top-level."
|
|
|
|
end
|
2011-02-18 17:01:21 +00:00
|
|
|
new_constants = Object.constants - old_constants
|
|
|
|
output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty?
|
2011-02-16 21:22:59 +00:00
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "cat", "Show output of VAR.inspect. Aliases: inspect" do |obj|
|
|
|
|
if !obj
|
|
|
|
output.puts "Must provide an object to inspect."
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
output.puts Pry.view(target.eval("#{obj}"))
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
2011-02-14 09:48:19 +00:00
|
|
|
|
|
|
|
alias_command "inspect", "cat", ""
|
2011-01-12 01:16:04 +00:00
|
|
|
|
2011-02-26 04:55:51 +00:00
|
|
|
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|
|
2011-02-16 16:27:55 +00:00
|
|
|
if !obj
|
|
|
|
output.puts "Must provide an object."
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2011-01-17 14:38:09 +00:00
|
|
|
throw(:breakout, opts[:nesting].level) if obj == ".."
|
2011-02-25 02:42:17 +00:00
|
|
|
|
|
|
|
if obj == "/"
|
|
|
|
throw(:breakout, 1) if opts[:nesting].level > 0
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2011-01-20 14:41:41 +00:00
|
|
|
target.eval("#{obj}.pry")
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info." do |*args|
|
|
|
|
options = {}
|
2011-02-21 00:46:29 +00:00
|
|
|
target = target()
|
2011-02-16 16:27:55 +00:00
|
|
|
meth_name = nil
|
|
|
|
|
|
|
|
OptionParser.new do |opts|
|
|
|
|
opts.banner = %{Usage: show-doc [OPTIONS] [METH]
|
|
|
|
Show the comments above method METH. Shows _method_ comments (rather than instance methods) by default.
|
|
|
|
e.g show-doc hello_method
|
|
|
|
--
|
|
|
|
}
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:M] = true
|
|
|
|
end
|
|
|
|
|
2011-02-21 00:46:29 +00:00
|
|
|
opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
|
|
|
|
target = Pry.binding_for(target.eval(context))
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on_tail("-h", "--help", "This message.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
output.puts opts
|
|
|
|
options[:h] = true
|
|
|
|
end
|
|
|
|
end.order(args) do |v|
|
|
|
|
meth_name = v
|
|
|
|
end
|
|
|
|
|
|
|
|
next if options[:h]
|
2011-01-12 01:16:04 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
if !meth_name
|
|
|
|
output.puts "You need to specify a method. Type `show-doc --help` for help"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
begin
|
|
|
|
if options[:M]
|
|
|
|
meth = target.eval("instance_method(:#{meth_name})")
|
|
|
|
else
|
|
|
|
meth = target.eval("method(:#{meth_name})")
|
|
|
|
end
|
|
|
|
rescue
|
|
|
|
output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2011-02-21 02:41:49 +00:00
|
|
|
doc = meth.comment
|
2011-02-16 16:27:55 +00:00
|
|
|
file, line = meth.source_location
|
2011-02-18 17:01:21 +00:00
|
|
|
check_for_dynamically_defined_method.call(file)
|
|
|
|
|
2011-02-17 07:23:58 +00:00
|
|
|
output.puts "--\nFrom #{file} @ line ~#{line}:\n--"
|
2011-03-02 11:18:26 +00:00
|
|
|
|
|
|
|
if Pry.color
|
|
|
|
doc = CodeRay.scan(doc, :ruby).term
|
|
|
|
end
|
|
|
|
|
2011-01-20 14:41:41 +00:00
|
|
|
output.puts doc
|
2011-02-19 05:21:13 +00:00
|
|
|
doc
|
2010-12-26 13:39:46 +00:00
|
|
|
end
|
2010-12-24 08:30:51 +00:00
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "show-method", "Show the source for METH. Type `show-method --help` for more info." do |*args|
|
|
|
|
options = {}
|
2011-02-21 00:46:29 +00:00
|
|
|
target = target()
|
2011-02-16 16:27:55 +00:00
|
|
|
meth_name = nil
|
|
|
|
|
|
|
|
OptionParser.new do |opts|
|
|
|
|
opts.banner = %{Usage: show-method [OPTIONS] [METH]
|
|
|
|
Show the source for method METH. Shows _method_ source (rather than instance methods) by default.
|
|
|
|
e.g: show-method hello_method
|
|
|
|
--
|
|
|
|
}
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
options[:M] = true
|
|
|
|
end
|
|
|
|
|
2011-02-21 00:46:29 +00:00
|
|
|
opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
|
|
|
|
target = Pry.binding_for(target.eval(context))
|
|
|
|
end
|
|
|
|
|
2011-02-16 21:22:59 +00:00
|
|
|
opts.on_tail("-h", "--help", "This message.") do
|
2011-02-16 16:27:55 +00:00
|
|
|
output.puts opts
|
|
|
|
options[:h] = true
|
|
|
|
end
|
|
|
|
end.order(args) do |v|
|
|
|
|
meth_name = v
|
|
|
|
end
|
|
|
|
|
|
|
|
next if options[:h]
|
|
|
|
|
|
|
|
# If no method name is given then use current method, if it exists
|
2011-02-14 09:48:19 +00:00
|
|
|
meth_name = meth_name_from_binding.call(target) if !meth_name
|
2011-02-16 16:27:55 +00:00
|
|
|
|
|
|
|
if !meth_name
|
|
|
|
output.puts "You need to specify a method. Type `show-method --help` for help"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
begin
|
|
|
|
if options[:M]
|
|
|
|
meth = target.eval("instance_method(:#{meth_name})")
|
|
|
|
else
|
|
|
|
meth = target.eval("method(:#{meth_name})")
|
|
|
|
end
|
|
|
|
rescue
|
2011-02-19 05:21:13 +00:00
|
|
|
target_self = target.eval('self')
|
|
|
|
if !options[:M]&& target_self.is_a?(Module) &&
|
|
|
|
target_self.method_defined?(meth_name)
|
|
|
|
output.puts "Did you mean: show-method -M #{meth_name} ?"
|
|
|
|
end
|
2011-02-16 16:27:55 +00:00
|
|
|
output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
|
|
|
|
next
|
2011-01-26 18:05:40 +00:00
|
|
|
end
|
2011-01-12 01:16:04 +00:00
|
|
|
|
2011-02-21 02:41:49 +00:00
|
|
|
code = meth.source
|
2011-02-16 16:27:55 +00:00
|
|
|
file, line = meth.source_location
|
2011-02-18 17:01:21 +00:00
|
|
|
check_for_dynamically_defined_method.call(file)
|
|
|
|
|
2011-02-17 07:23:58 +00:00
|
|
|
output.puts "--\nFrom #{file} @ line #{line}:\n--"
|
2011-03-02 11:18:26 +00:00
|
|
|
|
|
|
|
if Pry.color
|
|
|
|
code = CodeRay.scan(code, :ruby).term
|
|
|
|
end
|
|
|
|
|
2011-01-27 09:37:43 +00:00
|
|
|
output.puts code
|
2011-02-18 17:01:21 +00:00
|
|
|
code
|
2011-01-12 01:16:04 +00:00
|
|
|
end
|
2011-02-16 16:27:55 +00:00
|
|
|
|
2011-02-18 17:01:21 +00:00
|
|
|
command "show-command", "Show sourcecode for a Pry command, e.g: show-command cd" do |command_name|
|
2011-02-16 16:27:55 +00:00
|
|
|
if !command_name
|
|
|
|
output.puts "You must provide a command name."
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2011-02-18 17:01:21 +00:00
|
|
|
if commands[command_name]
|
|
|
|
meth = commands[command_name][:action]
|
|
|
|
|
2011-02-21 02:41:49 +00:00
|
|
|
code = meth.source
|
2011-02-16 16:27:55 +00:00
|
|
|
file, line = meth.source_location
|
2011-02-18 17:01:21 +00:00
|
|
|
check_for_dynamically_defined_method.call(file)
|
|
|
|
|
2011-02-17 07:23:58 +00:00
|
|
|
output.puts "--\nFrom #{file} @ line #{line}:\n--"
|
2011-03-02 11:18:26 +00:00
|
|
|
|
|
|
|
if Pry.color
|
|
|
|
code = CodeRay.scan(code, :ruby).term
|
|
|
|
end
|
|
|
|
|
2011-02-13 15:49:53 +00:00
|
|
|
output.puts code
|
2011-02-18 17:01:21 +00:00
|
|
|
code
|
2011-02-13 15:49:53 +00:00
|
|
|
else
|
|
|
|
output.puts "No such command: #{command_name}."
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-16 16:27:55 +00:00
|
|
|
command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
|
2011-01-17 14:38:09 +00:00
|
|
|
break_level = break_level.to_i
|
|
|
|
nesting = opts[:nesting]
|
2011-01-12 01:16:04 +00:00
|
|
|
|
2011-01-17 14:38:09 +00:00
|
|
|
case break_level
|
|
|
|
when nesting.level
|
2011-01-20 14:41:41 +00:00
|
|
|
output.puts "Already at nesting level #{nesting.level}"
|
2011-01-17 14:38:09 +00:00
|
|
|
when (0...nesting.level)
|
|
|
|
throw(:breakout, break_level + 1)
|
|
|
|
else
|
|
|
|
max_nest_level = nesting.level - 1
|
2011-01-20 14:41:41 +00:00
|
|
|
output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
|
2010-12-25 13:51:34 +00:00
|
|
|
end
|
2010-12-24 08:30:51 +00:00
|
|
|
end
|
2010-12-25 13:51:34 +00:00
|
|
|
|
2011-02-25 07:31:38 +00:00
|
|
|
command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
|
2011-03-02 11:18:26 +00:00
|
|
|
str = remove_first_word.call(opts[:val])
|
2011-02-25 07:31:38 +00:00
|
|
|
throw(:breakout, [opts[:nesting].level, target.eval(str)])
|
2010-12-26 13:39:46 +00:00
|
|
|
end
|
2011-02-16 16:27:55 +00:00
|
|
|
|
|
|
|
alias_command "quit", "exit", ""
|
|
|
|
alias_command "back", "exit", ""
|
2011-02-18 18:01:02 +00:00
|
|
|
|
|
|
|
command "game", "" do |highest|
|
|
|
|
highest = highest ? highest.to_i : 100
|
|
|
|
num = rand(highest)
|
|
|
|
output.puts "Guess the number between 0-#{highest}: ('.' to quit)"
|
|
|
|
count = 0
|
|
|
|
while(true)
|
|
|
|
count += 1
|
2011-02-18 18:06:33 +00:00
|
|
|
str = Readline.readline("game > ", true)
|
|
|
|
break if str == "." || !str
|
2011-02-18 18:01:02 +00:00
|
|
|
val = str.to_i
|
|
|
|
output.puts "Too large!" if val > num
|
|
|
|
output.puts "Too small!" if val < num
|
|
|
|
if val == num
|
|
|
|
output.puts "Well done! You guessed right! It took you #{count} guesses."
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-20 16:54:18 +00:00
|
|
|
command "east-coker", "" do
|
|
|
|
text = %{
|
|
|
|
--
|
|
|
|
Now the light falls
|
|
|
|
Across the open field, leaving the deep lane
|
|
|
|
Shuttered with branches, dark in the afternoon,
|
|
|
|
Where you lean against a bank while a van passes,
|
|
|
|
And the deep lane insists on the direction
|
|
|
|
Into the village, in the electric heat
|
|
|
|
Hypnotised. In a warm haze the sultry light
|
|
|
|
Is absorbed, not refracted, by grey stone.
|
|
|
|
The dahlias sleep in the empty silence.
|
|
|
|
Wait for the early owl.
|
|
|
|
-- T.S Eliot
|
|
|
|
}
|
|
|
|
output.puts text
|
|
|
|
text
|
|
|
|
end
|
|
|
|
|
2011-02-18 18:01:02 +00:00
|
|
|
command "cohen-poem", "" do
|
|
|
|
text = %{
|
|
|
|
--
|
|
|
|
When this American woman,
|
|
|
|
whose thighs are bound in casual red cloth,
|
|
|
|
comes thundering past my sitting place
|
|
|
|
like a forest-burning Mongol tribe,
|
|
|
|
the city is ravished
|
|
|
|
and brittle buildings of a hundred years
|
|
|
|
splash into the street;
|
|
|
|
and my eyes are burnt
|
|
|
|
for the embroidered Chinese girls,
|
|
|
|
already old,
|
|
|
|
and so small between the thin pines
|
|
|
|
on these enormous landscapes,
|
|
|
|
that if you turn your head
|
|
|
|
they are lost for hours.
|
|
|
|
-- Leonard Cohen
|
2011-02-25 02:42:17 +00:00
|
|
|
}
|
2011-02-18 18:01:02 +00:00
|
|
|
output.puts text
|
|
|
|
text
|
|
|
|
end
|
|
|
|
end
|
2010-12-26 13:39:46 +00:00
|
|
|
end
|