Skip to content

Commit b5cc003

Browse files
trastgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ea1ab4b commit b5cc003

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

git-add--interactive.perl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
my $normal_color = $repo->get_color("", "reset");
4646

4747
my $use_readkey = 0;
48+
my $use_termcap = 0;
49+
my %term_escapes;
50+
4851
sub ReadMode;
4952
sub ReadKey;
5053
if ($repo->config_bool("interactive.singlekey")) {
@@ -53,6 +56,14 @@
5356
Term::ReadKey->import;
5457
$use_readkey = 1;
5558
};
59+
eval {
60+
require Term::Cap;
61+
my $termcap = Term::Cap->Tgetent;
62+
foreach (values %$termcap) {
63+
$term_escapes{$_} = 1 if /^\e/;
64+
}
65+
$use_termcap = 1;
66+
};
5667
}
5768

5869
sub colored {
@@ -1067,6 +1078,14 @@ sub prompt_single_character {
10671078
ReadMode 'cbreak';
10681079
my $key = ReadKey 0;
10691080
ReadMode 'restore';
1081+
if ($use_termcap and $key eq "\e") {
1082+
while (!defined $term_escapes{$key}) {
1083+
my $next = ReadKey 0.5;
1084+
last if (!defined $next);
1085+
$key .= $next;
1086+
}
1087+
$key =~ s/\e/^[/;
1088+
}
10701089
print "$key" if defined $key;
10711090
print "\n";
10721091
return $key;

0 commit comments

Comments
 (0)