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>maint
							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
	
	 Thomas Rast
						Thomas Rast