diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-09-25 02:43:03 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-09-25 02:43:03 +0000 |
commit | 858362e761a41e7d96efbcb9b38ae815b1e388d7 (patch) | |
tree | b47a0968d921320591f9218bc746e11a7922c53f /lib/rdoc/ri/display.rb | |
parent | 00b4a3f9c4aaf5aa038a9530ec515e1718ae1c42 (diff) | |
download | ruby-858362e761a41e7d96efbcb9b38ae815b1e388d7.tar.gz |
Import RDoc 2.2.1 r185
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19537 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rdoc/ri/display.rb')
-rw-r--r-- | lib/rdoc/ri/display.rb | 201 |
1 files changed, 160 insertions, 41 deletions
diff --git a/lib/rdoc/ri/display.rb b/lib/rdoc/ri/display.rb index 379cef11b3..05a7cf253d 100644 --- a/lib/rdoc/ri/display.rb +++ b/lib/rdoc/ri/display.rb @@ -1,5 +1,15 @@ require 'rdoc/ri' +# readline support might not be present, so be careful +# when requiring it. +begin + require('readline') + require('abbrev') + CAN_USE_READLINE = true +rescue + CAN_USE_READLINE = false +end + ## # This is a kind of 'flag' module. If you want to write your own 'ri' display # module (perhaps because you're writing an IDE), you write a class which @@ -41,7 +51,7 @@ class RDoc::RI::DefaultDisplay # Display information about +klass+. Fetches additional information from # +ri_reader+ as necessary. - def display_class_info(klass, ri_reader) + def display_class_info(klass) page do superclass = klass.superclass_string @@ -61,17 +71,11 @@ class RDoc::RI::DefaultDisplay @formatter.blankline @formatter.display_heading("Includes:", 2, "") incs = [] + klass.includes.each do |inc| - inc_desc = ri_reader.find_class_by_name(inc.name) - if inc_desc - str = inc.name + "(" - str << inc_desc.instance_methods.map{|m| m.name}.join(", ") - str << ")" - incs << str - else - incs << inc.name - end - end + incs << inc.name + end + @formatter.wrap(incs.sort.join(', ')) end @@ -82,42 +86,19 @@ class RDoc::RI::DefaultDisplay constants = klass.constants.sort_by { |constant| constant.name } constants.each do |constant| + @formatter.wrap "#{constant.name} = #{constant.value}" if constant.comment then - @formatter.wrap "#{constant.name}:" - @formatter.indent do @formatter.display_flow constant.comment end else - @formatter.wrap constant.name + @formatter.break_to_newline end end end - class_data = [ - :class_methods, - :class_method_extensions, - :instance_methods, - :instance_method_extensions, - ] - - class_data.each do |data_type| - data = klass.send data_type - - unless data.empty? then - @formatter.blankline - - heading = data_type.to_s.split('_').join(' ').capitalize << ':' - @formatter.display_heading heading, 2, '' - - data = data.map { |item| item.name }.sort.join ', ' - @formatter.wrap data - end - end - unless klass.attributes.empty? then @formatter.blankline - @formatter.display_heading 'Attributes:', 2, '' attributes = klass.attributes.sort_by { |attribute| attribute.name } @@ -130,11 +111,119 @@ class RDoc::RI::DefaultDisplay end else @formatter.wrap "#{attribute.name} (#{attribute.rw})" + @formatter.break_to_newline end end end + + return display_class_method_list(klass) end end + + ## + # Given a Hash mapping a class' methods to method types (returned by + # display_class_method_list), this method allows the user to + # choose one of the methods. + + def get_class_method_choice(method_map) + if CAN_USE_READLINE + # prepare abbreviations for tab completion + abbreviations = method_map.keys.abbrev + Readline.completion_proc = proc do |string| + abbreviations.values.uniq.grep(/^#{string}/) + end + end + + @formatter.raw_print_line "\nEnter the method name you want.\n" + @formatter.raw_print_line "Class methods can be preceeded by '::' and instance methods by '#'.\n" + + if CAN_USE_READLINE + @formatter.raw_print_line "You can use tab to autocomplete.\n" + @formatter.raw_print_line "Enter a blank line to exit.\n" + + choice_string = Readline.readline(">> ").strip + else + @formatter.raw_print_line "Enter a blank line to exit.\n" + @formatter.raw_print_line ">> " + choice_string = $stdin.gets.strip + end + + if choice_string == '' + return nil + else + class_or_instance = method_map[choice_string] + + if class_or_instance + # If the user's choice is not preceeded by a '::' or a '#', figure + # out whether they want a class or an instance method and decorate + # the choice appropriately. + if(choice_string =~ /^[a-zA-Z]/) + if(class_or_instance == :class) + choice_string = "::#{choice_string}" + else + choice_string = "##{choice_string}" + end + end + + return choice_string + else + @formatter.raw_print_line "No method matched '#{choice_string}'.\n" + return nil + end + end + end + + + ## + # Display methods on +klass+ + # Returns a hash mapping method name to method contents (HACK?) + + def display_class_method_list(klass) + method_map = {} + + class_data = [ + :class_methods, + :class_method_extensions, + :instance_methods, + :instance_method_extensions, + ] + + class_data.each do |data_type| + data = klass.send data_type + + unless data.nil? or data.empty? then + @formatter.blankline + + heading = data_type.to_s.split('_').join(' ').capitalize << ':' + @formatter.display_heading heading, 2, '' + + method_names = [] + data.each do |item| + method_names << item.name + + if(data_type == :class_methods || + data_type == :class_method_extensions) then + method_map["::#{item.name}"] = :class + method_map[item.name] = :class + else + # + # Since we iterate over instance methods after class methods, + # an instance method always will overwrite the unqualified + # class method entry for a class method of the same name. + # + method_map["##{item.name}"] = :instance + method_map[item.name] = :instance + end + end + method_names.sort! + + @formatter.wrap method_names.join(',') + end + end + + method_map + end + private :display_class_method_list ## # Display an Array of RDoc::Markup::Flow objects, +flow+. @@ -172,10 +261,42 @@ class RDoc::RI::DefaultDisplay def display_method_list(methods) page do @formatter.wrap "More than one method matched your request. You can refine your search by asking for information on one of:" + @formatter.blankline + methods.each do |method| + @formatter.raw_print_line "#{method.full_name} [#{method.source_path}]\n" + end + end + end + + ## + # Display a list of +methods+ and allow the user to select one of them. + + def display_method_list_choice(methods) + page do + @formatter.wrap "More than one method matched your request. Please choose one of the possible matches." @formatter.blankline - @formatter.wrap methods.map { |m| m.full_name }.join(", ") + methods.each_with_index do |method, index| + @formatter.raw_print_line "%3d %s [%s]\n" % [index + 1, method.full_name, method.source_path] + end + + @formatter.raw_print_line ">> " + + choice = $stdin.gets.strip! + + if(choice == '') + return + end + + choice = choice.to_i + + if ((choice == 0) || (choice > methods.size)) then + @formatter.raw_print_line "Invalid choice!\n" + else + method = methods[choice - 1] + display_method_info(method) + end end end @@ -198,10 +319,8 @@ class RDoc::RI::DefaultDisplay @formatter.break_to_newline end - if method.source_path then - @formatter.blankline - @formatter.wrap("Extension from #{method.source_path}") - end + @formatter.blankline + @formatter.wrap("From #{method.source_path}") end ## |