def call(str, options = {})
custom_completions = options[:custom_completions] || []
path, input = build_path(str)
if path.call.empty?
target = options[:target]
else
begin
target = Pry::ObjectPath.new(path.call, @pry.binding_stack).resolve.last
rescue Pry::CommandError
target = options[:target]
end
end
begin
bind = target
case input
when REGEX_REGEXP
receiver = $1
message = Regexp.quote($2)
candidates = Regexp.instance_methods.collect(&:to_s)
select_message(path, receiver, message, candidates)
when ARRAY_REGEXP
receiver = $1
message = Regexp.quote($2)
candidates = Array.instance_methods.collect(&:to_s)
select_message(path, receiver, message, candidates)
when PROC_OR_HASH_REGEXP
receiver = $1
message = Regexp.quote($2)
candidates = Proc.instance_methods.collect(&:to_s)
candidates |= Hash.instance_methods.collect(&:to_s)
select_message(path, receiver, message, candidates)
when SYMBOL_REGEXP
if Symbol.respond_to?(:all_symbols)
sym = Regexp.quote($1)
candidates = Symbol.all_symbols.collect{|s| ":" << s.id2name}
candidates.grep(/^#{sym}/)
else
[]
end
when TOPLEVEL_LOOKUP_REGEXP
receiver = $1
candidates = Object.constants.collect(&:to_s)
candidates.grep(/^#{receiver}/).collect{|e| "::" << e}
when CONSTANT_REGEXP
message = $1
begin
context = target.eval("self")
context = context.class unless context.respond_to? :constants
candidates = context.constants.collect(&:to_s)
rescue
candidates = []
end
candidates = candidates.grep(/^#{message}/).collect(&path)
when CONSTANT_OR_METHOD_REGEXP
receiver = $1
message = Regexp.quote($2)
begin
candidates = eval("#{receiver}.constants.collect(&:to_s)", bind)
candidates |= eval("#{receiver}.methods.collect(&:to_s)", bind)
rescue Pry::RescuableException
candidates = []
end
candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
when SYMBOL_METHOD_CALL_REGEXP
receiver = $1
message = Regexp.quote($2)
candidates = Symbol.instance_methods.collect(&:to_s)
select_message(path, receiver, message, candidates)
when NUMERIC_REGEXP
receiver = $1
message = Regexp.quote($5)
begin
candidates = eval(receiver, bind).methods.collect(&:to_s)
rescue Pry::RescuableException
candidates = []
end
select_message(path, receiver, message, candidates)
when HEX_REGEXP
receiver = $1
message = Regexp.quote($2)
begin
candidates = eval(receiver, bind).methods.collect(&:to_s)
rescue Pry::RescuableException
candidates = []
end
select_message(path, receiver, message, candidates)
when GLOBALVARIABLE_REGEXP
regmessage = Regexp.new(Regexp.quote($1))
candidates = global_variables.collect(&:to_s).grep(regmessage)
when VARIABLE_REGEXP
receiver = $1
message = Regexp.quote($2)
gv = eval("global_variables", bind).collect(&:to_s)
lv = eval("local_variables", bind).collect(&:to_s)
cv = eval("self.class.constants", bind).collect(&:to_s)
if (gv | lv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
begin
candidates = eval("#{receiver}.methods", bind).collect(&:to_s)
rescue Pry::RescuableException
candidates = []
end
else
candidates = []
ObjectSpace.each_object(Module){|m|
begin
name = m.name.to_s
rescue Pry::RescuableException
name = ""
end
next if name != "IRB::Context" and
/^(IRB|SLex|RubyLex|RubyToken)/ =~ name
if m.respond_to?(:instance_methods)
candidates.concat m.instance_methods(false).collect(&:to_s)
end
}
candidates.sort!
candidates.uniq!
end
select_message(path, receiver, message, candidates)
when /^\.([^.]*)$/
receiver = ""
message = Regexp.quote($1)
candidates = String.instance_methods(true).collect(&:to_s)
select_message(path, receiver, message, candidates)
else
candidates = eval(
"methods | private_methods | local_variables | " \
"self.class.constants | instance_variables",
bind
).collect(&:to_s)
if eval("respond_to?(:class_variables)", bind)
candidates += eval("class_variables", bind).collect(&:to_s)
end
candidates = (candidates|ReservedWords|custom_completions).grep(/^#{Regexp.quote(input)}/)
candidates.collect(&path)
end
rescue Pry::RescuableException
[]
end
end