1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00

Adding find-method command.

This commit is contained in:
Matt Carey 2012-03-31 22:24:28 -04:00
parent 9bf587f234
commit 87ca34d793
5 changed files with 371 additions and 0 deletions

30
lib/pry/commands.rb~ Normal file
View file

@ -0,0 +1,30 @@
require "pry/default_commands/misc"
require "pry/default_commands/help"
require "pry/default_commands/gems"
require "pry/default_commands/context"
require "pry/default_commands/commands"
require "pry/default_commands/input_and_output"
require "pry/default_commands/introspection"
require "pry/default_commands/editing"
require "pry/default_commands/navigating_pry"
require "pry/default_commands/easter_eggs"
require "pry/default_commands/find_method"
require "pry/extended_commands/experimental"
class Pry
# Default commands used by Pry.
Commands = Pry::CommandSet.new do
import DefaultCommands::Misc
import DefaultCommands::Help
import DefaultCommands::Gems
import DefaultCommands::Context
import DefaultCommands::NavigatingPry
import DefaultCommands::Editing
import DefaultCommands::InputAndOutput
import DefaultCommands::Introspection
import DefaultCommands::EasterEggs
import DefaultCommands::Commands
end
end

View file

@ -1,5 +1,6 @@
require "pry/default_commands/ls"
require "pry/default_commands/cd"
require "pry/default_commands/find_method"
class Pry
module DefaultCommands
@ -7,6 +8,7 @@ class Pry
Context = Pry::CommandSet.new do
import Ls
import Cd
import FindMethod
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|
file, line_num = file_and_line_from_binding(target)

View file

@ -0,0 +1,115 @@
require "pry/default_commands/ls"
require "pry/default_commands/cd"
require "pry/default_commands/find_method"
class Pry
module DefaultCommands
Context = Pry::CommandSet.new do
import Ls
import Cd
import FindMethod
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|
file, line_num = file_and_line_from_binding(target)
i_num = num ? num.to_i : 5
if file != Pry.eval_path && (file =~ /(\(.*\))|<.*>/ || file == "" || file == "-e")
raise CommandError, "Cannot find local context. Did you use binding.pry?"
end
set_file_and_dir_locals(file)
method = Pry::Method.from_binding(target)
method_description = method ? " in #{method.name_with_owner}" : ""
output.puts "\n#{text.bold('From:')} #{file} @ line #{line_num}#{method_description}:\n\n"
code = Pry::Code.from_file(file).around(line_num, i_num)
output.puts code.with_line_numbers.with_marker(line_num)
output.puts
end
create_command "pry-backtrace", "Show the backtrace for the Pry session." do
banner <<-BANNER
Usage: pry-backtrace [OPTIONS] [--help]
Show the backtrace for the position in the code where Pry was started. This can be used to
infer the behavior of the program immediately before it entered Pry, just like the backtrace
property of an exception.
(NOTE: if you are looking for the backtrace of the most recent exception raised,
just type: `_ex_.backtrace` instead, see https://github.com/pry/pry/wiki/Special-Locals)
e.g: pry-backtrace
BANNER
def process
output.puts "\n#{text.bold('Backtrace:')}\n--\n"
stagger_output _pry_.backtrace.join("\n")
end
end
command "reset", "Reset the REPL to a clean state." do
output.puts "Pry reset."
exec "pry"
end
create_command /wtf([?!]*)/, "Show the backtrace of the most recent exception" do
options :listing => 'wtf?'
banner <<-BANNER
Show's a few lines of the backtrace of the most recent exception (also available
as _ex_.backtrace).
If you want to see more lines, add more question marks or exclamation marks:
e.g.
pry(main)> wtf?
pry(main)> wtf?!???!?!?
To see the entire backtrace, pass the -v/--verbose flag:
e.g.
pry(main)> wtf -v
BANNER
def options(opt)
opt.on(:v, :verbose, "Show the full backtrace.")
end
def process
raise Pry::CommandError, "No most-recent exception" unless _pry_.last_exception
output.puts "#{text.bold('Exception:')} #{_pry_.last_exception.class}: #{_pry_.last_exception}\n--"
if opts.verbose?
output.puts Code.new(_pry_.last_exception.backtrace, 0, :text).with_line_numbers.to_s
else
output.puts Code.new(_pry_.last_exception.backtrace.first([captures[0].size, 0.5].max * 10), 0, :text).with_line_numbers.to_s
end
end
end
# N.B. using a regular expresion here so that "raise-up 'foo'" does the right thing.
create_command /raise-up(!?\b.*)/, :listing => 'raise-up' do
description "Raise an exception out of the current pry instance."
banner <<-BANNER
Raise up, like exit, allows you to quit pry. Instead of returning a value however, it raises an exception.
If you don't provide the exception to be raised, it will use the most recent exception (in pry _ex_).
e.g. `raise-up "get-me-out-of-here"` is equivalent to:
`raise "get-me-out-of-here"
raise-up`
When called as raise-up! (with an exclamation mark), this command raises the exception through
any nested prys you have created by "cd"ing into objects.
BANNER
def process
return stagger_output help if captures[0] =~ /(-h|--help)\b/
# Handle 'raise-up', 'raise-up "foo"', 'raise-up RuntimeError, 'farble' in a rubyesque manner
target.eval("_pry_.raise_up#{captures[0]}")
end
end
end
end
end

View file

@ -0,0 +1,112 @@
class Pry
module DefaultCommands
FindMethod = Pry::CommandSet.new do
create_command "find-method" do
group "Context"
description "Recursively search for a method within a Class/Module or the current namespace. find-method [-n | -c] METHOD [NAMESPACE]"
def options(opti)
opti.on :n, :name, "Search for a method by name"
opti.on :c, :content, "Search for a method based on content in Regex form"
end
def process
return if args.size < 1
pattern = ::Regexp.new args[0]
if args[1]
if args[1].is_a?(Module)
klass = args[1]
else
klass = args[1].class
end
else
to_put = target_self_eval(pattern, opts)
if to_put.flatten == []
puts "\e[31;1mNo Methods Found\e[0m"
else
puts "\e[32;1;4mMethods Found\e[0m"
puts to_put
end
return
end
if opts.name?
to_put = name_search(pattern, klass)
elsif opts.content?
to_put = content_search(pattern, klass)
else
to_put = name_search(pattern, klass)
end
if to_put.flatten == []
puts "\e[31;1mNo Methods Found\e[0m"
else
puts "\e[1;4;32mMethods Found\e[0m"
puts to_put
end
end
private
def puts(item)
output.puts item
end
def target_self_eval(pattern, opts)
obj = target_self
if opts.name?
return (obj.methods.select {|x| x=~pattern}).map {|x| "(#{obj.to_s})##{x}" }
elsif opts.content?
ret = []
obj.methods.select do |x|
meth = Pry::Method.new obj.method(x)
if meth.source =~ pattern
ret << "(#{obj.to_s})##{x}: " + (meth.source.split(/\n/).select {|x| x =~ pattern }).join("\n\t")
end
end
return ret
else
return (obj.methods.select {|x| x=~pattern}).map {|x| "(#{obj.to_s})##{x}" }
end
end
def content_search(pattern, klass, current=[])
return unless(klass.is_a? Module)
return if current.include? klass
current << klass
meths = []
(Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).uniq.each do |meth|
begin
if meth.source =~ pattern && !meth.alias?
meths << "#{klass}##{meth.name}: " + (meth.source.split(/\n/).select {|x| x =~ pattern }).join("\n\t")
end
rescue Exception
next
end
end
klass.constants.each do |klazz|
meths += ((res = content_search(pattern, klass.const_get(klazz), current)) ? res : [])
end
return meths.flatten
end
def name_search(regex, klass, current=[])
return unless(klass.is_a? Module)
return if current.include? klass
current << klass
meths = []
(Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).uniq.each {|x| meths << "#{klass}##{x.name}" if x.name =~ regex }
klass.constants.each do |x|
meths += ((res = name_search(regex, klass.const_get(x), current)) ? res : [])
end
return meths.flatten
end
end
end
end
end

View file

@ -0,0 +1,112 @@
class Pry
module DefaultCommands
FindMethod = Pry::CommandSet.new do
create_command "find-method" do
group "Context"
description "Recursively search for a method within a Class/Module or the current namespace. find-method [-n | -c] METHOD [NAMESPACE]"
def options(opti)
opti.on :n, :name, "Search for a method by name"
opti.on :c, :content, "Search for a method based on content in Regex form"
end
def process
return if args.size < 1
pattern = ::Regexp.new args[0]
if args[1]
if args[1].is_a?(Module)
klass = args[1]
else
klass = args[1].class
end
else
to_put = target_self_eval(pattern, opts)
if to_put.flatten == []
puts "\e[31;1mNo Methods Found\e[0m"
else
puts "\e[32;1;4mMethods Found\e[0m"
puts to_put
end
return
end
if opts.name?
to_put = name_search(pattern, klass)
elsif opts.content?
to_put = content_search(pattern, klass)
else
to_put = name_search(pattern, klass)
end
if to_put.flatten == []
puts "\e[31;1mNo Methods Found\e[0m"
else
puts "\e[1;4;32mMethods Found\e[0m"
puts to_put
end
end
private
def puts(item)
output.puts item
end
def target_self_eval(pattern, opts)
obj = target_self
if opts.name?
return (obj.methods.select {|x| x=~pattern}).map {|x| "(#{obj.to_s})##{x}" }
elsif opts.content?
ret = []
obj.methods.select do |x|
meth = Pry::Method.new obj.method(x)
if meth.source =~ pattern
ret << "(#{obj.to_s})##{x}: " + (meth.source.split(/\n/).select {|x| x =~ pattern }).join("\n\t")
end
end
return ret
else
return (obj.methods.select {|x| x=~pattern}).map {|x| "(#{obj.to_s})##{x}" }
end
end
def content_search(pattern, klass, current=[])
return unless(klass.is_a? Module)
return if current.include? klass
current << klass
meths = []
(Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).uniq.each do |meth|
begin
if meth.source =~ pattern && !meth.alias?
meths << "#{klass}##{meth.name}: " + (meth.source.split(/\n/).select {|x| x =~ pattern }).join("\n\t")
end
rescue Exception
next
end
end
klass.constants.each do |klazz|
meths += ((res = content_search(pattern, klass.const_get(klazz), current)) ? res : [])
end
return meths.flatten
end
def name_search(regex, klass, current=[])
return unless(klass.is_a? Module)
return if current.include? klass
current << klass
meths = []
(Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).uniq.each {|x| meths << "#{klass}##{x.name}" if x.name =~ regex }
klass.constants.each do |x|
meths += ((res = name_search(regex, klass.const_get(x), current)) ? res : [])
end
return meths.flatten
end
end
end
end
end