Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ctags support for moops

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?

like image 313
sschober Avatar asked Feb 04 '14 16:02

sschober


2 Answers

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.

like image 129
sschober Avatar answered Oct 25 '22 04:10

sschober


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/"

like image 41
Ivan Baidakou Avatar answered Oct 25 '22 04:10

Ivan Baidakou