git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: <trast@student.ethz.ch>
To: <git@vger.kernel.org>
Cc: Junio C Hamano <gitster@pobox.com>, Jeff King <peff@peff.net>,
	Thomas Rast <trast@student.ethz.ch>
Subject: [PATCH] add -i: ignore terminal escape sequences
Date: Tue, 17 May 2011 17:19:08 +0200	[thread overview]
Message-ID: <05ce7ccdb3f4e07724d430f6ea2a8c9730971c9d.1305645331.git.trast@student.ethz.ch> (raw)

From: Thomas Rast <trast@student.ethz.ch>

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>
---

I nearly managed to lose a bunch of uncommitted work today, but could
salvage most of it from the pieces of diffs in the terminal
scrollback.  Sigh.

Future work might include mapping such sequences to the keys they
represent, so that (shift) up-arrow can be k (K) and (shift)
down-arrow j (J), or some such.

Oh yeah, PS: I'm alive ;-)

 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 4f08fe7..8f0839d 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -45,6 +45,9 @@
 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 @@
 		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;
-- 
1.7.5.1.520.g98107.dirty

             reply	other threads:[~2011-05-17 15:25 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-17 15:19 trast [this message]
2011-05-18  3:52 ` [PATCH] add -i: ignore terminal escape sequences Junio C Hamano
2011-05-18  4:37   ` Sverre Rabbelier
2011-05-18  5:03     ` Junio C Hamano
2011-05-18  5:54       ` Jeff King
2011-05-18  7:33         ` Thomas Rast

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=05ce7ccdb3f4e07724d430f6ea2a8c9730971c9d.1305645331.git.trast@student.ethz.ch \
    --to=trast@student.ethz.ch \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).