mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	Add pager support to ri, and start implementing command line options
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5205 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									313db605ed
								
							
						
					
					
						commit
						1c1d2b9c34
					
				
					 3 changed files with 211 additions and 12 deletions
				
			
		
							
								
								
									
										1
									
								
								MANIFEST
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								MANIFEST
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -262,6 +262,7 @@ lib/rdoc/parsers/parserfactory.rb
 | 
			
		|||
lib/rdoc/ri/ri_cache.rb
 | 
			
		||||
lib/rdoc/ri/ri_descriptions.rb
 | 
			
		||||
lib/rdoc/ri/ri_formatter.rb
 | 
			
		||||
lib/rdoc/ri/ri_options.rb
 | 
			
		||||
lib/rdoc/ri/ri_paths.rb
 | 
			
		||||
lib/rdoc/ri/ri_reader.rb
 | 
			
		||||
lib/rdoc/ri/ri_util.rb
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										64
									
								
								bin/ri
									
										
									
									
									
								
							
							
						
						
									
										64
									
								
								bin/ri
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -16,6 +16,7 @@ require 'rdoc/ri/ri_cache'
 | 
			
		|||
require 'rdoc/ri/ri_util'
 | 
			
		||||
require 'rdoc/ri/ri_reader'
 | 
			
		||||
require 'rdoc/ri/ri_formatter'
 | 
			
		||||
require 'rdoc/ri/ri_options'
 | 
			
		||||
 | 
			
		||||
######################################################################
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -33,19 +34,50 @@ end
 | 
			
		|||
class  RiDisplay
 | 
			
		||||
 | 
			
		||||
  def initialize
 | 
			
		||||
    @options = RI::Options.instance
 | 
			
		||||
    @options.parse
 | 
			
		||||
    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?"
 | 
			
		||||
      $stderr.puts "\nWas rdoc run to create documentation?"
 | 
			
		||||
      exit 1                   
 | 
			
		||||
    end
 | 
			
		||||
    @ri_reader = RI::RiReader.new(RI::RiCache.new(paths))
 | 
			
		||||
    @formatter = RI::RiFormatter.new(72, "     ")
 | 
			
		||||
    @formatter = RI::RiFormatter.new(@options.width, "     ")
 | 
			
		||||
  end    
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  ######################################################################
 | 
			
		||||
 | 
			
		||||
  def setup_pager
 | 
			
		||||
    require 'tempfile'
 | 
			
		||||
 | 
			
		||||
    @save_stdout = STDOUT.clone
 | 
			
		||||
    STDOUT.reopen(Tempfile.new("ri_"))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ######################################################################
 | 
			
		||||
 | 
			
		||||
  def page_output
 | 
			
		||||
    path = STDOUT.path
 | 
			
		||||
    STDOUT.reopen(@save_stdout)
 | 
			
		||||
    @save_stdout = nil
 | 
			
		||||
    paged = false
 | 
			
		||||
    for pager in [ ENV['pager'], "less", "more <" ].compact.uniq
 | 
			
		||||
      if system("#{pager} #{path}")
 | 
			
		||||
        paged = true
 | 
			
		||||
        break
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    if !paged
 | 
			
		||||
      @options.use_stdout = true
 | 
			
		||||
      puts File.read(path)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  ######################################################################
 | 
			
		||||
  
 | 
			
		||||
  def display_params(method)
 | 
			
		||||
| 
						 | 
				
			
			@ -175,18 +207,26 @@ def display_info_for(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}")
 | 
			
		||||
  setup_pager unless @options.use_stdout
 | 
			
		||||
  
 | 
			
		||||
  begin
 | 
			
		||||
    if desc.method_name.nil?
 | 
			
		||||
      report_class_stuff(namespaces)
 | 
			
		||||
    else
 | 
			
		||||
      report_method_stuff(desc.method_name, methods)
 | 
			
		||||
      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
 | 
			
		||||
 | 
			
		||||
    page_output unless @options.use_stdout
 | 
			
		||||
  ensure
 | 
			
		||||
    STDOUT.reopen(@save_stdout) if @save_stdout
 | 
			
		||||
  end
 | 
			
		||||
    
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										158
									
								
								lib/rdoc/ri/ri_options.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								lib/rdoc/ri/ri_options.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,158 @@
 | 
			
		|||
# We handle the parsing of options, and subsequently as a singleton
 | 
			
		||||
# object to be queried for option values
 | 
			
		||||
 | 
			
		||||
module RI
 | 
			
		||||
 | 
			
		||||
  VERSION_STRING = "alpha 0.1"
 | 
			
		||||
 | 
			
		||||
  class Options
 | 
			
		||||
    
 | 
			
		||||
    require 'singleton'
 | 
			
		||||
    require 'getoptlong'
 | 
			
		||||
    
 | 
			
		||||
    include Singleton
 | 
			
		||||
 | 
			
		||||
    # No not use a pager. Writable, because ri sets it if it
 | 
			
		||||
    # can't find a pager
 | 
			
		||||
    attr_accessor :use_stdout
 | 
			
		||||
 | 
			
		||||
    # The width of the output line
 | 
			
		||||
    attr_reader :width
 | 
			
		||||
    
 | 
			
		||||
    module OptionList
 | 
			
		||||
      
 | 
			
		||||
      OPTION_LIST = [
 | 
			
		||||
        [ "--help",          "-h",   nil,
 | 
			
		||||
         "you're looking at it" ],
 | 
			
		||||
             
 | 
			
		||||
        [ "--no-pager",      "-T",   nil,
 | 
			
		||||
          "Send output directly to stdout." 
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        [ "--width",         "-w",   "output width",
 | 
			
		||||
        "set the width of the output" ],
 | 
			
		||||
 | 
			
		||||
      ]
 | 
			
		||||
 | 
			
		||||
      def OptionList.options
 | 
			
		||||
        OPTION_LIST.map do |long, short, arg,|
 | 
			
		||||
          [ long, 
 | 
			
		||||
           short, 
 | 
			
		||||
           arg ? GetoptLong::REQUIRED_ARGUMENT : GetoptLong::NO_ARGUMENT 
 | 
			
		||||
          ]
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      def OptionList.strip_output(text)
 | 
			
		||||
        text =~ /^\s+/
 | 
			
		||||
        leading_spaces = $&
 | 
			
		||||
        text.gsub!(/^#{leading_spaces}/, '')
 | 
			
		||||
        $stdout.puts text
 | 
			
		||||
      end
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
      # Show an error and exit
 | 
			
		||||
      
 | 
			
		||||
      def OptionList.error(msg)
 | 
			
		||||
        $stderr.puts
 | 
			
		||||
        $stderr.puts msg
 | 
			
		||||
        $stderr.puts "\nFor help on options, try 'ri --help'\n\n"
 | 
			
		||||
        exit 1
 | 
			
		||||
      end
 | 
			
		||||
      
 | 
			
		||||
      # Show usage and exit
 | 
			
		||||
      
 | 
			
		||||
      def OptionList.usage
 | 
			
		||||
        
 | 
			
		||||
        puts
 | 
			
		||||
        puts(RI::VERSION_STRING)
 | 
			
		||||
        puts
 | 
			
		||||
        
 | 
			
		||||
        name = File.basename($0)
 | 
			
		||||
        OptionList.strip_output(<<-EOT)
 | 
			
		||||
          Usage:
 | 
			
		||||
 | 
			
		||||
            #{name} [options]  [names...]
 | 
			
		||||
 | 
			
		||||
          Display information on Ruby classes, modules, and methods.
 | 
			
		||||
          Give the names of classes or methods to see their documentation.
 | 
			
		||||
          Partial names may be given: if the names match more than
 | 
			
		||||
          one entity, a list will be shown, otherwise details on
 | 
			
		||||
          that entity will be displayed.
 | 
			
		||||
 | 
			
		||||
          Nested classes and modules can be specified using the normal
 | 
			
		||||
          Name::Name notation, and instance methods can be distinguished
 | 
			
		||||
          from class methods using "." (or "#") instead of "::".
 | 
			
		||||
 | 
			
		||||
          For example:
 | 
			
		||||
 | 
			
		||||
              ri  File
 | 
			
		||||
              ri  File.new
 | 
			
		||||
              ri  F.n
 | 
			
		||||
              ri  zip
 | 
			
		||||
 | 
			
		||||
          Note that shell quoting may be required for method names
 | 
			
		||||
          containing puncuation:
 | 
			
		||||
 | 
			
		||||
              ri 'Array.[]'
 | 
			
		||||
              ri compact\!
 | 
			
		||||
 | 
			
		||||
          Options:
 | 
			
		||||
 | 
			
		||||
      EOT
 | 
			
		||||
                                
 | 
			
		||||
        OPTION_LIST.each do |long, short, arg, desc|
 | 
			
		||||
          opt = sprintf("%20s", "#{long}, #{short}")
 | 
			
		||||
          oparg = sprintf("%-7s", arg)
 | 
			
		||||
          print "#{opt} #{oparg}"
 | 
			
		||||
          desc = desc.split("\n")
 | 
			
		||||
          if arg.nil? || arg.length < 7  
 | 
			
		||||
            puts desc.shift
 | 
			
		||||
          else
 | 
			
		||||
            puts
 | 
			
		||||
          end
 | 
			
		||||
          desc.each do |line|
 | 
			
		||||
            puts(" "*28 + line)
 | 
			
		||||
          end
 | 
			
		||||
          puts
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        exit 0
 | 
			
		||||
      end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
    # Parse command line options.
 | 
			
		||||
 | 
			
		||||
    def parse
 | 
			
		||||
 | 
			
		||||
      @use_stdout = !STDOUT.tty?
 | 
			
		||||
      @width = 72
 | 
			
		||||
      
 | 
			
		||||
      begin
 | 
			
		||||
        
 | 
			
		||||
        go = GetoptLong.new(*OptionList.options)
 | 
			
		||||
        go.quiet = true
 | 
			
		||||
        
 | 
			
		||||
        go.each do |opt, arg|
 | 
			
		||||
          case opt
 | 
			
		||||
          when "--help"      then OptionList.usage
 | 
			
		||||
          when "--no-pager"  then @use_stdout = true
 | 
			
		||||
          when "--width"
 | 
			
		||||
            begin
 | 
			
		||||
              @width = Integer(arg)
 | 
			
		||||
            rescue 
 | 
			
		||||
              $stderr.puts "Invalid width: '#{arg}'"
 | 
			
		||||
              exit 1
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        
 | 
			
		||||
      rescue GetoptLong::InvalidOption, GetoptLong::MissingArgument => error
 | 
			
		||||
        OptionList.error(error.message)
 | 
			
		||||
        
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue