Let's add Git userdiff defaults for Perl and Perl 6
Git allows you to define a custom
hunk-header
which'll be used by git diff
as the context line in diff
hunks. Git includes presets for several
languages
but no presets for Perl and Perl 6. I'd like to change that.
If you have no idea what these are, consider a file that contains this code:
sub foo {
my $x = "a";
my $y = "b";
my $z = "c";
my $poem = <<"POEM";
This is a
Long string
In a heredoc
POEM
I'm::On::A::Horse();
}
Now, if you change the last statement in that subroutine to
something more clever and run git diff
you'll get this:
diff --git a/file.pl b/file.pl
index 7ed4207..ffb1ff9 100644
--- a/file.pl
+++ b/file.pl
@@ -7,5 +7,5 @@ This is a
Long string
In a heredoc
POEM
- I'm::On::A::Horse();
+ The::Tickets::Are::Now::Diamonds();
}
In that diff this is the context line:
@@ -7,5 +7,5 @@ This is a
Having "This is a" there doesn't provide very useful context, but that
can be changed with userdiff, just add this to .gitattributes
:
*.pl diff=perl
And this to .git/config:
[diff "perl"]
xfuncname = "^\\s*(sub.*)"
And the hunk context is now more useful, and shows the name of the subroutine that's being changed:
@@ -7,5 +7,5 @@ sub foo {
I'd like to extend the Git defaults to include Perl, but I'm
probably forgetting some cases where something is subroutine-ish
that doesn't match simply "\\s*(sub.*)"
. Other cases I can think of are:
- The package statement
- my $x = sub { ... } (needs a complex regex to match `my/our
...) - The BEGIN/INIT/END etc. routines
- Maybe "method ..." from MooseX::Declare and friends? It shouldn't hurt to include this
- Something else?
Then there's the issue of Perl 6. I'm completely unfamiliar with it, but I can add it while I'm at it if I'm given some examples.
The userdiff facility also has support for defining a "word" for the
--word-diff
option to git diff
. I don't use this option, but I wouldn't be
surprised if it did the wrong thing for Perl code.
I would add 'has' and all the method modifiers (around, before, after, override, etc...) from Moose.
For Perl 6, instead of just 'sub', it's probably good to use
multi|sub|submethod|method|macro
Not sure if it's also a good idea to include BEGIN|END|INIT|CHECK etc., probably not.
This is over a decade later, but git now has this in core with many more patterns. See userdiff.c (which you already linked to). You still have to associate the file endings with a the
perl
driver as you show.There's a big caveat: the pattern only matches against lines that aren't shown in the hunk. For example, if you change the first line after
sub foo
, thesub foo {
line shows up as part of the hunk context and is not searched for the pattern. This threw me for a bit, but I guess it makes sense when. you can see the subroutine in the context. Things would be much more complicated if git tried to do this in some other way than line-oriented matching on stuff before the context.