2011-05-01 10:25:37 +00:00
|
|
|
class Pry
|
|
|
|
module DefaultCommands
|
|
|
|
|
2011-05-07 05:32:05 +00:00
|
|
|
Documentation = Pry::CommandSet.new do
|
2011-05-01 10:25:37 +00:00
|
|
|
|
|
|
|
command "ri", "View ri documentation. e.g `ri Array#each`" do |*args|
|
|
|
|
run ".ri", *args
|
|
|
|
end
|
|
|
|
|
|
|
|
command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info. Aliases: \?" do |*args|
|
|
|
|
target = target()
|
|
|
|
|
2011-05-19 15:53:44 +00:00
|
|
|
opts = Slop.parse!(args) do |opt|
|
2011-09-10 20:22:47 +00:00
|
|
|
opt.banner unindent <<-USAGE
|
|
|
|
Usage: show-doc [OPTIONS] [METH 1] [METH 2] [METH N]
|
|
|
|
Show the comments above method METH. Tries instance methods first and then methods by default.
|
|
|
|
e.g show-doc hello_method
|
|
|
|
USAGE
|
2011-05-19 15:53:44 +00:00
|
|
|
|
|
|
|
opt.on :M, "instance-methods", "Operate on instance methods."
|
|
|
|
opt.on :m, :methods, "Operate on methods."
|
|
|
|
opt.on :c, :context, "Select object context to run under.", true do |context|
|
2011-05-01 10:25:37 +00:00
|
|
|
target = Pry.binding_for(target.eval(context))
|
|
|
|
end
|
2011-05-19 15:53:44 +00:00
|
|
|
opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
|
|
|
opt.on :h, :help, "This message." do
|
|
|
|
output.puts opt
|
2011-05-01 10:25:37 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
next if opts.help?
|
|
|
|
|
2011-08-27 14:13:15 +00:00
|
|
|
args = [nil] if args.empty?
|
|
|
|
args.each do |method_name|
|
|
|
|
meth_name = method_name
|
|
|
|
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
|
|
|
output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
|
|
|
|
next
|
|
|
|
end
|
2011-05-01 10:25:37 +00:00
|
|
|
|
2011-08-27 14:13:15 +00:00
|
|
|
doc, code_type = doc_and_code_type_for(meth)
|
|
|
|
next if !doc
|
2011-05-01 10:25:37 +00:00
|
|
|
|
2011-08-27 14:13:15 +00:00
|
|
|
next output.puts("No documentation found.") if doc.empty?
|
|
|
|
doc = process_comment_markup(doc, code_type)
|
|
|
|
output.puts make_header(meth, code_type, doc)
|
|
|
|
output.puts "#{text.bold("visibility: ")} #{method_visibility(meth).to_s}"
|
2011-09-03 10:37:10 +00:00
|
|
|
output.puts "#{text.bold("signature: ")} #{signature_for(meth)}"
|
|
|
|
output.puts
|
2011-08-27 14:13:15 +00:00
|
|
|
render_output(opts.flood?, false, doc)
|
|
|
|
doc
|
2011-06-16 13:46:49 +00:00
|
|
|
end
|
2011-05-01 10:25:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
alias_command "?", "show-doc", ""
|
|
|
|
|
|
|
|
command "stat", "View method information and set _file_ and _dir_ locals. Type `stat --help` for more info." do |*args|
|
|
|
|
target = target()
|
|
|
|
|
2011-05-19 15:53:44 +00:00
|
|
|
opts = Slop.parse!(args) do |opt|
|
2011-09-10 20:22:47 +00:00
|
|
|
opt.banner unindent <<-USAGE
|
|
|
|
Usage: stat [OPTIONS] [METH]
|
|
|
|
Show method information for method METH and set _file_ and _dir_ locals.
|
|
|
|
e.g: stat hello_method
|
|
|
|
USAGE
|
2011-05-19 15:53:44 +00:00
|
|
|
|
|
|
|
opt.on :M, "instance-methods", "Operate on instance methods."
|
|
|
|
opt.on :m, :methods, "Operate on methods."
|
|
|
|
opt.on :c, :context, "Select object context to run under.", true do |context|
|
2011-05-01 10:25:37 +00:00
|
|
|
target = Pry.binding_for(target.eval(context))
|
|
|
|
end
|
2011-05-19 15:53:44 +00:00
|
|
|
opt.on :h, :help, "This message" do
|
|
|
|
output.puts opt
|
2011-05-01 10:25:37 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
next if opts.help?
|
|
|
|
|
|
|
|
meth_name = args.shift
|
|
|
|
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
|
|
|
output.puts "Invalid method name: #{meth_name}. Type `stat --help` for help"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
2011-06-16 13:46:49 +00:00
|
|
|
if !is_a_c_method?(meth) && !is_a_dynamically_defined_method?(meth)
|
|
|
|
set_file_and_dir_locals(path_line_for(meth).first)
|
|
|
|
end
|
2011-05-01 10:25:37 +00:00
|
|
|
|
2011-06-16 13:46:49 +00:00
|
|
|
output.puts "Method Information:"
|
|
|
|
output.puts "--"
|
|
|
|
output.puts "Name: " + meth_name
|
|
|
|
output.puts "Owner: " + (meth.owner.to_s ? meth.owner.to_s : "Unknown")
|
2011-08-14 09:13:41 +00:00
|
|
|
output.puts "Visibility: " + method_visibility(meth).to_s
|
2011-06-16 13:46:49 +00:00
|
|
|
output.puts "Type: " + (meth.is_a?(Method) ? "Bound" : "Unbound")
|
|
|
|
output.puts "Arity: " + meth.arity.to_s
|
2011-09-03 10:37:10 +00:00
|
|
|
output.puts "Method Signature: " + signature_for(meth)
|
2011-05-01 10:25:37 +00:00
|
|
|
|
2011-09-03 10:37:10 +00:00
|
|
|
output.puts "Source location: " + (meth.source_location ? meth.source_location.join(":") : "Not found.")
|
2011-05-01 10:25:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
command "gist-method", "Gist a method to github. Type `gist-method --help` for more info.", :requires_gem => "gist" do |*args|
|
2011-05-15 07:43:08 +00:00
|
|
|
require 'gist'
|
|
|
|
|
2011-05-01 10:25:37 +00:00
|
|
|
target = target()
|
|
|
|
|
2011-05-19 15:53:44 +00:00
|
|
|
opts = Slop.parse!(args) do |opt|
|
2011-09-10 20:22:47 +00:00
|
|
|
opt.banner unindent <<-USAGE
|
|
|
|
Usage: gist-method [OPTIONS] [METH]
|
|
|
|
Gist the method (doc or source) to github.
|
|
|
|
Ensure the `gist` gem is properly working before use. http://github.com/defunkt/gist for instructions.
|
|
|
|
e.g: gist -m my_method
|
|
|
|
e.g: gist -d my_method
|
|
|
|
USAGE
|
2011-05-19 15:53:44 +00:00
|
|
|
|
|
|
|
opt.on :m, :method, "Gist a method's source."
|
|
|
|
opt.on :d, :doc, "Gist a method's documentation."
|
|
|
|
opt.on :p, :private, "Create a private gist (default: true)", :default => true
|
|
|
|
opt.on :h, :help, "This message" do
|
|
|
|
output.puts opt
|
2011-05-01 10:25:37 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
next if opts.help?
|
|
|
|
|
|
|
|
# This needs to be extracted into its own method as it's shared
|
|
|
|
# by show-method and show-doc and stat commands
|
|
|
|
meth_name = args.shift
|
|
|
|
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
|
|
|
output.puts "Invalid method name: #{meth_name}. Type `gist-method --help` for help"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
type_map = { :ruby => "rb", :c => "c", :plain => "plain" }
|
|
|
|
if !opts.doc?
|
|
|
|
content, code_type = code_and_code_type_for(meth)
|
|
|
|
else
|
|
|
|
content, code_type = doc_and_code_type_for(meth)
|
2011-05-07 14:26:53 +00:00
|
|
|
text.no_color do
|
2011-05-01 10:25:37 +00:00
|
|
|
content = process_comment_markup(content, code_type)
|
|
|
|
end
|
|
|
|
code_type = :plain
|
|
|
|
end
|
|
|
|
|
2011-05-15 07:43:08 +00:00
|
|
|
link = Gist.write([:extension => ".#{type_map[code_type]}",
|
|
|
|
:input => content],
|
|
|
|
opts.p?)
|
|
|
|
|
|
|
|
output.puts "Gist created at #{link}"
|
2011-05-01 10:25:37 +00:00
|
|
|
end
|
|
|
|
|
2011-06-16 13:46:49 +00:00
|
|
|
helpers do
|
2011-09-03 10:37:10 +00:00
|
|
|
|
|
|
|
# paraphrased from awesome_print gem
|
|
|
|
def signature_for(method)
|
|
|
|
if method.respond_to?(:parameters)
|
|
|
|
|
|
|
|
args = method.parameters.inject([]) do |arr, (type, name)|
|
|
|
|
name ||= (type == :block ? 'block' : "arg#{arr.size + 1}")
|
|
|
|
arr << case type
|
|
|
|
when :req then name.to_s
|
|
|
|
when :opt, :rest then "*#{name}"
|
|
|
|
when :block then "&#{name}"
|
|
|
|
else '?'
|
|
|
|
end
|
2011-06-16 13:46:49 +00:00
|
|
|
end
|
2011-09-03 10:37:10 +00:00
|
|
|
else
|
|
|
|
args = (1..method.arity.abs).map { |i| "arg#{i}" }
|
|
|
|
args[-1] = "*#{args[-1]}" if method.arity < 0
|
2011-06-16 13:46:49 +00:00
|
|
|
end
|
2011-08-14 09:13:41 +00:00
|
|
|
|
2011-09-03 10:37:10 +00:00
|
|
|
"#{method.name}(#{args.join(', ')})"
|
|
|
|
end
|
|
|
|
|
2011-08-14 09:13:41 +00:00
|
|
|
def method_visibility(meth)
|
|
|
|
if meth.owner.public_instance_methods.include? meth.name
|
|
|
|
:public
|
|
|
|
elsif meth.owner.protected_instance_methods.include? meth.name
|
|
|
|
:protected
|
|
|
|
elsif meth.owner.private_instance_methods.include? meth.name
|
|
|
|
:private
|
|
|
|
else
|
|
|
|
:none
|
|
|
|
end
|
|
|
|
end
|
2011-06-16 13:46:49 +00:00
|
|
|
end
|
|
|
|
|
2011-05-01 10:25:37 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|