ctags support for moops

368 views Asked by At

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?

2

There are 2 answers

1
sschober On

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:

  1. moving the cursor over MyPkg::MyClass and pressing CTRL-] vim can find the class definition
  2. moving the cursor over the first call of run() vim finds a definition for the function

But, there are two problems here:

  1. 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)
  2. 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.

0
Ivan Baidakou On

Thanks!

I find that very useful with other syntax-sugar libraries (i.e.Function::Parameters), although a bit improved regex for method finding:

--regex-Perl="/^[ \t]*method\s+([a-zA-Z0-9_]+)/\1/s/"