diff-highlight: allow module callers to pass in color config

Users of the module may want to pass in their own color config for a few
obvious reasons:

  - they are pulling the config from different variables than
    diff-highlight itself uses

  - they are loading the config in a more efficient way (say, by parsing
    git-config --list) and don't want to incur the six (!) git-config
    calls that DiffHighlight.pm runs to check all config

Let's allow users of the module to pass in the color config, and
lazy-load it when needed if they haven't.

Signed-off-by: Scott Baker <scott@perturb.org>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Scott Baker
2026-03-23 02:02:15 -04:00
committed by Junio C Hamano
parent c6bc53ad95
commit bd958e91df
2 changed files with 35 additions and 12 deletions

View File

@@ -9,18 +9,11 @@ use File::Spec;
my $NULL = File::Spec->devnull();
# Highlight by reversing foreground and background. You could do
# other things like bold or underline if you prefer.
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])
);
# The color theme is initially set to nothing here to allow outside callers
# to set the colors for their application. If nothing is sent in we use
# colors from git config in load_color_config().
our @OLD_HIGHLIGHT = ();
our @NEW_HIGHLIGHT = ();
my $RESET = "\x1b[m";
my $COLOR = qr/\x1b\[[0-9;]*m/;
@@ -170,6 +163,29 @@ sub show_hunk {
$line_cb->(@queue);
}
sub load_color_config {
# If the colors were NOT set from outside this module we load them on-demand
# from the git config. Note that only one of elements 0 and 2 in each
# array is used (depending on whether you are doing set/unset on an
# attribute, or specifying normal vs highlighted coloring). So we use
# element 1 as our check for whether colors were passed in; it should
# always be set if you want highlighting to do anything.
if (!defined $OLD_HIGHLIGHT[1]) {
@OLD_HIGHLIGHT = (
color_config('color.diff-highlight.oldnormal'),
color_config('color.diff-highlight.oldhighlight', "\x1b[7m"),
color_config('color.diff-highlight.oldreset', "\x1b[27m")
);
}
if (!defined $NEW_HIGHLIGHT[1]) {
@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])
);
};
}
sub highlight_pair {
my @a = split_line(shift);
my @b = split_line(shift);
@@ -218,6 +234,7 @@ sub highlight_pair {
}
if (is_pair_interesting(\@a, $pa, $sa, \@b, $pb, $sb)) {
load_color_config();
return highlight_line(\@a, $pa, $sa, \@OLD_HIGHLIGHT),
highlight_line(\@b, $pb, $sb, \@NEW_HIGHLIGHT);
}

View File

@@ -138,6 +138,12 @@ Your script may set up one or more of the following variables:
processing a logical chunk of input). The default function flushes
stdout.
- @DiffHighlight::OLD_HIGHLIGHT and @DiffHighlight::NEW_HIGHLIGHT - these
arrays specify the normal, highlighted, and reset colors (in that order)
for old/new lines. If unset, values will be retrieved by calling `git
config` (see "Color Config" above). Note that these should be the literal
color bytes (starting with an ANSI escape code), not color names.
The script may then feed lines, one at a time, to DiffHighlight::handle_line().
When lines are done processing, they will be fed to $line_cb. Note that
DiffHighlight may queue up many input lines (to analyze a whole hunk)