11package DiffHighlight ;
22
3- require v5.26 ;
3+ require v5.008 ;
44use warnings FATAL => ' all' ;
55use strict;
66
@@ -9,18 +9,11 @@ use File::Spec;
99
1010my $NULL = File::Spec-> devnull();
1111
12- # Highlight by reversing foreground and background. You could do
13- # other things like bold or underline if you prefer.
14- my @OLD_HIGHLIGHT = (
15- color_config(' color.diff-highlight.oldnormal' ),
16- color_config(' color.diff-highlight.oldhighlight' , " \x1b [7m" ),
17- color_config(' color.diff-highlight.oldreset' , " \x1b [27m" )
18- );
19- my @NEW_HIGHLIGHT = (
20- color_config(' color.diff-highlight.newnormal' , $OLD_HIGHLIGHT [0]),
21- color_config(' color.diff-highlight.newhighlight' , $OLD_HIGHLIGHT [1]),
22- color_config(' color.diff-highlight.newreset' , $OLD_HIGHLIGHT [2])
23- );
12+ # The color theme is initially set to nothing here to allow outside callers
13+ # to set the colors for their application. If nothing is sent in we use
14+ # colors from git config in load_color_config().
15+ our @OLD_HIGHLIGHT = ();
16+ our @NEW_HIGHLIGHT = ();
2417
2518my $RESET = " \x1b [m" ;
2619my $COLOR = qr /\x1b\[ [0-9;]*m/ ;
@@ -138,9 +131,21 @@ sub highlight_stdin {
138131# of it being used in other settings. Let's handle our own
139132# fallback, which means we will work even if git can't be run.
140133sub color_config {
134+ our $cached_config ;
141135 my ($key , $default ) = @_ ;
142- my $s = ` git config --get-color $key 2>$NULL ` ;
143- return length ($s ) ? $s : $default ;
136+
137+ if (!defined $cached_config ) {
138+ $cached_config = {};
139+ my $data = ` git config --type=color --get-regexp '^color\. diff-highlight\. ' 2>$NULL ` ;
140+ for my $line (split /\n/, $data ) {
141+ my ($key , $color ) = split ' ' , $line , 2;
142+ $key =~ s / ^color\. diff-highlight\. // or next ;
143+ $cached_config -> {$key } = $color ;
144+ }
145+ }
146+
147+ my $s = $cached_config -> {$key };
148+ return defined ($s ) ? $s : $default ;
144149}
145150
146151sub show_hunk {
@@ -170,6 +175,29 @@ sub show_hunk {
170175 $line_cb -> (@queue );
171176}
172177
178+ sub load_color_config {
179+ # If the colors were NOT set from outside this module we load them on-demand
180+ # from the git config. Note that only one of elements 0 and 2 in each
181+ # array is used (depending on whether you are doing set/unset on an
182+ # attribute, or specifying normal vs highlighted coloring). So we use
183+ # element 1 as our check for whether colors were passed in; it should
184+ # always be set if you want highlighting to do anything.
185+ if (!defined $OLD_HIGHLIGHT [1]) {
186+ @OLD_HIGHLIGHT = (
187+ color_config(' oldnormal' ),
188+ color_config(' oldhighlight' , " \x1b [7m" ),
189+ color_config(' oldreset' , " \x1b [27m" )
190+ );
191+ }
192+ if (!defined $NEW_HIGHLIGHT [1]) {
193+ @NEW_HIGHLIGHT = (
194+ color_config(' newnormal' , $OLD_HIGHLIGHT [0]),
195+ color_config(' newhighlight' , $OLD_HIGHLIGHT [1]),
196+ color_config(' newreset' , $OLD_HIGHLIGHT [2])
197+ );
198+ };
199+ }
200+
173201sub highlight_pair {
174202 my @a = split_line(shift );
175203 my @b = split_line(shift );
@@ -218,6 +246,7 @@ sub highlight_pair {
218246 }
219247
220248 if (is_pair_interesting(\@a , $pa , $sa , \@b , $pb , $sb )) {
249+ load_color_config();
221250 return highlight_line(\@a , $pa , $sa , \@OLD_HIGHLIGHT ),
222251 highlight_line(\@b , $pb , $sb , \@NEW_HIGHLIGHT );
223252 }
0 commit comments