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.