@@ -11,7 +11,11 @@ $fatpacked{"DiffHighlight.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'D
1111 use 5.008;
1212 use warnings FATAL => 'all';
1313 use strict;
14- use Encode;
14+
15+ # Use the correct value for both UNIX and Windows (/dev/null vs nul)
16+ use File::Spec;
17+
18+ my $NULL = File::Spec->devnull();
1519
1620 # Highlight by reversing foreground and background. You could do
1721 # other things like bold or underline if you prefer.
@@ -26,41 +30,88 @@ $fatpacked{"DiffHighlight.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'D
2630 $OLD_HIGHLIGHT[2],
2731 );
2832
33+
34+
2935 my $RESET = "\x1b[m";
3036 my $COLOR = qr/\x1b\[[0-9;]*m/;
3137 my $BORING = qr/$COLOR|\s/;
3238
33- # The patch portion of git log -p --graph should only ever have preceding | and
34- # not / or \ as merge history only shows up on the commit line.
35- my $GRAPH = qr/$COLOR?\|$COLOR?\s+/;
36-
3739 my @removed;
3840 my @added;
3941 my $in_hunk;
42+ my $graph_indent = 0;
4043
4144 our $line_cb = sub { print @_ };
4245 our $flush_cb = sub { local $| = 1 };
4346
44- sub handle_line {
47+ # Count the visible width of a string, excluding any terminal color sequences.
48+ sub visible_width {
4549 local $_ = shift;
50+ my $ret = 0;
51+ while (length) {
52+ if (s/^$COLOR//) {
53+ # skip colors
54+ } elsif (s/^.//) {
55+ $ret++;
56+ }
57+ }
58+ return $ret;
59+ }
60+
61+ # Return a substring of $str, omitting $len visible characters from the
62+ # beginning, where terminal color sequences do not count as visible.
63+ sub visible_substr {
64+ my ($str, $len) = @_;
65+ while ($len > 0) {
66+ if ($str =~ s/^$COLOR//) {
67+ next
68+ }
69+ $str =~ s/^.//;
70+ $len--;
71+ }
72+ return $str;
73+ }
74+
75+ sub handle_line {
76+ my $orig = shift;
77+ local $_ = $orig;
78+
79+ # match a graph line that begins a commit
80+ if (/^(?:$COLOR?\|$COLOR?[ ])* # zero or more leading "|" with space
81+ $COLOR?\*$COLOR?[ ] # a "*" with its trailing space
82+ (?:$COLOR?\|$COLOR?[ ])* # zero or more trailing "|"
83+ [ ]* # trailing whitespace for merges
84+ /x) {
85+ my $graph_prefix = $&;
86+
87+ # We must flush before setting graph indent, since the
88+ # new commit may be indented differently from what we
89+ # queued.
90+ flush();
91+ $graph_indent = visible_width($graph_prefix);
92+
93+ } elsif ($graph_indent) {
94+ if (length($_) < $graph_indent) {
95+ $graph_indent = 0;
96+ } else {
97+ $_ = visible_substr($_, $graph_indent);
98+ }
99+ }
46100
47101 if (!$in_hunk) {
48- $line_cb->($_ );
49- $in_hunk = /^$GRAPH*$ COLOR*\@\@ /;
102+ $line_cb->($orig );
103+ $in_hunk = /^$COLOR*\@\@ /;
50104 }
51- elsif (/^$GRAPH*$ COLOR*-/) {
52- push @removed, $_ ;
105+ elsif (/^$COLOR*-/) {
106+ push @removed, $orig ;
53107 }
54- elsif (/^$GRAPH*$ COLOR*\+/) {
55- push @added, $_ ;
108+ elsif (/^$COLOR*\+/) {
109+ push @added, $orig ;
56110 }
57111 else {
58- show_hunk(\@removed, \@added);
59- @removed = ();
60- @added = ();
61-
62- $line_cb->($_);
63- $in_hunk = /^$GRAPH*$COLOR*[\@ ]/;
112+ flush();
113+ $line_cb->($orig);
114+ $in_hunk = /^$COLOR*[\@ ]/;
64115 }
65116
66117 # Most of the time there is enough output to keep things streaming,
@@ -80,6 +131,8 @@ $fatpacked{"DiffHighlight.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'D
80131 # Flush any queued hunk (this can happen when there is no trailing
81132 # context in the final diff of the input).
82133 show_hunk(\@removed, \@added);
134+ @removed = ();
135+ @added = ();
83136 }
84137
85138 sub highlight_stdin {
@@ -96,7 +149,7 @@ $fatpacked{"DiffHighlight.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'D
96149 # fallback, which means we will work even if git can't be run.
97150 sub color_config {
98151 my ($key, $default) = @_;
99- my $s = `git config --get-color $key 2>/dev/null `;
152+ my $s = `git config --get-color $key 2>$NULL `;
100153 return length($s) ? $s : $default;
101154 }
102155
@@ -130,7 +183,6 @@ $fatpacked{"DiffHighlight.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'D
130183 sub highlight_pair {
131184 my @a = split_line(shift);
132185 my @b = split_line(shift);
133- my $opts = shift();
134186
135187 # Find common prefix, taking care to skip any ansi
136188 # color codes.
@@ -175,18 +227,9 @@ $fatpacked{"DiffHighlight.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'D
175227 }
176228 }
177229
178- my @OLD_COLOR_SPEC = @OLD_HIGHLIGHT;
179- my @NEW_COLOR_SPEC = @NEW_HIGHLIGHT;
180-
181- # If we're only highlight the differences temp disable the old/new normal colors
182- if ($opts->{'only_diff'}) {
183- $OLD_COLOR_SPEC[0] = '';
184- $NEW_COLOR_SPEC[0] = '';
185- }
186-
187230 if (is_pair_interesting(\@a, $pa, $sa, \@b, $pb, $sb)) {
188- return highlight_line(\@a, $pa, $sa, \@OLD_COLOR_SPEC ),
189- highlight_line(\@b, $pb, $sb, \@NEW_COLOR_SPEC );
231+ return highlight_line(\@a, $pa, $sa, \@OLD_HIGHLIGHT ),
232+ highlight_line(\@b, $pb, $sb, \@NEW_HIGHLIGHT );
190233 }
191234 else {
192235 return join('', @a),
@@ -199,8 +242,8 @@ $fatpacked{"DiffHighlight.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'D
199242 # or "+"
200243 sub split_line {
201244 local $_ = shift;
202- return eval { $_ = Encode ::decode('UTF-8', $_, 1); 1 } ?
203- map { Encode ::encode('UTF-8', $_) }
245+ return utf8 ::decode($_) ?
246+ map { utf8 ::encode($_); $_ }
204247 map { /$COLOR/ ? $_ : (split //) }
205248 split /($COLOR+)/ :
206249 map { /$COLOR/ ? $_ : (split //) }
@@ -245,8 +288,8 @@ $fatpacked{"DiffHighlight.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'D
245288 my $suffix_a = join('', @$a[($sa+1)..$#$a]);
246289 my $suffix_b = join('', @$b[($sb+1)..$#$b]);
247290
248- return $prefix_a !~ /^$GRAPH* $COLOR*-$BORING*$/ ||
249- $prefix_b !~ /^$GRAPH* $COLOR*\+$BORING*$/ ||
291+ return visible_substr( $prefix_a, $graph_indent) !~ /^$COLOR*-$BORING*$/ ||
292+ visible_substr( $prefix_b, $graph_indent) !~ /^$COLOR*\+$BORING*$/ ||
250293 $suffix_a !~ /^$BORING*$/ ||
251294 $suffix_b !~ /^$BORING*$/;
252295 }
@@ -289,7 +332,7 @@ unshift @INC, bless \%fatpacked, $class;
289332 } # END OF FATPACK CODE
290333
291334
292- my $VERSION = " 1.2.5 " ;
335+ my $VERSION = " 1.2.6 " ;
293336
294337# ################################################################################
295338
0 commit comments