Quoting chris_guenther / freenet.de, on Fri, Feb 25, 2005 at 05:10:14PM +0900: > Hi, > > I would like to use (g)vim to browse my (and of course others') > ruby-source-code. > > - I heard about rtags.rb to build a tags file from ruby sources, but > unfortunately I cannot find it anywhere in the RAA. > I've seen that it is supposed to be in irb-tools but the RAA's download link > seems to be obsoleted. > Can anyone point me to another location where I can find it ? exhuberant ctags supports ruby, but doesn't produce as many tags as you might want. I've extended ri to produce qualified tags: class Answer def inspect end end exhuberant ctags will make a tag for Answer, and for inspect, but not for Answer.inspect. Since every class can have an inspect, this can be less than useful. Put the below file in your ruby's lib/rdoc/generators directory, and here's how I call it: .PHONY: tags tags: exctags -R lib rdoc18 -f tags lib mv tags tags.ctags sort tags.ctags tags.rdoc > tags Its not very integrated, but works well for me. Cheers, Sam Note - rdoc finds the file based on its name, it must be called this! --------------- tags_generators.rb ------------------ require 'ftools' require 'rdoc/options' require 'rdoc/template' require 'rdoc/markup/simple_markup' require 'rdoc/markup/simple_markup/to_flow' require 'cgi' require 'rdoc/ri/ri_cache' require 'rdoc/ri/ri_reader' require 'rdoc/ri/ri_writer' require 'rdoc/ri/ri_descriptions' require 'pp' module RDoc class ClassModule # FIXME - I don't think this works... def file_name if @parent.class === TopLevel @parent.file_absolute_name else @parent.file_name end end end class AnyMethod # Collect all the tokens for the method up-to and including the identifier, and the filename. def decl_string_and_file src = '' filename = nil break_on_nl = false if @token_stream @token_stream.each do |t| next unless t case t when RubyToken::TkCOMMENT # TkCOMMENT.text is "# File vpim/maker/vcard.rb, line 29" if( t.text =~ /# File (.*), line \d+/ ) filename = $1 end when RubyToken::TkNL break if break_on_nl src = '' else src << t.text end break_on_nl = true if RubyToken::TkIDENTIFIER === t end if false puts "----------------------" pp @token_stream puts "+++" puts src puts "----------------------" end end [ src, filename ] end end end module Generators class TAGSGenerator # Generators may need to return specific subclasses depending # on the options they are passed. Because of this # we create them using a factory def TAGSGenerator.for(options) new(options) end class <<self protected :new end # Set up a new HTML generator. Basically all we do here is load # up the correct output temlate def initialize(options) #:not-new: @options = options # TODO - make this a command-line option @gen_qualified = true # TODO - make this a command-line option @gen_unqualified = false # TODO - make this a command-line option @output = File.open("tags.rdoc", 'w') # TODO - make this a command-line option @dump = nil # File.open("rdoc.dump", 'w') # TODO - make this a command-line option @verbose = nil #pp options end def generate(toplevels) # This takes +8 minutes on vPim! Wow! PP.pp( toplevels, @dump ) if @dump RDoc::TopLevel.all_classes_and_modules.each do |cls| process_class(cls) end end def process_class(from_class) generate_class_info(from_class) # now recure into this classes constituent classess from_class.each_classmodule do |mod| process_class(mod) end end def generate_class_info(cls) # TODO: # - when generating qualified names, generate the intermediate qualified as well, so # all of these: # Outer.Middle.Inner.a_method # Middle.Inner.a_method # Inner.a_method # a_method =begin # TODO: can't do classes and modules, we don't have the original text tokens to reconstruct # the tag's REGEX. if cls === RDoc::NormalModule tag_type = 'c' else tag_type = 'm' end @output.puts tag = "#{cls.name}\t#{cls.file_name}\t/^class *#{cls.name}/;"\t#{tag_type}" if @gen_qualified && cls.name != cls.full_name @output.puts "#{cls.full_name.gsub('::', '.')}\t#{cls.file_name}\t/^class *#{cls.name}/;\"\t#{tag_type}" end =end cls.method_list.each do |m| if m.singleton tag_type = 'F' else tag_type = 'f' end decl_string, decl_file = m.decl_string_and_file puts "Tagging: #{m.name} in: #{cls.full_name} from: #{decl_file}" if @verbose tag = "#{m.name}\t#{decl_file}\t/^#{decl_string}$/;\"\t#{tag_type}" if @gen_unqualified @output.puts tag end if @gen_qualified path = cls.full_name.split('::') (1..path.length).each do |elements| qualifier = path[-elements, elements].join('.') puts " ..#{qualifier}" if @verbose @output.puts "#{qualifier}.#{tag}" end end end # TODO: It would be great to tag attributes and contstants # cls.attributes.each do |a| # cls.constants.each do |c| end end end