ctags support for moops

ctags, exuberant-ctags, moops, perl, vim

Solution

I can add regular expressions to ctags extending the built-in perl language like so:

$ ctags \
--regex-Perl="/^[ \t]*method\s+([a-zA-Z0-9]+)/\1/s/" \
--regex-Perl="/^\s*class\s+([a-zA-Z0-9:]+)/\1/p/" \
-R .

or I can put them in my `~/.ctags` file (omitting the quotes)

Assuming we have a small project:

$ tree
.
├── MyPkg
│   ├── MyClass.pm
│   └── MyOtherClass.pm
└── myscript.pl

With `MyPkg/MyClass.pm`:

use Moops;

class MyPkg::MyClass {
  method run( ArrayRef $args ){
  }
}

and `MyPkg/MyOtherClass.pm`:

use Moops;
package MyPkg;

class MyOtherClass {
  method run( ArrayRef $args ){
  }
}

Note the alternate syntax here. The package name gets prepended to the class name resulting in `MyPkg::MyOtherClass`.

Finally, `myscript.pl`:

#!/usr/bin/env perl
use MyPkg::MyClass;
use MyPkg::MyOtherClass;

MyPkg::MyClass->new()->run(\@ARGV);
MyPkg::MyOtherClass->new()->run(\@ARGV);

Calling `ctags` with the additional regex definitions mentioned above, the resulting tag file looks like this:

MyOtherClass    MyPkg/MyOtherClass.pm   /^class MyOtherClass {$/;"  p
MyPkg   MyPkg/MyOtherClass.pm   /^package MyPkg;$/;"    p
MyPkg::MyClass  MyPkg/MyClass.pm    /^class MyPkg::MyClass {$/;"    p
run MyPkg/MyClass.pm    /^  method run( ArrayRef $args ){$/;"   s
run MyPkg/MyOtherClass.pm   /^  method run( ArrayRef $args ){$/;"   s

This almost works:

- moving the cursor over `MyPkg::MyClass` and pressing `CTRL-]` vim can find the class definition

- moving the cursor over the first call of `run()` vim finds a definition for the function

But, there are two problems here:

- in the case of the first call of `run()` vim cannot unambigously decide which function is called, as it lacks context; you have to decide for yourself (using `:ts`)

- moving the cursor over `MyPkg::MyOtherClass` vim cannot find a tag at all

So, in conclusion, my best practise for `Moops`, `vim` and `ctags` would be to always declare classes fully qualified.

Problem

Moops enhances the perl syntax by constructs such as: ``` class MyPkg::MyClass { # ... } ``` and adds the possibility to declare signatures for member functions by introducing the new keywords `fun` and `method`: ``` class MyPkg::MyClass { method run(ArrayRef $ar){ } } ``` I use vim and tag files to navigate my code base, but those new keywords are unknown to `ctags`, so classes, functions and methods are not indexed. How can I improve the situation?

Original source