add -i: ignore terminal escape sequences
On the author's terminal, the up-arrow input sequence is ^[[A, and thus fat-fingering an up-arrow into 'git checkout -p' is quite dangerous: git-add--interactive.perl will ignore the ^[ and [ characters and happily treat A as "discard everything". As a band-aid fix, use Term::Cap to get all terminal capabilities. Then use the heuristic that any capability value that starts with ^[ (i.e., \e in perl) must be a key input sequence. Finally, given an input that starts with ^[, read more characters until we have read a full escape sequence, then return that to the caller. We use a timeout of 0.5 seconds on the subsequent reads to avoid getting stuck if the user actually input a lone ^[. Since none of the currently recognized keys start with ^[, the net result is that the sequence as a whole will be ignored and the help displayed. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
ea1ab4b280
commit
b5cc003253
@ -45,6 +45,9 @@ my ($diff_new_color) =
|
|||||||
my $normal_color = $repo->get_color("", "reset");
|
my $normal_color = $repo->get_color("", "reset");
|
||||||
|
|
||||||
my $use_readkey = 0;
|
my $use_readkey = 0;
|
||||||
|
my $use_termcap = 0;
|
||||||
|
my %term_escapes;
|
||||||
|
|
||||||
sub ReadMode;
|
sub ReadMode;
|
||||||
sub ReadKey;
|
sub ReadKey;
|
||||||
if ($repo->config_bool("interactive.singlekey")) {
|
if ($repo->config_bool("interactive.singlekey")) {
|
||||||
@ -53,6 +56,14 @@ if ($repo->config_bool("interactive.singlekey")) {
|
|||||||
Term::ReadKey->import;
|
Term::ReadKey->import;
|
||||||
$use_readkey = 1;
|
$use_readkey = 1;
|
||||||
};
|
};
|
||||||
|
eval {
|
||||||
|
require Term::Cap;
|
||||||
|
my $termcap = Term::Cap->Tgetent;
|
||||||
|
foreach (values %$termcap) {
|
||||||
|
$term_escapes{$_} = 1 if /^\e/;
|
||||||
|
}
|
||||||
|
$use_termcap = 1;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
sub colored {
|
sub colored {
|
||||||
@ -1067,6 +1078,14 @@ sub prompt_single_character {
|
|||||||
ReadMode 'cbreak';
|
ReadMode 'cbreak';
|
||||||
my $key = ReadKey 0;
|
my $key = ReadKey 0;
|
||||||
ReadMode 'restore';
|
ReadMode 'restore';
|
||||||
|
if ($use_termcap and $key eq "\e") {
|
||||||
|
while (!defined $term_escapes{$key}) {
|
||||||
|
my $next = ReadKey 0.5;
|
||||||
|
last if (!defined $next);
|
||||||
|
$key .= $next;
|
||||||
|
}
|
||||||
|
$key =~ s/\e/^[/;
|
||||||
|
}
|
||||||
print "$key" if defined $key;
|
print "$key" if defined $key;
|
||||||
print "\n";
|
print "\n";
|
||||||
return $key;
|
return $key;
|
||||||
|
Loading…
Reference in New Issue
Block a user