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

Use correctly RI output in IRB completion

This commit is contained in:
aycabta 2019-05-27 01:24:03 +09:00
parent 2a7821b289
commit e39c950c2b

View file

@ -39,6 +39,10 @@ module IRB
BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{(" BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
CompletionProc = proc { |input| CompletionProc = proc { |input|
retrieve_completion_data(input)
}
def self.retrieve_completion_data(input, doc_namespace = false)
bind = IRB.conf[:MAIN_CONTEXT].workspace.binding bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
case input case input
@ -48,7 +52,11 @@ module IRB
message = Regexp.quote($3) message = Regexp.quote($3)
candidates = String.instance_methods.collect{|m| m.to_s} candidates = String.instance_methods.collect{|m| m.to_s}
select_message(receiver, message, candidates) if doc_namespace
"String.#{message}"
else
select_message(receiver, message, candidates)
end
when /^(\/[^\/]*\/)\.([^.]*)$/ when /^(\/[^\/]*\/)\.([^.]*)$/
# Regexp # Regexp
@ -56,7 +64,11 @@ module IRB
message = Regexp.quote($2) message = Regexp.quote($2)
candidates = Regexp.instance_methods.collect{|m| m.to_s} candidates = Regexp.instance_methods.collect{|m| m.to_s}
select_message(receiver, message, candidates) if doc_namespace
"Regexp.#{message}"
else
select_message(receiver, message, candidates)
end
when /^([^\]]*\])\.([^.]*)$/ when /^([^\]]*\])\.([^.]*)$/
# Array # Array
@ -64,19 +76,28 @@ module IRB
message = Regexp.quote($2) message = Regexp.quote($2)
candidates = Array.instance_methods.collect{|m| m.to_s} candidates = Array.instance_methods.collect{|m| m.to_s}
select_message(receiver, message, candidates) if doc_namespace
"Array.#{message}"
else
select_message(receiver, message, candidates)
end
when /^([^\}]*\})\.([^.]*)$/ when /^([^\}]*\})\.([^.]*)$/
# Proc or Hash # Proc or Hash
receiver = $1 receiver = $1
message = Regexp.quote($2) message = Regexp.quote($2)
candidates = Proc.instance_methods.collect{|m| m.to_s} proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
candidates |= Hash.instance_methods.collect{|m| m.to_s} hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
select_message(receiver, message, candidates) if doc_namespace
["Proc.#{message}", "Hash.#{message}"]
else
select_message(receiver, message, proc_candidates | hash_candidates)
end
when /^(:[^:.]*)$/ when /^(:[^:.]*)$/
# Symbol # Symbol
return nil if doc_namespace
if Symbol.respond_to?(:all_symbols) if Symbol.respond_to?(:all_symbols)
sym = $1 sym = $1
candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name} candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
@ -89,7 +110,11 @@ module IRB
# Absolute Constant or class methods # Absolute Constant or class methods
receiver = $1 receiver = $1
candidates = Object.constants.collect{|m| m.to_s} candidates = Object.constants.collect{|m| m.to_s}
candidates.grep(/^#{receiver}/).collect{|e| "::" + e} if doc_namespace
candidates.find { |i| i == receiver }
else
candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
end
when /^([A-Z].*)::([^:.]*)$/ when /^([A-Z].*)::([^:.]*)$/
# Constant or class methods # Constant or class methods
@ -101,7 +126,11 @@ module IRB
rescue Exception rescue Exception
candidates = [] candidates = []
end end
select_message(receiver, message, candidates, "::") if doc_namespace
"#{receiver}::#{message}"
else
select_message(receiver, message, candidates, "::")
end
when /^(:[^:.]+)(\.|::)([^.]*)$/ when /^(:[^:.]+)(\.|::)([^.]*)$/
# Symbol # Symbol
@ -110,20 +139,33 @@ module IRB
message = Regexp.quote($3) message = Regexp.quote($3)
candidates = Symbol.instance_methods.collect{|m| m.to_s} candidates = Symbol.instance_methods.collect{|m| m.to_s}
select_message(receiver, message, candidates, sep) if doc_namespace
"Symbol.#{message}"
else
select_message(receiver, message, candidates, sep)
end
when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)(\.|::)([^.]*)$/ when /^(?<num>-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)(?<sep>\.|::)(?<mes>[^.]*)$/
# Numeric # Numeric
receiver = $1 receiver = $~[:num]
sep = $5 sep = $~[:sep]
message = Regexp.quote($6) message = Regexp.quote($~[:mes])
begin begin
candidates = eval(receiver, bind).methods.collect{|m| m.to_s} instance = eval(receiver, bind)
if doc_namespace
"#{instance.class.name}.#{message}"
else
candidates = instance.methods.collect{|m| m.to_s}
select_message(receiver, message, candidates, sep)
end
rescue Exception rescue Exception
candidates = [] if doc_namespace
nil
else
candidates = []
end
end end
select_message(receiver, message, candidates, sep)
when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/ when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/
# Numeric(0xFFFF) # Numeric(0xFFFF)
@ -132,16 +174,31 @@ module IRB
message = Regexp.quote($3) message = Regexp.quote($3)
begin begin
candidates = eval(receiver, bind).methods.collect{|m| m.to_s} instance = eval(receiver, bind)
if doc_namespace
"#{instance.class.name}.#{message}"
else
candidates = instance.methods.collect{|m| m.to_s}
select_message(receiver, message, candidates, sep)
end
rescue Exception rescue Exception
candidates = [] if doc_namespace
nil
else
candidates = []
end
end end
select_message(receiver, message, candidates, sep)
when /^(\$[^.]*)$/ when /^(\$[^.]*)$/
# global var # global var
regmessage = Regexp.new(Regexp.quote($1)) gvar = $1
candidates = global_variables.collect{|m| m.to_s}.grep(regmessage) regmessage =
all_gvars = global_variables.collect{|m| m.to_s}
if doc_namespace
all_gvars.find{ |i| i == gvar }
else
all_gvars.grep(Regexp.new(Regexp.quote(gvar)))
end
when /^([^."].*)(\.|::)([^.]*)$/ when /^([^."].*)(\.|::)([^.]*)$/
# variable.func or func.func # variable.func or func.func
@ -180,7 +237,11 @@ module IRB
candidates.sort! candidates.sort!
candidates.uniq! candidates.uniq!
end end
select_message(receiver, message, candidates, sep) if doc_namespace
"#{rec.class.name}#{sep}#{candidates.find{ |i| i == message }}"
else
select_message(receiver, message, candidates, sep)
end
when /^\.([^.]*)$/ when /^\.([^.]*)$/
# unknown(maybe String) # unknown(maybe String)
@ -189,20 +250,42 @@ module IRB
message = Regexp.quote($1) message = Regexp.quote($1)
candidates = String.instance_methods(true).collect{|m| m.to_s} candidates = String.instance_methods(true).collect{|m| m.to_s}
select_message(receiver, message, candidates) if doc_namespace
"String.#{candidates.find{ |i| i == message }}"
else
select_message(receiver, message, candidates)
end
else else
candidates = eval("methods | private_methods | local_variables | instance_variables | self.class.constants", bind).collect{|m| m.to_s} candidates = eval("methods | private_methods | local_variables | instance_variables | self.class.constants", bind).collect{|m| m.to_s}
conditions |= ReservedWords
(candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/) if doc_namespace
candidates.find{ |i| i == input }
else
candidates.grep(/^#{Regexp.quote(input)}/)
end
end end
} end
RDocRIDriver = RDoc::RI::Driver.new RDocRIDriver = RDoc::RI::Driver.new
PerfectMatchedProc = proc { |matched| PerfectMatchedProc = proc { |matched|
begin namespace = retrieve_completion_data(matched, true)
RDocRIDriver.display_name(matched) return unless matched
rescue RDoc::RI::Driver::NotFoundError if namespace.is_a?(Array)
out = RDoc::Markup::Document.new
namespace.each do |m|
begin
RDocRIDriver.add_method(out, m)
rescue RDoc::RI::Driver::NotFoundError
end
end
RDocRIDriver.display(out)
else
begin
RDocRIDriver.display_names([namespace])
rescue RDoc::RI::Driver::NotFoundError
end
end end
} }