Date: 2008-06-13 23:31
Sender: Daniel Choi
Here is a patch file for rdoc 1. I also adapted the code to
rdoc 2 and submitted those patches in the RDoc project area.
--- ri_driver-orig.rb 2008-06-13 19:29:04.000000000 -0400
+++ ri_driver.rb 2008-06-13 19:30:13.000000000 -0400
@@ -45,22 +45,53 @@
# if it contains an entry that exactly matches the
requested method,
# then display that entry, otherwise display the list of
# matching method names
-
+ #
+ # This patched version of the method allows the user to
choose
+ # a matching method from an interactive prompt if
multiple methods
+ # are matched.
def report_method_stuff(requested_method_name, methods)
if methods.size == 1
method = @ri_reader.get_method(methods[0])
@display.display_method_info(method)
else
entries = methods.find_all {|m| m.name ==
requested_method_name}
+ if entries.empty?
+ unless methods.empty? # There are no exact matches,
but partial matches
+ # Print approximate matches.
+ STDOUT.puts "There are no exact matches, but
#{methods.size} partial matches."
+ STDOUT.puts "Type the number of the method you
want, or press Return to cancel:\n\n"
+ entries = methods
+ end
+ else # There are multiple exact matches
+ STDOUT.puts "More than one method matched your
request. Type the number"
+ STDOUT.puts "of the method you want, or press
Return to cancel:\n\n"
+ end
if entries.size == 1
method = @ri_reader.get_method(entries[0])
@display.display_method_info(method)
else
- @display.display_method_list(methods)
- end
- end
- end
-
+ entries.each_with_index do |m, i|
+ # Show version numbers if there is more than one
exact match.
+ # Assume that a gem version always appears like
"-2.0.2" in the path.
+ # Thanks to Leslie Viljoen for suggesting this
version-numbering
+ # feature on comp.lang.ruby.
+ version_string = nil
+ if entries.select {|e| e.full_name ==
m.full_name}.size > 1
+ match_data = /-(\d+\.\d+\.\d+)/.match(m.path_name)
+ version_string = match_data ? "
(#{match_data[1]})" : nil
+ end
+ STDOUT.puts "%2d %s%s" % [i+1, m.full_name,
version_string]
+ end
+ STDOUT.print ">> "
+ choice = STDIN.gets.chomp.to_i
+ if choice == 0
+ exit
+ end
+ method = @ri_reader.get_method(entries[choice-1])
+ @display.display_method_info(method)
+ end
+ end
+ end
#################################################################
#####
def report_class_stuff(namespaces)
@@ -79,11 +110,29 @@
end
#################################################################
#####
-
-
+
+ # This patch enables the user to get all methods on a
class as a numbered
+ # menu if the user enters something like "ri
String*"
def get_info_for(arg)
- desc = NameDescriptor.new(arg)
+
+ # The patch:
+ show_method_menu = false
+ if arg =~ /\w\*/
+ filter = []
+ case arg.split('*')[1]
+ when /^i/
+ filter << :instance_methods
+ when /^c/
+ filter << :class_methods
+ else
+ filter = [:class_methods, :instance_methods]
+ end
+ arg = klass = arg.split('*')[0]
+ show_method_menu = true
+ end
+ desc = NameDescriptor.new(arg)
+
namespaces = @ri_reader.top_level_namespace
for class_name in desc.class_names
@@ -101,7 +150,82 @@
namespaces = entries if entries.size == 1
if desc.method_name.nil?
- report_class_stuff(namespaces)
+ # Another patch here: Show an interactive menu of
methods for the class
+ if show_method_menu
+ klass = @ri_reader.get_class(namespaces[0])
+ index = 1
+ menu_methods = []
+ use_readline = false
+ if require('readline') && require('abbrev')
+ use_readline = true
+ end
+ options = RI::Options.instance
+ formatter = RI::TextFormatter.new(options, "
")
+ superclass = klass.superclass_string
+
+ if superclass
+ superclass = " < " + superclass
+ else
+ superclass = ""
+ end
+
+ formatter.draw_line(klass.display_name + ": "
+
+ klass.full_name + superclass)
+
+ filter.each do |x|
+ formatter.display_heading(x.to_s.gsub('_', '
').capitalize + ":", 2, "")
+
+ methods_to_display = klass.send(x).collect do |m|
+ menu_methods << m
+ index += 1
+ m.name
+ end
+ if methods_to_display.empty?
+ STDOUT.puts " No methods"
+ end
+ formatter.wrap( methods_to_display.join(", ")
)
+ end
+ # prepare abbreviations
+ if use_readline
+ abbreviations = menu_methods.map {|m| m.name}.abbrev
+ Readline.completion_proc = proc do |string|
+ abbreviations.values.uniq.grep /^#{string}/
+ end
+ end
+ if index == 1
+ # no results
+ STDOUT.puts "No results."
+ exit
+ end
+
+ loop do
+ if use_readline
+ STDOUT.puts "\nEnter the method name you want.
You can use tab to autocomplete."
+ STDOUT.puts "Enter a blank line to exit."
+ choice_string = Readline.readline(">>
").chomp
+ else
+ STDOUT.puts "\nEnter the method name you want.
Enter a blank line to exit."
+ STDOUT.print ">> "
+ choice_string = STDIN.gets.chomp
+ end
+ if choice_string == ''
+ exit
+ end
+ choice = menu_methods.detect {|m| m.name ==
choice_string}
+ if choice.nil?
+ STDOUT.puts "No method matched
'#{choice_string}'."
+ exit
+ end
+ methods = @ri_reader.find_methods(choice.name,
+
desc.is_class_method,
+
namespaces).select {|m| m.name == choice.name}
+ method = @ri_reader.get_method(methods[0])
+ @display.display_method_info(method)
+ end
+ else
+ # The original code
+ report_class_stuff(namespaces)
+ end
else
methods = @ri_reader.find_methods(desc.method_name,
desc.is_class_method,
|