I have a perl file where some functions are defined using special syntax (Mojolicious):
$app->helper('helper1' => sub {
print "Hello 1";
});
$app->helper("helper2" => sub {
print "Hello 2";
});
$app->helper(helper3 => sub {
print "Hello 3";
});
helper1();
helper2();
helper3();
I managed to create the Perl regexp to capture these definitions:
#!/usr/bin/perl
use strict;
use warnings;
use File::Slurp 'read_file';
my $code = read_file('helpers.pl');
my @matches = $code =~ /\$app\->helper\(['"]?(.*?)['"]? => sub/g;
foreach(@matches)
{
print "$_\n";
}
Output:
helper1
helper2
helper3
But my attempt to use it in etags failed;
etags -l perl --regex="/\$app\->helper\\\(['\"]\(.*?\)['\"] => sub/" ./helpers.pl
Gives an empty TAGS file. What's wrong?
CodePudding user response:
One of your problems is your shell escapes, eg:
"\$xxx"
will end up being to$xxx
which means EOL in regex."\-"
will in a POSIX shell expand to\-
.
You should use single quoted string to hold your pattern, as the only special character in single quotes are single quotes. If the pattern should be:
/\$app->helper\(['"](.*?)['"] => sub/
Then the single quote string would be:
'/\$app->helper\(['\''"](.*?)['\''"] => sub/'
I don't use exuberant-ctags, but Universal Ctags which is never. In Universal Ctags one would need to write:
/\$app->helper\(['"](.*)['"] => sub/\1/
Notice how the non-greedy modifier isn't supported, and how I provided the keyword creation part: \1/
after the pattern.
I'll leave it as an exercise to the reader to enclose the above pattern in single quotes.
CodePudding user response:
Universal Ctags just introduced pcre2 as an optional regular expression engine. If you build a ctags executable from the latest code in the git repository (git clone https://github.com/universal-ctags/ctags.git) with pcre2, you can use non-greedy match. That means the command line Andreas Louv showed may work well.
$ cat /tmp/foo.pl
$app->helper('helper1' => sub {
print "Hello 1";
});
$app->helper("helper2" => sub {
print "Hello 2";
});
$app->helper(helper3 => sub {
print "Hello 3";
});
helper1();
helper2();
helper3();
$ ./ctags -o - --regex-perl='/\$app->helper\(['\''"]?(.*?)['\''"]? => sub/\1/s/{pcre2}' /tmp/foo.pl
helper1 /tmp/foo.pl /^$app->helper('helper1' => sub {$/;" s
helper2 /tmp/foo.pl /^$app->helper("helper2" => sub {$/;" s
helper3 /tmp/foo.pl /^$app->helper(helper3 => sub {$/;" s
$ ./ctags -e --regex-perl='/\$app->helper\(['\''"]?(.*?)['\''"]? => sub/\1/s/{pcre2}' /tmp/foo.pl
$ cat TAGS
^L
/tmp/foo.pl,133
$app->helper('helper1' => sub {^?helper1^A1,0
$app->helper("helper2" => sub {^?helper2^A5,74
$app->helper(helper3 => sub {^?helper3^A9,148
$
You can verify you whether pcre2 is linked to your ctags or not.
$ ./ctags --list-features | grep pcre2
pcre2 has pcre2 regex engine
$