diff options
author | Thomas Rast <trast@student.ethz.ch> | 2011-05-17 17:19:08 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2011-05-17 20:44:17 -0700 |
commit | b5cc003253c8e1b505d5a2fbbcecb1ffcb409758 (patch) | |
tree | 1433f9ee41fee1a42bce53842c941769792d2eee | |
parent | ea1ab4b280ed3b041da53e161e32e38930569f3e (diff) | |
download | git-b5cc003253c8e1b505d5a2fbbcecb1ffcb409758.tar.gz git-b5cc003253c8e1b505d5a2fbbcecb1ffcb409758.tar.xz |
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>
-rwxr-xr-x | git-add--interactive.perl | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/git-add--interactive.perl b/git-add--interactive.perl index 4f08fe704..8f0839d20 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -45,6 +45,9 @@ my ($diff_new_color) = my $normal_color = $repo->get_color("", "reset"); my $use_readkey = 0; +my $use_termcap = 0; +my %term_escapes; + sub ReadMode; sub ReadKey; if ($repo->config_bool("interactive.singlekey")) { @@ -53,6 +56,14 @@ if ($repo->config_bool("interactive.singlekey")) { Term::ReadKey->import; $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 { @@ -1067,6 +1078,14 @@ sub prompt_single_character { ReadMode 'cbreak'; my $key = ReadKey 0; 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 "\n"; return $key; |