Browse Source

Merge branch 'tr/add-p-single'

* tr/add-p-single:
  add -p: import Term::ReadKey with 'require'
  add -p: print errors in separate color
  add -p: prompt for single characters
maint
Junio C Hamano 16 years ago
parent
commit
c19923add0
  1. 11
      Documentation/config.txt
  2. 78
      git-add--interactive.perl

11
Documentation/config.txt

@ -569,8 +569,8 @@ color.interactive::


color.interactive.<slot>:: color.interactive.<slot>::
Use customized color for 'git-add --interactive' Use customized color for 'git-add --interactive'
output. `<slot>` may be `prompt`, `header`, or `help`, for output. `<slot>` may be `prompt`, `header`, `help` or `error`, for
three distinct types of normal output from interactive four distinct types of normal output from interactive
programs. The values of these variables may be specified as programs. The values of these variables may be specified as
in color.branch.<slot>. in color.branch.<slot>.


@ -1013,6 +1013,13 @@ instaweb.port::
The port number to bind the gitweb httpd to. See The port number to bind the gitweb httpd to. See
linkgit:git-instaweb[1]. linkgit:git-instaweb[1].


interactive.singlekey::
In interactive programs, allow the user to provide one-letter
input with a single key (i.e., without hitting enter).
Currently this is used only by the `\--patch` mode of
linkgit:git-add[1]. Note that this setting is silently
ignored if portable keystroke input is not available.

log.date:: log.date::
Set default date-time mode for the log command. Setting log.date Set default date-time mode for the log command. Setting log.date
value is similar to using 'git-log'\'s --date option. The value is one of the value is similar to using 'git-log'\'s --date option. The value is one of the

78
git-add--interactive.perl

@ -12,6 +12,12 @@ my ($prompt_color, $header_color, $help_color) =
$repo->get_color('color.interactive.header', 'bold'), $repo->get_color('color.interactive.header', 'bold'),
$repo->get_color('color.interactive.help', 'red bold'), $repo->get_color('color.interactive.help', 'red bold'),
) : (); ) : ();
my $error_color = ();
if ($menu_use_color) {
my $help_color_spec = $repo->config('color.interactive.help');
$error_color = $repo->get_color('color.interactive.error',
$help_color_spec);
}


my $diff_use_color = $repo->get_colorbool('color.diff'); my $diff_use_color = $repo->get_colorbool('color.diff');
my ($fraginfo_color) = my ($fraginfo_color) =
@ -33,6 +39,17 @@ my ($diff_new_color) =


my $normal_color = $repo->get_color("", "reset"); my $normal_color = $repo->get_color("", "reset");


my $use_readkey = 0;
sub ReadMode;
sub ReadKey;
if ($repo->config_bool("interactive.singlekey")) {
eval {
require Term::ReadKey;
Term::ReadKey->import;
$use_readkey = 1;
};
}

sub colored { sub colored {
my $color = shift; my $color = shift;
my $string = join("", @_); my $string = join("", @_);
@ -325,6 +342,10 @@ sub highlight_prefix {
return "$prompt_color$prefix$normal_color$remainder"; return "$prompt_color$prefix$normal_color$remainder";
} }


sub error_msg {
print STDERR colored $error_color, @_;
}

sub list_and_choose { sub list_and_choose {
my ($opts, @stuff) = @_; my ($opts, @stuff) = @_;
my (@chosen, @return); my (@chosen, @return);
@ -420,12 +441,12 @@ sub list_and_choose {
else { else {
$bottom = $top = find_unique($choice, @stuff); $bottom = $top = find_unique($choice, @stuff);
if (!defined $bottom) { if (!defined $bottom) {
print "Huh ($choice)?\n"; error_msg "Huh ($choice)?\n";
next TOPLOOP; next TOPLOOP;
} }
} }
if ($opts->{SINGLETON} && $bottom != $top) { if ($opts->{SINGLETON} && $bottom != $top) {
print "Huh ($choice)?\n"; error_msg "Huh ($choice)?\n";
next TOPLOOP; next TOPLOOP;
} }
for ($i = $bottom-1; $i <= $top-1; $i++) { for ($i = $bottom-1; $i <= $top-1; $i++) {
@ -758,11 +779,32 @@ sub diff_applies {
return close $fh; return close $fh;
} }


sub _restore_terminal_and_die {
ReadMode 'restore';
print "\n";
exit 1;
}

sub prompt_single_character {
if ($use_readkey) {
local $SIG{TERM} = \&_restore_terminal_and_die;
local $SIG{INT} = \&_restore_terminal_and_die;
ReadMode 'cbreak';
my $key = ReadKey 0;
ReadMode 'restore';
print "$key" if defined $key;
print "\n";
return $key;
} else {
return <STDIN>;
}
}

sub prompt_yesno { sub prompt_yesno {
my ($prompt) = @_; my ($prompt) = @_;
while (1) { while (1) {
print colored $prompt_color, $prompt; print colored $prompt_color, $prompt;
my $line = <STDIN>; my $line = prompt_single_character;
return 0 if $line =~ /^n/i; return 0 if $line =~ /^n/i;
return 1 if $line =~ /^y/i; return 1 if $line =~ /^y/i;
} }
@ -893,7 +935,7 @@ sub patch_update_file {
print @{$mode->{DISPLAY}}; print @{$mode->{DISPLAY}};
print colored $prompt_color, print colored $prompt_color,
"Stage mode change [y/n/a/d/?]? "; "Stage mode change [y/n/a/d/?]? ";
my $line = <STDIN>; my $line = prompt_single_character;
if ($line =~ /^y/i) { if ($line =~ /^y/i) {
$mode->{USE} = 1; $mode->{USE} = 1;
last; last;
@ -966,7 +1008,7 @@ sub patch_update_file {
print; print;
} }
print colored $prompt_color, "Stage this hunk [y,n,a,d,/$other,?]? "; print colored $prompt_color, "Stage this hunk [y,n,a,d,/$other,?]? ";
my $line = <STDIN>; my $line = prompt_single_character;
if ($line) { if ($line) {
if ($line =~ /^y/i) { if ($line =~ /^y/i) {
$hunk[$ix]{USE} = 1; $hunk[$ix]{USE} = 1;
@ -1000,11 +1042,11 @@ sub patch_update_file {
chomp $response; chomp $response;
} }
if ($response !~ /^\s*\d+\s*$/) { if ($response !~ /^\s*\d+\s*$/) {
print STDERR "Invalid number: '$response'\n"; error_msg "Invalid number: '$response'\n";
} elsif (0 < $response && $response <= $num) { } elsif (0 < $response && $response <= $num) {
$ix = $response - 1; $ix = $response - 1;
} else { } else {
print STDERR "Sorry, only $num hunks available.\n"; error_msg "Sorry, only $num hunks available.\n";
} }
next; next;
} }
@ -1018,14 +1060,22 @@ sub patch_update_file {
next; next;
} }
elsif ($line =~ m|^/(.*)|) { elsif ($line =~ m|^/(.*)|) {
my $regex = $1;
if ($1 eq "") {
print colored $prompt_color, "search for regex? ";
$regex = <STDIN>;
if (defined $regex) {
chomp $regex;
}
}
my $search_string; my $search_string;
eval { eval {
$search_string = qr{$1}m; $search_string = qr{$regex}m;
}; };
if ($@) { if ($@) {
my ($err,$exp) = ($@, $1); my ($err,$exp) = ($@, $1);
$err =~ s/ at .*git-add--interactive line \d+, <STDIN> line \d+.*$//; $err =~ s/ at .*git-add--interactive line \d+, <STDIN> line \d+.*$//;
print STDERR "Malformed search regexp $exp: $err\n"; error_msg "Malformed search regexp $exp: $err\n";
next; next;
} }
my $iy = $ix; my $iy = $ix;
@ -1035,7 +1085,7 @@ sub patch_update_file {
$iy++; $iy++;
$iy = 0 if ($iy >= $num); $iy = 0 if ($iy >= $num);
if ($ix == $iy) { if ($ix == $iy) {
print STDERR "No hunk matches the given pattern\n"; error_msg "No hunk matches the given pattern\n";
last; last;
} }
} }
@ -1047,7 +1097,7 @@ sub patch_update_file {
$ix--; $ix--;
} }
else { else {
print STDERR "No previous hunk\n"; error_msg "No previous hunk\n";
} }
next; next;
} }
@ -1056,7 +1106,7 @@ sub patch_update_file {
$ix++; $ix++;
} }
else { else {
print STDERR "No next hunk\n"; error_msg "No next hunk\n";
} }
next; next;
} }
@ -1069,13 +1119,13 @@ sub patch_update_file {
} }
} }
else { else {
print STDERR "No previous hunk\n"; error_msg "No previous hunk\n";
} }
next; next;
} }
elsif ($line =~ /^j/) { elsif ($line =~ /^j/) {
if ($other !~ /j/) { if ($other !~ /j/) {
print STDERR "No next hunk\n"; error_msg "No next hunk\n";
next; next;
} }
} }

Loading…
Cancel
Save