{"thread":{"id":"17565","subject":"[PATCH v3 4/4] add -p: print errors in separate color","startedAt":"2009-02-04T20:12:38Z","lastAt":"2009-02-04T20:12:39Z","messageCount":2,"participants":["Thomas Rast"],"isPatch":true,"patchVersion":3,"patchTotal":4},"messages":[{"id":"103193","messageId":"1233778359-7568-1-git-send-email-trast@student.ethz.ch","threadId":"17565","inReplyTo":"200902042042.13787.trast@student.ethz.ch","subject":"[PATCH v3 3/4] add -p: prompt for single characters","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-02-04T20:12:38Z","receivedAt":"2009-02-04T20:12:38Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Use Term::ReadKey, if available and enabled with interactive.readkey,\nto let the user answer add -p's prompts by pressing a single key.\nWe're not doing the same in the main 'add -i' interface because file\nselection etc. may expect several characters.\n\nTwo commands take an argument: 'g' can easily cope since it'll just\noffer a choice of chunks.  '/' now (unconditionally, even without\nreadkey) offers a chance to enter a regex if none was given.\n\nDocumentation text by Jeff King.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n\nBah; I edited the patch message after format-patch last time and\nforgot to do it again.  The above is the intended message that covers\n'/' too.  Sorry for the noise.\n\n\n Documentation/config.txt  |    8 ++++++++\n git-add--interactive.perl |   45 +++++++++++++++++++++++++++++++++++++++++----\n 2 files changed, 49 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 7fbf64d..403edb8 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1013,6 +1013,14 @@ instaweb.port::\n \tThe port number to bind the gitweb httpd to. See\n \tlinkgit:git-instaweb[1].\n \n+interactive.readkey::\n+\tIn interactive programs, allow the user to provide one-letter\n+\tinput with a single key (i.e., without hitting\n+\tenter). Currently this is used only by the `\\--patch` mode of\n+\tlinkgit:git-add[1].  Note that this feature is silently\n+\tdisabled for Perl programs (like git-add) if Term::ReadKey is\n+\tnot available.\n+\n log.date::\n \tSet default date-time mode for the log command. Setting log.date\n \tvalue is similar to using 'git-log'\\'s --date option. The value is one of the\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex 3bf0cda..3aa21db 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -33,6 +33,14 @@ my ($diff_new_color) =\n \n my $normal_color = $repo->get_color(\"\", \"reset\");\n \n+my $use_readkey = 0;\n+if ($repo->config_bool(\"interactive.readkey\")) {\n+\teval {\n+\t\tuse Term::ReadKey;\n+\t\t$use_readkey = 1;\n+\t};\n+}\n+\n sub colored {\n \tmy $color = shift;\n \tmy $string = join(\"\", @_);\n@@ -758,11 +766,32 @@ sub diff_applies {\n \treturn close $fh;\n }\n \n+sub _restore_terminal_and_die {\n+\tReadMode 'restore';\n+\tprint \"\\n\";\n+\texit 1;\n+}\n+\n+sub prompt_single_character {\n+\tif ($use_readkey) {\n+\t\tlocal $SIG{TERM} = \\&_restore_terminal_and_die;\n+\t\tlocal $SIG{INT} = \\&_restore_terminal_and_die;\n+\t\tReadMode 'cbreak';\n+\t\tmy $key = ReadKey 0;\n+\t\tReadMode 'restore';\n+\t\tprint \"$key\" if defined $key;\n+\t\tprint \"\\n\";\n+\t\treturn $key;\n+\t} else {\n+\t\treturn <STDIN>;\n+\t}\n+}\n+\n sub prompt_yesno {\n \tmy ($prompt) = @_;\n \twhile (1) {\n \t\tprint colored $prompt_color, $prompt;\n-\t\tmy $line = <STDIN>;\n+\t\tmy $line = prompt_single_character;\n \t\treturn 0 if $line =~ /^n/i;\n \t\treturn 1 if $line =~ /^y/i;\n \t}\n@@ -893,7 +922,7 @@ sub patch_update_file {\n \t\t\tprint @{$mode->{DISPLAY}};\n \t\t\tprint colored $prompt_color,\n \t\t\t\t\"Stage mode change [y/n/a/d/?]? \";\n-\t\t\tmy $line = <STDIN>;\n+\t\t\tmy $line = prompt_single_character;\n \t\t\tif ($line =~ /^y/i) {\n \t\t\t\t$mode->{USE} = 1;\n \t\t\t\tlast;\n@@ -966,7 +995,7 @@ sub patch_update_file {\n \t\t\tprint;\n \t\t}\n \t\tprint colored $prompt_color, \"Stage this hunk [y,n,a,d,/$other,?]? \";\n-\t\tmy $line = <STDIN>;\n+\t\tmy $line = prompt_single_character;\n \t\tif ($line) {\n \t\t\tif ($line =~ /^y/i) {\n \t\t\t\t$hunk[$ix]{USE} = 1;\n@@ -1018,9 +1047,17 @@ sub patch_update_file {\n \t\t\t\tnext;\n \t\t\t}\n \t\t\telsif ($line =~ m|^/(.*)|) {\n+\t\t\t\tmy $regex = $1;\n+\t\t\t\tif ($1 eq \"\") {\n+\t\t\t\t\tprint colored $prompt_color, \"search for regex? \";\n+\t\t\t\t\t$regex = <STDIN>;\n+\t\t\t\t\tif (defined $regex) {\n+\t\t\t\t\t\tchomp $regex;\n+\t\t\t\t\t}\n+\t\t\t\t}\n \t\t\t\tmy $search_string;\n \t\t\t\teval {\n-\t\t\t\t\t$search_string = qr{$1}m;\n+\t\t\t\t\t$search_string = qr{$regex}m;\n \t\t\t\t};\n \t\t\t\tif ($@) {\n \t\t\t\t\tmy ($err,$exp) = ($@, $1);\n-- \n1.6.1.2.554.g6515b\n"},{"id":"103192","messageId":"1233778359-7568-2-git-send-email-trast@student.ethz.ch","threadId":"17565","inReplyTo":"1233778359-7568-1-git-send-email-trast@student.ethz.ch","subject":"[PATCH v3 4/4] add -p: print errors in separate color","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-02-04T20:12:39Z","receivedAt":"2009-02-04T20:12:39Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Print interaction error messages in color.interactive.error, which\ndefaults to the value of color.interactive.help.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n Documentation/config.txt  |    4 ++--\n git-add--interactive.perl |   30 ++++++++++++++++++++----------\n 2 files changed, 22 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 403edb8..51f684f 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -569,8 +569,8 @@ color.interactive::\n \n color.interactive.<slot>::\n \tUse customized color for 'git-add --interactive'\n-\toutput. `<slot>` may be `prompt`, `header`, or `help`, for\n-\tthree distinct types of normal output from interactive\n+\toutput. `<slot>` may be `prompt`, `header`, `help` or `error`, for\n+\tfour distinct types of normal output from interactive\n \tprograms.  The values of these variables may be specified as\n \tin color.branch.<slot>.\n \ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex 3aa21db..e06a445 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -12,6 +12,12 @@ my ($prompt_color, $header_color, $help_color) =\n \t\t$repo->get_color('color.interactive.header', 'bold'),\n \t\t$repo->get_color('color.interactive.help', 'red bold'),\n \t) : ();\n+my $error_color = ();\n+if ($menu_use_color) {\n+\tmy $help_color_spec = $repo->config('color.interactive.help');\n+\t$error_color = $repo->get_color('color.interactive.error',\n+\t\t\t\t\t$help_color_spec);\n+}\n \n my $diff_use_color = $repo->get_colorbool('color.diff');\n my ($fraginfo_color) =\n@@ -333,6 +339,10 @@ sub highlight_prefix {\n \treturn \"$prompt_color$prefix$normal_color$remainder\";\n }\n \n+sub error_msg {\n+\tprint STDERR colored $error_color, @_;\n+}\n+\n sub list_and_choose {\n \tmy ($opts, @stuff) = @_;\n \tmy (@chosen, @return);\n@@ -428,12 +438,12 @@ sub list_and_choose {\n \t\t\telse {\n \t\t\t\t$bottom = $top = find_unique($choice, @stuff);\n \t\t\t\tif (!defined $bottom) {\n-\t\t\t\t\tprint \"Huh ($choice)?\\n\";\n+\t\t\t\t\terror_msg \"Huh ($choice)?\\n\";\n \t\t\t\t\tnext TOPLOOP;\n \t\t\t\t}\n \t\t\t}\n \t\t\tif ($opts->{SINGLETON} && $bottom != $top) {\n-\t\t\t\tprint \"Huh ($choice)?\\n\";\n+\t\t\t\terror_msg \"Huh ($choice)?\\n\";\n \t\t\t\tnext TOPLOOP;\n \t\t\t}\n \t\t\tfor ($i = $bottom-1; $i <= $top-1; $i++) {\n@@ -1029,11 +1039,11 @@ sub patch_update_file {\n \t\t\t\t\tchomp $response;\n \t\t\t\t}\n \t\t\t\tif ($response !~ /^\\s*\\d+\\s*$/) {\n-\t\t\t\t\tprint STDERR \"Invalid number: '$response'\\n\";\n+\t\t\t\t\terror_msg \"Invalid number: '$response'\\n\";\n \t\t\t\t} elsif (0 < $response && $response <= $num) {\n \t\t\t\t\t$ix = $response - 1;\n \t\t\t\t} else {\n-\t\t\t\t\tprint STDERR \"Sorry, only $num hunks available.\\n\";\n+\t\t\t\t\terror_msg \"Sorry, only $num hunks available.\\n\";\n \t\t\t\t}\n \t\t\t\tnext;\n \t\t\t}\n@@ -1062,7 +1072,7 @@ sub patch_update_file {\n \t\t\t\tif ($@) {\n \t\t\t\t\tmy ($err,$exp) = ($@, $1);\n \t\t\t\t\t$err =~ s/ at .*git-add--interactive line \\d+, <STDIN> line \\d+.*$//;\n-\t\t\t\t\tprint STDERR \"Malformed search regexp $exp: $err\\n\";\n+\t\t\t\t\terror_msg \"Malformed search regexp $exp: $err\\n\";\n \t\t\t\t\tnext;\n \t\t\t\t}\n \t\t\t\tmy $iy = $ix;\n@@ -1072,7 +1082,7 @@ sub patch_update_file {\n \t\t\t\t\t$iy++;\n \t\t\t\t\t$iy = 0 if ($iy >= $num);\n \t\t\t\t\tif ($ix == $iy) {\n-\t\t\t\t\t\tprint STDERR \"No hunk matches the given pattern\\n\";\n+\t\t\t\t\t\terror_msg \"No hunk matches the given pattern\\n\";\n \t\t\t\t\t\tlast;\n \t\t\t\t\t}\n \t\t\t\t}\n@@ -1084,7 +1094,7 @@ sub patch_update_file {\n \t\t\t\t\t$ix--;\n \t\t\t\t}\n \t\t\t\telse {\n-\t\t\t\t\tprint STDERR \"No previous hunk\\n\";\n+\t\t\t\t\terror_msg \"No previous hunk\\n\";\n \t\t\t\t}\n \t\t\t\tnext;\n \t\t\t}\n@@ -1093,7 +1103,7 @@ sub patch_update_file {\n \t\t\t\t\t$ix++;\n \t\t\t\t}\n \t\t\t\telse {\n-\t\t\t\t\tprint STDERR \"No next hunk\\n\";\n+\t\t\t\t\terror_msg \"No next hunk\\n\";\n \t\t\t\t}\n \t\t\t\tnext;\n \t\t\t}\n@@ -1106,13 +1116,13 @@ sub patch_update_file {\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t\telse {\n-\t\t\t\t\tprint STDERR \"No previous hunk\\n\";\n+\t\t\t\t\terror_msg \"No previous hunk\\n\";\n \t\t\t\t}\n \t\t\t\tnext;\n \t\t\t}\n \t\t\telsif ($line =~ /^j/) {\n \t\t\t\tif ($other !~ /j/) {\n-\t\t\t\t\tprint STDERR \"No next hunk\\n\";\n+\t\t\t\t\terror_msg \"No next hunk\\n\";\n \t\t\t\t\tnext;\n \t\t\t\t}\n \t\t\t}\n-- \n1.6.1.2.554.g6515b\n"}]}