Skip to content

Instantly share code, notes, and snippets.

@csirac2
Created April 13, 2012 01:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csirac2/2372519 to your computer and use it in GitHub Desktop.
Save csirac2/2372519 to your computer and use it in GitHub Desktop.
perltidy filter for Method::Signatures & friends
#!/usr/bin/perl
package main;
use strict;
use warnings;
use Perl::Tidy();
my $secret = '# __PERLTIDY_IGNORING ###';
my $secret_sub = '# __PERLTIDY_KEYWORD: ';
sub perltidy {
return Perl::Tidy::perltidy(
prefilter => \&prefilter,
postfilter => sub {
$_ = $_[0];
s/$secret//g;
s/sub\s+$secret_sub(method|func)\n/$1/g;
return $_;
}
);
}
sub prefilter {
my ($text) = @_;
return perltidy_ignore( transform_subs($text) );
}
sub transform_subs {
my ($text) = @_;
$text =~ s/\b(method|func)\b/sub${secret_sub}${1}\n/g;
return $text;
}
sub perltidy_ignore {
my ($text) = @_;
my @inputs = split( /^(#(?:<<<|>>>)(?:\s+[^\r\n]*?\Z)?)$/m, $text );
my $output = '';
my $ignoring;
foreach my $input (@inputs) {
if ($ignoring) {
die 'nested perltidy ignore comments are not supported'
if $input =~ /^#<<<(?:\s+.*)?$/;
foreach my $input_part ( split( /([\r\n]+)/, $input ) ) {
if ( $input_part =~ /^[\r\n]+$/ ) {
$output .= $input_part;
}
elsif ($input_part) {
$output .= $secret . $input_part;
}
}
$ignoring = 0;
}
elsif ( $input =~ /^(#(?:<<<)(?:\s+[^\r\n]*?\Z)?)$/m ) {
die if $ignoring;
$output .= $input;
$ignoring = 1;
}
elsif ( $input =~ /^(#(?:>>>)(?:\s+[^\r\n]*?\Z)?)$/m ) {
die if $ignoring;
$output .= $input;
}
else {
$output .= $input;
}
}
return $output;
}
perltidy();
=begin
perltidy makes a mess of code using Method::Signatures and
MooseX::Method::Signatures.
The standard hacks didn't seem to work for me if I split my method signatures
over multiple lines.
I tried using perltidy's comment notation to ignore the signature, something
like this:
method foo
#<<<
(
Str $bar where {$_ eq 'CAT' || $_ eq 'DOG'},
Blah::Blah $obj,
Str $stuff
)
#>>>
But that didn't work either; seems perltidy would arbitrarily add indent to the
following code block. I guess because block comments aren't strictly allowed there.
So this filtering tries to convert the #<<< ... #>>> block comments into
ordinary comments, which seems to make perltidy happier.
=cut
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment