Do You Know an Alternative Ctags Generator for Ruby

Do you know an alternative ctags generator for Ruby

Exuberant ctags out of the box doesn’t do a number of useful things:

  • It doesn’t deal with:

    module A::B
  • It doesn’t tag (at least some of) the “operator” methods like ‘==’

  • It doesn’t support qualified tags, —type=+

  • It doesn’t output tags for constants or attributes.

Patch available, but it is only for version 5.5 and does not work anymore.

Other projects:

  • https://github.com/tmm1/ripper-tags (best option for Ruby 1.9+)
  • https://rubygems.org/gems/rdoc-tags (very slow but works with 1.8)

Source

Generate ctags for Ruby and Javascript

Adding --tag-relative and --sort=yes fixed the problem.

ctags --tag-relative -R --sort=yes --languages=ruby,javascript --exclude=.git --exclude=log . $(bundle list --paths)

Is there an alternative to ctags that works better?

I've spent quite some time struggling with this myself.

The closest I ever got was something called gccsense. Unfortunately, the project seems abandoned and moreover it was difficult setting it up because English was not the author's first language.

I ended up approaching the problem from another angle. I made the decision that intellisense/autocomplete was more important to my coding than having all the available features of vim, so I chose an IDE like Eclipse, and then found a plugin for Eclipse that emulates Vim. So far the best kind of plugin like that that I found was Viable.

Here is the full list of options that I have tried and found unsatisfactory:

  • clang - requires you switch from gcc to a different and "better" compiler. The problem is gcc is much more mature [edit apparently you don't need to switch compilers see comments below, I may give this another try in the future.]
  • gccsense - great idea (using gcc to give you the code completion) however work on the project is abandoned :( and the version that is up is beta quality
  • xref in vim - xref is a great standalone tool and works great for parsing C. It can be made to work in vim with vxref, however from my experience xref lacks in parsing current C++ code and development on it has stopped (as well as development on vxref.)
  • eclim - seems to work great for Java support using eclipse, extremely slow and completely unreliable when parsing C++ or C code. What usually happens is everything works for a long while, but then suddenly, the parser stops parsing any new code that you write, and nothing short of loading up eclipse itself and forcing eclipse to reparse the project seems to help. Also, less of an important fact, but more of an annoyance is that eclim takes over handling errors, so it screws up the way vim usually parses errors from gcc meaning you have no access to the quickfix list which is annoying.
  • netbeans + jvi - alot of people swear by this, but I had all sorts of problems with jvi. One major problem I had was jvi would say I'm in normal mode, but really was in insert mode, nothing short of a restart would help.
  • eclipse + viplugin/vrapper - this was beginning to look like the best option; each had its own set of bugs + lacking features, but still was most attractive, until I found viable which seemed to be the most stable and have the most features.

If you do find a solution you are happy with please share it in a comment, because I would be interested in it.

gem-ctags won't generate any tag

This is the solution from @larrylv, and it's work.

Remove gem plugin for zshrc, it will make conflict in your gem path.
after that, source zshrc file and run gem ctags again.

You can chase your gem path by using gem env home.
It should be like /Users/<your name>/<your ruby manager>/versions/<your ruby version>/lib/ruby/gems/

can't generate tag __mrs_s from #define __mrs_s(v, r) in a file.. even using --excmd=pattern

There is no simple way to satisfy the goal.

sysreg.h contains assembly language code that makes the C++ indexer of ctags confused. See https://elixir.bootlin.com/linux/v5.4.21/source/arch/arm64/include/asm/sysreg.h#L741

(It would be nice to add a feature to the C++ indexer to skip __ASSEMBLY__ and __ASSEMBLER__ area.)

I found one hacky technique that works only with Universal ctags (https://ctags.io). Your ctags may be Exuberant Ctags. So the technique I will write here may not work with your ctags.

$ ./ctags --version
./ctags --version
Universal Ctags 5.9.0(692f5fd15), Copyright (C) 2015 Universal Ctags Team
Universal Ctags is derived from Exuberant Ctags.
Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
Compiled: Feb 6 2022, 06:19:35
URL: https://ctags.io/
Optional compiled features: +wildcards, +regex, +gnulib_regex, +iconv, +debug, +option-directory, +xpath, +json, +interactive, +sandbox, +yaml, +packcc, +optscript, +pcre2
$ ./ctags --options=NONE -Dendm='endm;' -o - /tmp/sysreg.h | grep __msr_s
./ctags --options=NONE -Dendm='endm;' -o - /tmp/sysreg.h | grep __msr_s
ctags: Notice: No options will be read from files or environment
__msr_s /tmp/sysreg.h /^#define __msr_s(/;" d

The option -D... replaces the words endm in the __ASSEMBLY__ area with endm;. The appended semicolon characters mitigate the indexer's confusion.

ctags match if not comment

I think I figured it out and it is easier than I thought:

--regex-latex=/^[[:space:]]*[^%]+\\section[[:space:]]*(\[[^]]*\])?[[:space:]]*\{([^}]+)\}/\. \2/s,section/

should simply be

--regex-latex=/^[[:space:]]*[^%]*\\section[[:space:]]*(\[[^]]*\])?[[:space:]]*\{([^}]+)\}/\. \2/s,section/

So instead of [^%]+, I changed it to [^%]*.
I don't think I understand why, but it seems to work.

Include ctags files recursively from a directory

:help 'tags' explains:

The filename itself cannot contain wildcards, it is used as-is.

So you either need to explicitly add all tags on startup:

for tagfile in split(glob('~/.ctags/*'), "\n")
let &tags .= ',' . tagfile
endfor

or change your tag generation to put identically named files in subdirectories. Then you can use the * wildcard to include them all:

set tags+=~/.ctags/*/tags

I haven't used tags that much, but I think it is a good practice to separate them. After all, Vim does support multiple tag file locations.

How to combine multiple ctags-like tags tools?

Your hypothetical omni-tags command would be easy to implement in shell or any scripting language (Perl, Python, Ruby, whatever) assuming you were only dealing with projects with one particular kind of source code. Just recursively scan a project directory, look for the predominant type of file within it (by matching file extensions, or using the Unix file program) and then run the tags-generation program associated with that particular kind of source file.

This would get more difficult, but not impossible, if you have a project containing code in multiple languages. One example would be a Ruby gem containing both Ruby .rb source files and some .c and .h files implementing a native C extension. In this case the Ruby and C files are usually fairly cleanly separated--i.e., one directory tree under the root directory of the gem is all Ruby, and another is all C. So omni-tags could probably be written to recognize this case and run ctags on the .c and .h files and ripper-tags on the .rb files. Since most editors can integrate multiple tags files per project (at least, I know Emacs can), you would then be able to navigate between a symbol defined in the C source and used in the Ruby source (for example).

The trickiest part would be how to deal with code bases where multiple languages are intermingled that you want to tag. For your JavaScript example, are you likely to have a directory containing both JavaScript and CoffeeScript files, for instance? In this case omni-tags needs to run the tool appropriate to each language on each source file. If the tags-generating tools are written to ignore any file not of the right type, you could just run each from the root directory of your project and then, again, use an editor that integrates multiple tags files. If the tools need to be fed only the right kind of files, then omni-tags needs to build an index of the files in question and then feed the names of only the correct files to each tool. It's not impossible, but would require a bit more work (in contrast to the simplest case described in the first paragraph, which would probably be doable in about 10 lines of Python or Ruby).



Related Topics



Leave a reply



Submit