-
Notifications
You must be signed in to change notification settings - Fork 1
/
perl-etags.pl
executable file
·117 lines (83 loc) · 2.36 KB
/
perl-etags.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
use List::MoreUtils qw{ any };
use Path::Tiny qw{ path };
sub wanted {
my ($path, $state) = @_;
return if $path->is_dir
|| $path !~ /\.p[lm]$/;
my $code = $path->slurp;
my %found;
for my $regex (
qr/^(\s* (sub | method | fun) \s+ (\w+)) /xm,
qr/^(\s* (alias) \s+ (\w+)) /xm,
qr/^(\s* (has) \s+ (?:["']\+?)? (\w+)) /xm,
qr/^(\s* (has) \s+ \[ \s* qw \s* . \s* ([^)\]\/>]+)) /xm,
qr/^(\s* \{? \s* (package) \s+ ([\w:]+)) /xm,
) {
while ($code =~ /$regex/g) {
my ($full, $keyword, $funcs) = ($1, $2, $3);
for my $func (split ' ', $funcs) {
my $pos = pos($code) - length $full;
my $nl_count = substr($code, 0, $pos) =~ tr/\n//;
my ($single_line) = $full =~ /(.*\Q$func\E.*)/g;
$found{$keyword}{$func} = [$nl_count + 1, $pos, $single_line];
}
}
}
return unless keys %found;
say "\cl";
my $string = join "\n",
map {
my $keyword = $_;
map "$found{$keyword}{$_}[2]\x7f"
. "$_\x01"
. "$found{$keyword}{$_}[0],$found{$keyword}{$_}[1]",
keys %{ $found{$keyword} }
}
keys %found;
say $path, ',', 1 + length $string;
say $string;
}
sub main {
path('.')->visit(\&wanted, { recurse => 1 });
}
main();
=head1 NAME
perl-etags.pl
=head1 SYNOPSIS
cd /project/root && perl-etags.pl > TAGS
=head1 DESCRIPTION
Creates TAGS file similar to what the command C<etags> produces, but
tries to handle C<Moose> keywords as well (C<has>, C<alias>).
=head1 AUTHOR
(c) 2016 E. Choroba
=cut
__END__
# Tested on the following:
# ------------------------
#!/usr/bin/perl
use warnings;
use strict;
package Etags::Test;
use Moose;
use MooseX::Aliases;
has bare => (is => 'rw');
has 'quoted' => (is => 'rw');
has "double_quoted" => (is => 'rw');
has [qw[ list1 list2 ]] => (is => 'ro');
has [qw[ multi
line
]] => (is => 'ro');
sub method {}
sub
method2 {}
alias m2 => 'method2';
use MooseX::Declare;
class Etags::Test2 {
method method3 (Num $count) {}
}
{ package Inner::Package;
}