# Ruby + vim + rtags.rb

**URL:** <https://rubytalk.org/t/ruby-vim-rtags-rb/16697>\
**Category:** ruby-talk\
**Created:** [25 February 2005 08:10 UTC](https://rubytalk.org/t/ruby-vim-rtags-rb/16697 "2005-02-25T08:10:14Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chris\_Guenther](https://avatars.discourse-cdn.com/v4/letter/c/bc8723/32.png) [@Chris\_Guenther](https://rubytalk.org/u/Chris_Guenther)\
**Post date:** [25 February 2005 08:10 UTC](https://rubytalk.org/t/ruby-vim-rtags-rb/16697/1 "2005-02-25T08:10:14Z")

</div>

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 ?

- I was also wondering wether there exists a prebuilt gvim6.3 windows  
executable with builtin support for ruby-interpretation ?

Thanks a lot in advance,  
Chris

---

<div class="post-metadata">

**Author:** ![Kaspar\_Schiess](https://avatars.discourse-cdn.com/v4/letter/k/d78d45/32.png) [@Kaspar\_Schiess](https://rubytalk.org/u/Kaspar_Schiess)\
**Post date:** [25 February 2005 08:29 UTC](https://rubytalk.org/t/ruby-vim-rtags-rb/16697/2 "2005-02-25T08:29:53Z")

</div>

Good choice, vim just rocks.

> - I was also wondering wether there exists a prebuilt gvim6.3 windows  
> executable with builtin support for ruby-interpretation ?

Try this here:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Cream :: a modern configuration of the Vim text editor](http://cream.sourceforge.net/vim.html)

Last time I looked, it did include Ruby support. I now run a custom version  
since I did not have use for the Ruby scripting. Be sure to either take a  
6.2 or a late 6.3 version, since early 6.3 had problems with Ruby folding.

k

---

<div class="post-metadata">

**Author:** ![Sam\_Roberts1](https://avatars.discourse-cdn.com/v4/letter/s/ed8c4c/32.png) [@Sam\_Roberts1](https://rubytalk.org/u/Sam_Roberts1)\
**Post date:** [25 February 2005 13:35 UTC](https://rubytalk.org/t/ruby-vim-rtags-rb/16697/3 "2005-02-25T13:35:51Z")

</div>

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:

&nbsp;&nbsp;class Answer  
&nbsp;&nbsp;&nbsp;&nbsp;def inspect  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;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:

&nbsp;&nbsp;.PHONY: tags  
&nbsp;&nbsp;tags:  
&nbsp;&nbsp;&nbsp;&nbsp;exctags -R lib  
&nbsp;&nbsp;&nbsp;&nbsp;rdoc18 -f tags lib  
&nbsp;&nbsp;&nbsp;&nbsp;mv tags tags.ctags  
&nbsp;&nbsp;&nbsp;&nbsp;sort tags.ctags tags.rdoc \> tags  
&nbsp;&nbsp;  
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  
&nbsp;&nbsp;class ClassModule  
&nbsp;&nbsp;&nbsp;&nbsp;# FIXME - I don't think this works...  
&nbsp;&nbsp;&nbsp;&nbsp;def file\_name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @parent.class === TopLevel  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@parent.file\_absolute\_name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@parent.file\_name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
&nbsp;&nbsp;class AnyMethod  
&nbsp;&nbsp;&nbsp;&nbsp;# Collect all the tokens for the method up-to and including the identifier, and the filename.  
&nbsp;&nbsp;&nbsp;&nbsp;def decl\_string\_and\_file  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src = ''  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filename = nil  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break\_on\_nl = false  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @token\_stream  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@token\_stream.each do |t|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next unless t  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case t  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when RubyToken::TkCOMMENT  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# TkCOMMENT.text is "# File vpim/maker/vcard.rb, line 29"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( t.text =~ /# File (.\*), line \d+/ )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filename = $1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when RubyToken::TkNL  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break if break\_on\_nl  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src = ''  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src \<\< t.text  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break\_on\_nl = true if RubyToken::TkIDENTIFIER === t  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if false  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "----------------------"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pp @token\_stream  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "+++"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts src  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "----------------------"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[src, filename]  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

module Generators

&nbsp;&nbsp;class TAGSGenerator

&nbsp;&nbsp;&nbsp;&nbsp;# Generators may need to return specific subclasses depending  
&nbsp;&nbsp;&nbsp;&nbsp;# on the options they are passed. Because of this  
&nbsp;&nbsp;&nbsp;&nbsp;# we create them using a factory

&nbsp;&nbsp;&nbsp;&nbsp;def TAGSGenerator.for(options)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new(options)  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;class \<\<self  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected :new  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;# Set up a new HTML generator. Basically all we do here is load  
&nbsp;&nbsp;&nbsp;&nbsp;# up the correct output temlate

&nbsp;&nbsp;&nbsp;&nbsp;def initialize(options) #:not-new:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@options = options

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# TODO - make this a command-line option  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@gen\_qualified = true

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# TODO - make this a command-line option  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@gen\_unqualified = false

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# TODO - make this a command-line option  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@output = File.open("tags.rdoc", 'w')

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# TODO - make this a command-line option  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@dump = nil # File.open("rdoc.dump", 'w')

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# TODO - make this a command-line option  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@verbose = nil

#pp options  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;def generate(toplevels)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# This takes +8 minutes on vPim! Wow!  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PP.pp( toplevels, @dump ) if @dump

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RDoc::TopLevel.all\_classes\_and\_modules.each do |cls|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process\_class(cls)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;def process\_class(from\_class)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;generate\_class\_info(from\_class)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# now recure into this classes constituent classess  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from\_class.each\_classmodule do |mod|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process\_class(mod)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;def generate\_class\_info(cls)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# TODO:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# - when generating qualified names, generate the intermediate qualified as well, so  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# all of these:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Outer.Middle.Inner.a\_method  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Middle.Inner.a\_method  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Inner.a\_method  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# a\_method

=begin  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# TODO: can't do classes and modules, we don't have the original text tokens to reconstruct  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# the tag's REGEX.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if cls === RDoc::NormalModule  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag\_type = 'c'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag\_type = 'm'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@output.puts tag = "#{cls.name}\t#{cls.file\_name}\t/^class \*#{cls.name}/;"\t#{tag\_type}"

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @gen\_qualified && cls.name != cls.full\_name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@output.puts "#{cls.full\_name.gsub('::', '.')}\t#{cls.file\_name}\t/^class \*#{cls.name}/;\"\t#{tag\_type}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
=end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cls.method\_list.each do |m|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if m.singleton  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag\_type = 'F'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag\_type = 'f'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;decl\_string, decl\_file = m.decl\_string\_and\_file

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "Tagging: #{m.name} in: #{cls.full\_name} from: #{decl\_file}" if @verbose

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag = "#{m.name}\t#{decl\_file}\t/^#{decl\_string}$/;\"\t#{tag\_type}"

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @gen\_unqualified  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@output.puts tag  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @gen\_qualified  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path = cls.full\_name.split('::')  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1..path.length).each do |elements|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;qualifier = path[-elements, elements].join('.')

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts " ..#{qualifier}" if @verbose

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@output.puts "#{qualifier}.#{tag}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# TODO: It would be great to tag attributes and contstants  
# cls.attributes.each do |a|  
# cls.constants.each do |c|  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;end  
end
