10
my $COLOR = qr/\x1b\[[0-9;]*m/;
11
my $BORING = qr/$COLOR|\s/;
12
13
-my @window;
13
+my @removed;
14
+my @added;
15
+my $in_hunk;
16
17
while (<>) {
16
- # We highlight only single-line changes, so we need
17
- # a 4-line window to make a decision on whether
18
- # to highlight.
19
- push @window, $_;
20
- next if @window < 4;
21
- if ($window[0] =~ /^$COLOR*(\@| )/ &&
22
- $window[1] =~ /^$COLOR*-/ &&
23
- $window[2] =~ /^$COLOR*\+/ &&
24
- $window[3] !~ /^$COLOR*\+/) {
25
- print shift @window;
26
- show_hunk(shift @window, shift @window);
18
+ if (!$in_hunk) {
19
+ print;
20
+ $in_hunk = /^$COLOR*\@/;
21
+ }
22
+ elsif (/^$COLOR*-/) {
23
+ push @removed, $_;
24
+ }
25
+ elsif (/^$COLOR*\+/) {
26
+ push @added, $_;
27
}
28
else {
29
- print shift @window;
29
+ show_hunk(\@removed, \@added);
30
+ @removed = ();
31
+ @added = ();
32
+
33
+ print;
34
+ $in_hunk = /^$COLOR*[\@ ]/;
35
}
36
37
# Most of the time there is enough output to keep things streaming,
47
}
48
}
49
45
-# Special case a single-line hunk at the end of file.
46
-if (@window == 3 &&
47
- $window[0] =~ /^$COLOR*(\@| )/ &&
48
- $window[1] =~ /^$COLOR*-/ &&
49
- $window[2] =~ /^$COLOR*\+/) {
50
- print shift @window;
51
- show_hunk(shift @window, shift @window);
52
-}
53
-
54
-# And then flush any remaining lines.
55
-while (@window) {
56
- print shift @window;
57
-}
50
+# Flush any queued hunk (this can happen when there is no trailing context in
51
+# the final diff of the input).
52
+show_hunk(\@removed, \@added);
53
54
exit 0;
55
56
sub show_hunk {
57
my ($a, $b) = @_;
58
64
- print highlight_pair($a, $b);
59
+ # If one side is empty, then there is nothing to compare or highlight.
60
+ if (!@$a || !@$b) {
61
+ print @$a, @$b;
62
+ return;
63
+ }
64
+
65
+ # If we have mismatched numbers of lines on each side, we could try to
66
+ # be clever and match up similar lines. But for now we are simple and
67
+ # stupid, and only handle multi-line hunks that remove and add the same
68
+ # number of lines.
69
+ if (@$a != @$b) {
70
+ print @$a, @$b;
71
+ return;
72
+ }
73
+
74
+ my @queue;
75
+ for (my $i = 0; $i < @$a; $i++) {
76
+ my ($rm, $add) = highlight_pair($a->[$i], $b->[$i]);
77
+ print $rm;
78
+ push @queue, $add;
79
+ }
80
+ print @queue;
81
}
82
83
sub highlight_pair {