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:
parent
9bf587f234
commit
87ca34d793
5 changed files with 371 additions and 0 deletions
30
lib/pry/commands.rb~
Normal file
30
lib/pry/commands.rb~
Normal 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
|
|
@ -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)
|
||||
|
|
115
lib/pry/default_commands/context.rb~
Normal file
115
lib/pry/default_commands/context.rb~
Normal 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
|
112
lib/pry/default_commands/find_method.rb
Normal file
112
lib/pry/default_commands/find_method.rb
Normal 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
|
112
lib/pry/default_commands/find_method.rb~
Normal file
112
lib/pry/default_commands/find_method.rb~
Normal 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
|
Loading…
Reference in a new issue