]> git.ipfire.org Git - thirdparty/git.git/commitdiff
built-in add -p: respect the `interactive.singlekey` config setting
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Tue, 14 Jan 2020 18:43:50 +0000 (18:43 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 15 Jan 2020 20:06:17 +0000 (12:06 -0800)
The Perl version of `git add -p` supports this config setting to allow
users to input commands via single characters (as opposed to having to
press the <Enter> key afterwards).

This is an opt-in feature because it requires Perl packages
(Term::ReadKey and Term::Cap, where it tries to handle an absence of the
latter package gracefully) to work. Note that at least on Ubuntu, that
Perl package is not installed by default (it needs to be installed via
`sudo apt-get install libterm-readkey-perl`), so this feature is
probably not used a whole lot.

In C, we obviously do not have these packages available, but we just
introduced `read_single_keystroke()` that is similar to what
Term::ReadKey provides, and we use that here.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
add-interactive.c
add-interactive.h
add-patch.c

index 9e4bcb382c527855cb29a5bd4c8f4eb0bc3e9154..39c38964949e6d6d16c68734ab6f86a730ebf8a8 100644 (file)
@@ -60,6 +60,8 @@ void init_add_i_state(struct add_i_state *s, struct repository *r)
        FREE_AND_NULL(s->interactive_diff_algorithm);
        git_config_get_string("diff.algorithm",
                              &s->interactive_diff_algorithm);
+
+       git_config_get_bool("interactive.singlekey", &s->use_single_key);
 }
 
 void clear_add_i_state(struct add_i_state *s)
index 923efaf52718e617ce48b7d4e6d294f5de2ebc13..693f125e8e4bc64ac0ccc8ac3b8dea812a397330 100644 (file)
@@ -16,6 +16,7 @@ struct add_i_state {
        char file_old_color[COLOR_MAXLEN];
        char file_new_color[COLOR_MAXLEN];
 
+       int use_single_key;
        char *interactive_diff_filter, *interactive_diff_algorithm;
 };
 
index 8f2ee8688b5fed4769333fbd8e60cf0fcee95904..d8dafa8168dc8389468d8c2c3cd6221220826605 100644 (file)
@@ -6,6 +6,7 @@
 #include "pathspec.h"
 #include "color.h"
 #include "diff.h"
+#include "compat/terminal.h"
 
 enum prompt_mode_type {
        PROMPT_MODE_CHANGE = 0, PROMPT_DELETION, PROMPT_HUNK,
@@ -1149,14 +1150,27 @@ static int run_apply_check(struct add_p_state *s,
        return 0;
 }
 
+static int read_single_character(struct add_p_state *s)
+{
+       if (s->s.use_single_key) {
+               int res = read_key_without_echo(&s->answer);
+               printf("%s\n", res == EOF ? "" : s->answer.buf);
+               return res;
+       }
+
+       if (strbuf_getline(&s->answer, stdin) == EOF)
+               return EOF;
+       strbuf_trim_trailing_newline(&s->answer);
+       return 0;
+}
+
 static int prompt_yesno(struct add_p_state *s, const char *prompt)
 {
        for (;;) {
                color_fprintf(stdout, s->s.prompt_color, "%s", _(prompt));
                fflush(stdout);
-               if (strbuf_getline(&s->answer, stdin) == EOF)
+               if (read_single_character(s) == EOF)
                        return -1;
-               strbuf_trim_trailing_newline(&s->answer);
                switch (tolower(s->answer.buf[0])) {
                case 'n': return 0;
                case 'y': return 1;
@@ -1396,9 +1410,8 @@ static int patch_update_file(struct add_p_state *s,
                              _(s->mode->prompt_mode[prompt_mode_type]),
                              s->buf.buf);
                fflush(stdout);
-               if (strbuf_getline(&s->answer, stdin) == EOF)
+               if (read_single_character(s) == EOF)
                        break;
-               strbuf_trim_trailing_newline(&s->answer);
 
                if (!s->answer.len)
                        continue;