Merge branch 'ls/editor-waiting-message'
authorJunio C Hamano <gitster@pobox.com>
Tue, 19 Dec 2017 19:33:59 +0000 (11:33 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 19 Dec 2017 19:33:59 +0000 (11:33 -0800)
Git shows a message to tell the user that it is waiting for the
user to finish editing when spawning an editor, in case the editor
opens to a hidden window or somewhere obscure and the user gets
lost.

* ls/editor-waiting-message:
launch_editor(): indicate that Git waits for user input
refactor "dumb" terminal determination

Documentation/config.txt
advice.c
advice.h
cache.h
color.c
editor.c
sideband.c
index 9fac2f2b88c4b26a771b698b40483f3472600c96..b18c0f97fec8dda4ba90a245f8e827b57a585cf4 100644 (file)
@@ -354,6 +354,9 @@ advice.*::
        ignoredHook::
                Advice shown if an hook is ignored because the hook is not
                set as executable.
+       waitingForEditor::
+               Print a message to the terminal whenever Git is waiting for
+               editor input from the user.
 --
 
 core.fileMode::
index c6169bcb52fa935969ee938967adb337b06961c7..406efc183ba272b94a39d4cc7e97d7483a40a9d4 100644 (file)
--- a/advice.c
+++ b/advice.c
@@ -18,6 +18,7 @@ int advice_object_name_warning = 1;
 int advice_rm_hints = 1;
 int advice_add_embedded_repo = 1;
 int advice_ignored_hook = 1;
+int advice_waiting_for_editor = 1;
 
 static struct {
        const char *name;
@@ -40,6 +41,7 @@ static struct {
        { "rmhints", &advice_rm_hints },
        { "addembeddedrepo", &advice_add_embedded_repo },
        { "ignoredhook", &advice_ignored_hook },
+       { "waitingforeditor", &advice_waiting_for_editor },
 
        /* make this an alias for backward compatibility */
        { "pushnonfastforward", &advice_push_update_rejected }
index f525d6f89cb44dc39188dd06472cf8a59b56f411..70568fa7922d8aea403e415f9b9b554a88ace293 100644 (file)
--- a/advice.h
+++ b/advice.h
@@ -20,6 +20,7 @@ extern int advice_object_name_warning;
 extern int advice_rm_hints;
 extern int advice_add_embedded_repo;
 extern int advice_ignored_hook;
+extern int advice_waiting_for_editor;
 
 int git_default_advice_config(const char *var, const char *value);
 __attribute__((format (printf, 1, 2)))
diff --git a/cache.h b/cache.h
index 3d00d03d92bc205fea39bb147b51c69f35faa307..a2ec8c0b55422f2b95a30d140cb2bfdf15f0721d 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1491,6 +1491,7 @@ extern const char *ident_default_name(void);
 extern const char *ident_default_email(void);
 extern const char *git_editor(void);
 extern const char *git_pager(int stdout_is_tty);
+extern int is_terminal_dumb(void);
 extern int git_ident_config(const char *, const char *, void *);
 extern void reset_ident_date(void);
 
diff --git a/color.c b/color.c
index 9a9261ac164f503e2a9240806f4f44bedf9b8192..d48dd947c987cdca13f103fd8b4a2e56eceab238 100644 (file)
--- a/color.c
+++ b/color.c
@@ -329,8 +329,7 @@ static int check_auto_color(void)
        if (color_stdout_is_tty < 0)
                color_stdout_is_tty = isatty(1);
        if (color_stdout_is_tty || (pager_in_use() && pager_use_color)) {
-               char *term = getenv("TERM");
-               if (term && strcmp(term, "dumb"))
+               if (!is_terminal_dumb())
                        return 1;
        }
        return 0;
index 7519edecdc297a0c0fdbbb2f3c68cb55abf2e8b2..9a9b4e12d1db7f8ec2f4f99d9a5f348b680cecc3 100644 (file)
--- a/editor.c
+++ b/editor.c
@@ -7,11 +7,16 @@
 #define DEFAULT_EDITOR "vi"
 #endif
 
+int is_terminal_dumb(void)
+{
+       const char *terminal = getenv("TERM");
+       return !terminal || !strcmp(terminal, "dumb");
+}
+
 const char *git_editor(void)
 {
        const char *editor = getenv("GIT_EDITOR");
-       const char *terminal = getenv("TERM");
-       int terminal_is_dumb = !terminal || !strcmp(terminal, "dumb");
+       int terminal_is_dumb = is_terminal_dumb();
 
        if (!editor && editor_program)
                editor = editor_program;
@@ -40,6 +45,23 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en
                const char *args[] = { editor, real_path(path), NULL };
                struct child_process p = CHILD_PROCESS_INIT;
                int ret, sig;
+               int print_waiting_for_editor = advice_waiting_for_editor && isatty(2);
+
+               if (print_waiting_for_editor) {
+                       /*
+                        * A dumb terminal cannot erase the line later on. Add a
+                        * newline to separate the hint from subsequent output.
+                        *
+                        * Make sure that our message is separated with a whitespace
+                        * from further cruft that may be written by the editor.
+                        */
+                       const char term = is_terminal_dumb() ? '\n' : ' ';
+
+                       fprintf(stderr,
+                               _("hint: Waiting for your editor to close the file...%c"),
+                               term);
+                       fflush(stderr);
+               }
 
                p.argv = args;
                p.env = env;
@@ -58,6 +80,13 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en
                if (ret)
                        return error("There was a problem with the editor '%s'.",
                                        editor);
+
+               if (print_waiting_for_editor && !is_terminal_dumb())
+                       /*
+                        * Go back to the beginning and erase the entire line to
+                        * avoid wasting the vertical space.
+                        */
+                       fputs("\r\033[K", stderr);
        }
 
        if (!buffer)
index 1e4d684d6c5dcdeee94f6eb64cfa6e2f17d44674..6d7f943e4384fa90001fbb73cc5b63e2c0cfa639 100644 (file)
 
 int recv_sideband(const char *me, int in_stream, int out)
 {
-       const char *term, *suffix;
+       const char *suffix;
        char buf[LARGE_PACKET_MAX + 1];
        struct strbuf outbuf = STRBUF_INIT;
        int retval = 0;
 
-       term = getenv("TERM");
-       if (isatty(2) && term && strcmp(term, "dumb"))
+       if (isatty(2) && !is_terminal_dumb())
                suffix = ANSI_SUFFIX;
        else
                suffix = DUMB_SUFFIX;