summaryrefslogtreecommitdiff
path: root/lib/rdoc/ri/display.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rdoc/ri/display.rb')
-rw-r--r--lib/rdoc/ri/display.rb201
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
##