Merge branch 'jn/doc-api-errors'
[gitweb.git] / contrib / diff-highlight / diff-highlight
index 69a652e7b2cc4ed2e03ead8aec4b3abeebf20b14..08c88bbc87e51e25cacc5826b26a223f3bfbd382 100755 (executable)
@@ -5,8 +5,18 @@ use strict;
 
 # Highlight by reversing foreground and background. You could do
 # other things like bold or underline if you prefer.
-my $HIGHLIGHT   = "\x1b[7m";
-my $UNHIGHLIGHT = "\x1b[27m";
+my @OLD_HIGHLIGHT = (
+       color_config('color.diff-highlight.oldnormal'),
+       color_config('color.diff-highlight.oldhighlight', "\x1b[7m"),
+       color_config('color.diff-highlight.oldreset', "\x1b[27m")
+);
+my @NEW_HIGHLIGHT = (
+       color_config('color.diff-highlight.newnormal', $OLD_HIGHLIGHT[0]),
+       color_config('color.diff-highlight.newhighlight', $OLD_HIGHLIGHT[1]),
+       color_config('color.diff-highlight.newreset', $OLD_HIGHLIGHT[2])
+);
+
+my $RESET = "\x1b[m";
 my $COLOR = qr/\x1b\[[0-9;]*m/;
 my $BORING = qr/$COLOR|\s/;
 
@@ -57,6 +67,17 @@ show_hunk(\@removed, \@added);
 
 exit 0;
 
+# Ideally we would feed the default as a human-readable color to
+# git-config as the fallback value. But diff-highlight does
+# not otherwise depend on git at all, and there are reports
+# of it being used in other settings. Let's handle our own
+# fallback, which means we will work even if git can't be run.
+sub color_config {
+       my ($key, $default) = @_;
+       my $s = `git config --get-color $key 2>/dev/null`;
+       return length($s) ? $s : $default;
+}
+
 sub show_hunk {
        my ($a, $b) = @_;
 
@@ -132,8 +153,8 @@ sub highlight_pair {
        }
 
        if (is_pair_interesting(\@a, $pa, $sa, \@b, $pb, $sb)) {
-               return highlight_line(\@a, $pa, $sa),
-                      highlight_line(\@b, $pb, $sb);
+               return highlight_line(\@a, $pa, $sa, \@OLD_HIGHLIGHT),
+                      highlight_line(\@b, $pb, $sb, \@NEW_HIGHLIGHT);
        }
        else {
                return join('', @a),
@@ -148,15 +169,30 @@ sub split_line {
 }
 
 sub highlight_line {
-       my ($line, $prefix, $suffix) = @_;
-
-       return join('',
-               @{$line}[0..($prefix-1)],
-               $HIGHLIGHT,
-               @{$line}[$prefix..$suffix],
-               $UNHIGHLIGHT,
-               @{$line}[($suffix+1)..$#$line]
-       );
+       my ($line, $prefix, $suffix, $theme) = @_;
+
+       my $start = join('', @{$line}[0..($prefix-1)]);
+       my $mid = join('', @{$line}[$prefix..$suffix]);
+       my $end = join('', @{$line}[($suffix+1)..$#$line]);
+
+       # If we have a "normal" color specified, then take over the whole line.
+       # Otherwise, we try to just manipulate the highlighted bits.
+       if (defined $theme->[0]) {
+               s/$COLOR//g for ($start, $mid, $end);
+               chomp $end;
+               return join('',
+                       $theme->[0], $start, $RESET,
+                       $theme->[1], $mid, $RESET,
+                       $theme->[0], $end, $RESET,
+                       "\n"
+               );
+       } else {
+               return join('',
+                       $start,
+                       $theme->[1], $mid, $theme->[2],
+                       $end
+               );
+       }
 }
 
 # Pairs are interesting to highlight only if we are going to end up