From d3e92ce85e33191d2bbdf5bbb0d2afdd31dbd162 Mon Sep 17 00:00:00 2001 From: dave Date: Tue, 16 Dec 2003 05:44:25 +0000 Subject: Initial load of support for ri/rdoc integration git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@5199 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- bin/ri | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100755 bin/ri (limited to 'bin') diff --git a/bin/ri b/bin/ri new file mode 100755 index 000000000..899fc2dd2 --- /dev/null +++ b/bin/ri @@ -0,0 +1,201 @@ +#!/usr/bin/env ruby +# usage: +# +# ri name... +# +# where name can be +# +# Class | Class::method | Class#method | Class.method | method +# +# All names may be abbreviated to their minimum unbiguous form. If a name +# _is_ ambiguous, all valid options will be listed. +# + +require 'rdoc/ri/ri_paths' +require 'rdoc/ri/ri_cache' +require 'rdoc/ri/ri_util' +require 'rdoc/ri/ri_reader' +require 'rdoc/ri/ri_formatter' + +###################################################################### + +def display_usage + File.open(__FILE__) do |f| + f.gets + puts $1 while (f.gets =~ /^# ?(.*)/) + end + exit +end + + +###################################################################### + +class RiDisplay + + def initialize + paths = RI::Paths::PATH + if paths.empty? + $stderr.puts "No ri documentation found in:" + [ RI::Paths::SYSDIR, RI::Paths::SITEDIR, RI::Paths::HOMEDIR].each do |d| + $stderr.puts " #{d}" + end + $stderr.puts "\nIs ri correctly installed?" + exit 1 + end + @ri_reader = RI::RiReader.new(RI::RiCache.new(paths)) + @formatter = RI::RiFormatter.new(72, " ") + end + + ###################################################################### + + def display_params(method) + params = method.params + if params[0,1] == "(" + if method.is_singleton + params = method.full_name + params + else + params = method.name + params + end + end + @formatter.wrap(params) + end + + ###################################################################### + + def display_flow(flow) + if !flow || flow.empty? + @formatter.wrap("(no description...)") + else + @formatter.display_flow(flow) + end + end + +###################################################################### + +def display_method_info(method_entry) + method = @ri_reader.get_method(method_entry) + @formatter.draw_line(method.full_name) + display_params(method) + @formatter.draw_line + display_flow(method.comment) + if method.aliases && !method.aliases.empty? + @formatter.blankline + aka = "(also known as " + aka << method.aliases.map {|a| a.name }.join(", ") + aka << ")" + @formatter.wrap(aka) + end +end + +###################################################################### + +def display_class_info(class_entry) + klass = @ri_reader.get_class(class_entry) + @formatter.draw_line("Class: " + klass.full_name) + display_flow(klass.comment) + @formatter.draw_line + + unless klass.constants.empty? + @formatter.blankline + @formatter.wrap("Constants:", "") + len = 0 + klass.constants.each { |c| len = c.name.length if c.name.length > len } + len += 2 + klass.constants.each do |c| + @formatter.wrap(c.value, + @formatter.indent+((c.name+":").ljust(len))) + end + end + + unless klass.method_list.empty? + @formatter.blankline + @formatter.wrap("Methods:", "") + @formatter.wrap(klass.method_list.map{|m| m.name}.sort.join(', ')) + end + + unless klass.attributes.empty? + @formatter.blankline + @formatter.wrap("Attributes:", "") + @formatter.wrap(klass.attributes.map{|a| a.name}.sort.join(', ')) + end +end + +###################################################################### + +# If the list of matching methods contains exactly one entry, or +# if it contains an entry that exactly matches the requested method, +# then display that entry, otherwise display the list of +# matching method names + +def report_method_stuff(requested_method_name, methods) + if methods.size == 1 + display_method_info(methods[0]) + elsif (entry = methods.find {|m| m.name == requested_method_name}) + display_method_info(entry) + else + puts "More than one method matched your request. You can refine" + puts "your search by asking for information on one of:\n\n" + @formatter.wrap(methods.map {|m| m.full_name} .join(", ")) + end +end + +###################################################################### + +def report_class_stuff(namespaces) + if namespaces.size > 1 + puts "More than one class or module matched your request. You can refine" + puts "your search by asking for information on one of:\n\n" + puts @formatter.wrap("", namespaces.map {|m| m.full_name} .join(", ")) + else + class_desc = @ri_reader.get_class(namespaces[0]) + display_class_info(namespaces[0]) + end +end + +###################################################################### + + +def display_info_for(arg) + desc = NameDescriptor.new(arg) + + namespaces = @ri_reader.top_level_namespace + + for class_name in desc.class_names + namespaces = @ri_reader.lookup_namespace_in(class_name, namespaces) + if namespaces.empty? + raise RiError.new("Nothing known about #{arg}") + end + end + + if desc.method_name.nil? + report_class_stuff(namespaces) + else + methods = @ri_reader.find_methods(desc.method_name, + desc.is_class_method, + namespaces) + + if methods.empty? + raise RiError.new("Nothing known about #{arg}") + else + report_method_stuff(desc.method_name, methods) + end + end + +end +end + +###################################################################### + +if ARGV.size.zero? + display_usage +else + ri = RiDisplay.new + begin + ARGV.each do |arg| + ri.display_info_for(arg) + end + rescue RiError => e + $stderr.puts(e.message) + exit(1) + end +end -- cgit