summaryrefslogtreecommitdiff
path: root/lib/irb/completion.rb
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2019-05-27 01:24:03 +0900
committeraycabta <aycabta@gmail.com>2019-05-27 01:24:12 +0900
commite39c950c2bcb8f77f12f841a7acc13b12402ee5a (patch)
treee26bc3f499019117117fb57d5ef96ad80b562cbb /lib/irb/completion.rb
parent2a7821b28964ba9d71d8714554502a02fabe3781 (diff)
Use correctly RI output in IRB completion
Diffstat (limited to 'lib/irb/completion.rb')
-rw-r--r--lib/irb/completion.rb139
1 files changed, 111 insertions, 28 deletions
diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb
index 573f2ed3e6..2696f597a6 100644
--- a/lib/irb/completion.rb
+++ b/lib/irb/completion.rb
@@ -39,6 +39,10 @@ module IRB
BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
CompletionProc = proc { |input|
+ retrieve_completion_data(input)
+ }
+
+ def self.retrieve_completion_data(input, doc_namespace = false)
bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
case input
@@ -48,7 +52,11 @@ module IRB
message = Regexp.quote($3)
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 /^(\/[^\/]*\/)\.([^.]*)$/
# Regexp
@@ -56,7 +64,11 @@ module IRB
message = Regexp.quote($2)
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 /^([^\]]*\])\.([^.]*)$/
# Array
@@ -64,19 +76,28 @@ module IRB
message = Regexp.quote($2)
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 /^([^\}]*\})\.([^.]*)$/
# Proc or Hash
receiver = $1
message = Regexp.quote($2)
- candidates = Proc.instance_methods.collect{|m| m.to_s}
- candidates |= Hash.instance_methods.collect{|m| m.to_s}
- select_message(receiver, message, candidates)
+ proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
+ hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
+ if doc_namespace
+ ["Proc.#{message}", "Hash.#{message}"]
+ else
+ select_message(receiver, message, proc_candidates | hash_candidates)
+ end
when /^(:[^:.]*)$/
# Symbol
+ return nil if doc_namespace
if Symbol.respond_to?(:all_symbols)
sym = $1
candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
@@ -89,7 +110,11 @@ module IRB
# Absolute Constant or class methods
receiver = $1
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].*)::([^:.]*)$/
# Constant or class methods
@@ -101,7 +126,11 @@ module IRB
rescue Exception
candidates = []
end
- select_message(receiver, message, candidates, "::")
+ if doc_namespace
+ "#{receiver}::#{message}"
+ else
+ select_message(receiver, message, candidates, "::")
+ end
when /^(:[^:.]+)(\.|::)([^.]*)$/
# Symbol
@@ -110,20 +139,33 @@ module IRB
message = Regexp.quote($3)
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
- receiver = $1
- sep = $5
- message = Regexp.quote($6)
+ receiver = $~[:num]
+ sep = $~[:sep]
+ message = Regexp.quote($~[:mes])
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
- candidates = []
+ if doc_namespace
+ nil
+ else
+ candidates = []
+ end
end
- select_message(receiver, message, candidates, sep)
when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/
# Numeric(0xFFFF)
@@ -132,16 +174,31 @@ module IRB
message = Regexp.quote($3)
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
- candidates = []
+ if doc_namespace
+ nil
+ else
+ candidates = []
+ end
end
- select_message(receiver, message, candidates, sep)
when /^(\$[^.]*)$/
# global var
- regmessage = Regexp.new(Regexp.quote($1))
- candidates = global_variables.collect{|m| m.to_s}.grep(regmessage)
+ gvar = $1
+ 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 /^([^."].*)(\.|::)([^.]*)$/
# variable.func or func.func
@@ -180,7 +237,11 @@ module IRB
candidates.sort!
candidates.uniq!
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 /^\.([^.]*)$/
# unknown(maybe String)
@@ -189,20 +250,42 @@ module IRB
message = Regexp.quote($1)
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
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
RDocRIDriver = RDoc::RI::Driver.new
PerfectMatchedProc = proc { |matched|
- begin
- RDocRIDriver.display_name(matched)
- rescue RDoc::RI::Driver::NotFoundError
+ namespace = retrieve_completion_data(matched, true)
+ return unless matched
+ 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
}