Quoting (e-mail address removed), 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