mirror of
https://github.com/git/git
synced 2024-09-13 05:14:36 +00:00
Color support for "git-add -i"
This is mostly lifted from earlier series by Dan Zwell, but updated to use "git config --get-color" and "git config --get-colorbool" to make it simpler and more consistent with commands written in C. A new configuration color.interactive variable is like color.diff and color.status, and controls if "git-add -i" uses color. A set of configuration variables, color.interactive.<slot>, are used to define what color is used for the prompt, header, and help text. For perl scripts, Git.pm provides $repo->get_color() method, which takes the slot name and the default color, and returns the terminal escape sequence to color the output text. $repo->get_colorbool() method can be used to check if color is set to be used for a given operation. Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
0f6f5a4022
commit
b4c61ed6d3
|
@ -391,6 +391,18 @@ color.diff.<slot>::
|
||||||
whitespace). The values of these variables may be specified as
|
whitespace). The values of these variables may be specified as
|
||||||
in color.branch.<slot>.
|
in color.branch.<slot>.
|
||||||
|
|
||||||
|
color.interactive::
|
||||||
|
When set to `always`, always use colors in `git add --interactive`.
|
||||||
|
When false (or `never`), never. When set to `true` or `auto`, use
|
||||||
|
colors only when the output is to the terminal. Defaults to false.
|
||||||
|
|
||||||
|
color.interactive.<slot>::
|
||||||
|
Use customized color for `git add --interactive`
|
||||||
|
output. `<slot>` may be `prompt`, `header`, or `help`, for
|
||||||
|
three distinct types of normal output from interactive
|
||||||
|
programs. The values of these variables may be specified as
|
||||||
|
in color.branch.<slot>.
|
||||||
|
|
||||||
color.pager::
|
color.pager::
|
||||||
A boolean to enable/disable colored output when the pager is in
|
A boolean to enable/disable colored output when the pager is in
|
||||||
use (default is true).
|
use (default is true).
|
||||||
|
|
|
@ -1,6 +1,55 @@
|
||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
|
use Git;
|
||||||
|
|
||||||
|
# Prompt colors:
|
||||||
|
my ($prompt_color, $header_color, $help_color, $normal_color);
|
||||||
|
# Diff colors:
|
||||||
|
my ($new_color, $old_color, $fraginfo_color, $metainfo_color, $whitespace_color);
|
||||||
|
|
||||||
|
my ($use_color, $diff_use_color);
|
||||||
|
my $repo = Git->repository();
|
||||||
|
|
||||||
|
$use_color = $repo->get_colorbool('color.interactive');
|
||||||
|
|
||||||
|
if ($use_color) {
|
||||||
|
# Set interactive colors:
|
||||||
|
|
||||||
|
# Grab the 3 main colors in git color string format, with sane
|
||||||
|
# (visible) defaults:
|
||||||
|
$prompt_color = $repo->get_color("color.interactive.prompt", "bold blue");
|
||||||
|
$header_color = $repo->get_color("color.interactive.header", "bold");
|
||||||
|
$help_color = $repo->get_color("color.interactive.help", "red bold");
|
||||||
|
$normal_color = $repo->get_color("", "reset");
|
||||||
|
|
||||||
|
# Do we also set diff colors?
|
||||||
|
$diff_use_color = $repo->get_colorbool('color.diff');
|
||||||
|
if ($diff_use_color) {
|
||||||
|
$new_color = $repo->get_color("color.diff.new", "green");
|
||||||
|
$old_color = $repo->get_color("color.diff.old", "red");
|
||||||
|
$fraginfo_color = $repo->get_color("color.diff.frag", "cyan");
|
||||||
|
$metainfo_color = $repo->get_color("color.diff.meta", "bold");
|
||||||
|
$whitespace_color = $repo->get_color("color.diff.whitespace", "normal red");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub colored {
|
||||||
|
my $color = shift;
|
||||||
|
my $string = join("", @_);
|
||||||
|
|
||||||
|
if ($use_color) {
|
||||||
|
# Put a color code at the beginning of each line, a reset at the end
|
||||||
|
# color after newlines that are not at the end of the string
|
||||||
|
$string =~ s/(\n+)(.)/$1$color$2/g;
|
||||||
|
# reset before newlines
|
||||||
|
$string =~ s/(\n+)/$normal_color$1/g;
|
||||||
|
# codes at beginning and end (if necessary):
|
||||||
|
$string =~ s/^/$color/;
|
||||||
|
$string =~ s/$/$normal_color/ unless $string =~ /\n$/;
|
||||||
|
}
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
# command line options
|
# command line options
|
||||||
my $patch_mode;
|
my $patch_mode;
|
||||||
|
@ -246,10 +295,20 @@ sub is_valid_prefix {
|
||||||
sub highlight_prefix {
|
sub highlight_prefix {
|
||||||
my $prefix = shift;
|
my $prefix = shift;
|
||||||
my $remainder = shift;
|
my $remainder = shift;
|
||||||
return $remainder unless defined $prefix;
|
|
||||||
return is_valid_prefix($prefix) ?
|
if (!defined $prefix) {
|
||||||
"[$prefix]$remainder" :
|
return $remainder;
|
||||||
"$prefix$remainder";
|
}
|
||||||
|
|
||||||
|
if (!is_valid_prefix($prefix)) {
|
||||||
|
return "$prefix$remainder";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$use_color) {
|
||||||
|
return "[$prefix]$remainder";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "$prompt_color$prefix$normal_color$remainder";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub list_and_choose {
|
sub list_and_choose {
|
||||||
|
@ -266,7 +325,7 @@ sub list_and_choose {
|
||||||
if (!$opts->{LIST_FLAT}) {
|
if (!$opts->{LIST_FLAT}) {
|
||||||
print " ";
|
print " ";
|
||||||
}
|
}
|
||||||
print "$opts->{HEADER}\n";
|
print colored $header_color, "$opts->{HEADER}\n";
|
||||||
}
|
}
|
||||||
for ($i = 0; $i < @stuff; $i++) {
|
for ($i = 0; $i < @stuff; $i++) {
|
||||||
my $chosen = $chosen[$i] ? '*' : ' ';
|
my $chosen = $chosen[$i] ? '*' : ' ';
|
||||||
|
@ -304,7 +363,7 @@ sub list_and_choose {
|
||||||
|
|
||||||
return if ($opts->{LIST_ONLY});
|
return if ($opts->{LIST_ONLY});
|
||||||
|
|
||||||
print $opts->{PROMPT};
|
print colored $prompt_color, $opts->{PROMPT};
|
||||||
if ($opts->{SINGLETON}) {
|
if ($opts->{SINGLETON}) {
|
||||||
print "> ";
|
print "> ";
|
||||||
}
|
}
|
||||||
|
@ -371,7 +430,7 @@ sub list_and_choose {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub singleton_prompt_help_cmd {
|
sub singleton_prompt_help_cmd {
|
||||||
print <<\EOF ;
|
print colored $help_color, <<\EOF ;
|
||||||
Prompt help:
|
Prompt help:
|
||||||
1 - select a numbered item
|
1 - select a numbered item
|
||||||
foo - select item based on unique prefix
|
foo - select item based on unique prefix
|
||||||
|
@ -380,7 +439,7 @@ sub singleton_prompt_help_cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub prompt_help_cmd {
|
sub prompt_help_cmd {
|
||||||
print <<\EOF ;
|
print colored $help_color, <<\EOF ;
|
||||||
Prompt help:
|
Prompt help:
|
||||||
1 - select a single item
|
1 - select a single item
|
||||||
3-5 - select a range of items
|
3-5 - select a range of items
|
||||||
|
@ -477,6 +536,31 @@ sub parse_diff {
|
||||||
return @hunk;
|
return @hunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub colored_diff_hunk {
|
||||||
|
my ($text) = @_;
|
||||||
|
# return the text, so that it can be passed to print()
|
||||||
|
my @ret;
|
||||||
|
for (@$text) {
|
||||||
|
if (!$diff_use_color) {
|
||||||
|
push @ret, $_;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^\+/) {
|
||||||
|
push @ret, colored($new_color, $_);
|
||||||
|
} elsif (/^\-/) {
|
||||||
|
push @ret, colored($old_color, $_);
|
||||||
|
} elsif (/^\@/) {
|
||||||
|
push @ret, colored($fraginfo_color, $_);
|
||||||
|
} elsif (/^ /) {
|
||||||
|
push @ret, colored($normal_color, $_);
|
||||||
|
} else {
|
||||||
|
push @ret, colored($metainfo_color, $_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return @ret;
|
||||||
|
}
|
||||||
|
|
||||||
sub hunk_splittable {
|
sub hunk_splittable {
|
||||||
my ($text) = @_;
|
my ($text) = @_;
|
||||||
|
|
||||||
|
@ -671,7 +755,7 @@ sub coalesce_overlapping_hunks {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub help_patch_cmd {
|
sub help_patch_cmd {
|
||||||
print <<\EOF ;
|
print colored $help_color, <<\EOF ;
|
||||||
y - stage this hunk
|
y - stage this hunk
|
||||||
n - do not stage this hunk
|
n - do not stage this hunk
|
||||||
a - stage this and all the remaining hunks in the file
|
a - stage this and all the remaining hunks in the file
|
||||||
|
@ -710,9 +794,7 @@ sub patch_update_file {
|
||||||
my ($ix, $num);
|
my ($ix, $num);
|
||||||
my $path = shift;
|
my $path = shift;
|
||||||
my ($head, @hunk) = parse_diff($path);
|
my ($head, @hunk) = parse_diff($path);
|
||||||
for (@{$head->{TEXT}}) {
|
print colored_diff_hunk($head->{TEXT});
|
||||||
print;
|
|
||||||
}
|
|
||||||
$num = scalar @hunk;
|
$num = scalar @hunk;
|
||||||
$ix = 0;
|
$ix = 0;
|
||||||
|
|
||||||
|
@ -754,10 +836,8 @@ sub patch_update_file {
|
||||||
if (hunk_splittable($hunk[$ix]{TEXT})) {
|
if (hunk_splittable($hunk[$ix]{TEXT})) {
|
||||||
$other .= '/s';
|
$other .= '/s';
|
||||||
}
|
}
|
||||||
for (@{$hunk[$ix]{TEXT}}) {
|
print colored_diff_hunk($hunk[$ix]{TEXT});
|
||||||
print;
|
print colored $prompt_color, "Stage this hunk [y/n/a/d$other/?]? ";
|
||||||
}
|
|
||||||
print "Stage this hunk [y/n/a/d$other/?]? ";
|
|
||||||
my $line = <STDIN>;
|
my $line = <STDIN>;
|
||||||
if ($line) {
|
if ($line) {
|
||||||
if ($line =~ /^y/i) {
|
if ($line =~ /^y/i) {
|
||||||
|
@ -811,7 +891,7 @@ sub patch_update_file {
|
||||||
elsif ($other =~ /s/ && $line =~ /^s/) {
|
elsif ($other =~ /s/ && $line =~ /^s/) {
|
||||||
my @split = split_hunk($hunk[$ix]{TEXT});
|
my @split = split_hunk($hunk[$ix]{TEXT});
|
||||||
if (1 < @split) {
|
if (1 < @split) {
|
||||||
print "Split into ",
|
print colored $header_color, "Split into ",
|
||||||
scalar(@split), " hunks.\n";
|
scalar(@split), " hunks.\n";
|
||||||
}
|
}
|
||||||
splice(@hunk, $ix, 1,
|
splice(@hunk, $ix, 1,
|
||||||
|
@ -894,8 +974,7 @@ sub diff_cmd {
|
||||||
HEADER => $status_head, },
|
HEADER => $status_head, },
|
||||||
@mods);
|
@mods);
|
||||||
return if (!@them);
|
return if (!@them);
|
||||||
system(qw(git diff-index -p --cached HEAD --),
|
system(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them);
|
||||||
map { $_->{VALUE} } @them);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub quit_cmd {
|
sub quit_cmd {
|
||||||
|
@ -904,7 +983,7 @@ sub quit_cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub help_cmd {
|
sub help_cmd {
|
||||||
print <<\EOF ;
|
print colored $help_color, <<\EOF ;
|
||||||
status - show paths with changes
|
status - show paths with changes
|
||||||
update - add working tree state to the staged set of changes
|
update - add working tree state to the staged set of changes
|
||||||
revert - revert staged set of changes back to the HEAD version
|
revert - revert staged set of changes back to the HEAD version
|
||||||
|
|
35
perl/Git.pm
35
perl/Git.pm
|
@ -581,6 +581,41 @@ sub config_int {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=item get_colorbool ( NAME )
|
||||||
|
|
||||||
|
Finds if color should be used for NAMEd operation from the configuration,
|
||||||
|
and returns boolean (true for "use color", false for "do not use color").
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub get_colorbool {
|
||||||
|
my ($self, $var) = @_;
|
||||||
|
my $stdout_to_tty = (-t STDOUT) ? "true" : "false";
|
||||||
|
my $use_color = $self->command_oneline('config', '--get-colorbool',
|
||||||
|
$var, $stdout_to_tty);
|
||||||
|
return ($use_color eq 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
=item get_color ( SLOT, COLOR )
|
||||||
|
|
||||||
|
Finds color for SLOT from the configuration, while defaulting to COLOR,
|
||||||
|
and returns the ANSI color escape sequence:
|
||||||
|
|
||||||
|
print $repo->get_color("color.interactive.prompt", "underline blue white");
|
||||||
|
print "some text";
|
||||||
|
print $repo->get_color("", "normal");
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub get_color {
|
||||||
|
my ($self, $slot, $default) = @_;
|
||||||
|
my $color = $self->command_oneline('config', '--get-color', $slot, $default);
|
||||||
|
if (!defined $color) {
|
||||||
|
$color = "";
|
||||||
|
}
|
||||||
|
return $color;
|
||||||
|
}
|
||||||
|
|
||||||
=item ident ( TYPE | IDENTSTR )
|
=item ident ( TYPE | IDENTSTR )
|
||||||
|
|
||||||
=item ident_person ( TYPE | IDENTSTR | IDENTARRAY )
|
=item ident_person ( TYPE | IDENTSTR | IDENTARRAY )
|
||||||
|
|
Loading…
Reference in a new issue