Merge branch 'ls/editor-waiting-message'

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
This commit is contained in:
Junio C Hamano 2017-12-19 11:33:59 -08:00
commit 0c69a132cb
7 changed files with 41 additions and 7 deletions

View File

@ -354,6 +354,9 @@ advice.*::
ignoredHook:: ignoredHook::
Advice shown if an hook is ignored because the hook is not Advice shown if an hook is ignored because the hook is not
set as executable. set as executable.
waitingForEditor::
Print a message to the terminal whenever Git is waiting for
editor input from the user.
-- --
core.fileMode:: core.fileMode::

View File

@ -18,6 +18,7 @@ int advice_object_name_warning = 1;
int advice_rm_hints = 1; int advice_rm_hints = 1;
int advice_add_embedded_repo = 1; int advice_add_embedded_repo = 1;
int advice_ignored_hook = 1; int advice_ignored_hook = 1;
int advice_waiting_for_editor = 1;
static struct { static struct {
const char *name; const char *name;
@ -40,6 +41,7 @@ static struct {
{ "rmhints", &advice_rm_hints }, { "rmhints", &advice_rm_hints },
{ "addembeddedrepo", &advice_add_embedded_repo }, { "addembeddedrepo", &advice_add_embedded_repo },
{ "ignoredhook", &advice_ignored_hook }, { "ignoredhook", &advice_ignored_hook },
{ "waitingforeditor", &advice_waiting_for_editor },
/* make this an alias for backward compatibility */ /* make this an alias for backward compatibility */
{ "pushnonfastforward", &advice_push_update_rejected } { "pushnonfastforward", &advice_push_update_rejected }

View File

@ -20,6 +20,7 @@ extern int advice_object_name_warning;
extern int advice_rm_hints; extern int advice_rm_hints;
extern int advice_add_embedded_repo; extern int advice_add_embedded_repo;
extern int advice_ignored_hook; extern int advice_ignored_hook;
extern int advice_waiting_for_editor;
int git_default_advice_config(const char *var, const char *value); int git_default_advice_config(const char *var, const char *value);
__attribute__((format (printf, 1, 2))) __attribute__((format (printf, 1, 2)))

View File

@ -1491,6 +1491,7 @@ extern const char *ident_default_name(void);
extern const char *ident_default_email(void); extern const char *ident_default_email(void);
extern const char *git_editor(void); extern const char *git_editor(void);
extern const char *git_pager(int stdout_is_tty); 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 int git_ident_config(const char *, const char *, void *);
extern void reset_ident_date(void); extern void reset_ident_date(void);

View File

@ -329,8 +329,7 @@ static int check_auto_color(void)
if (color_stdout_is_tty < 0) if (color_stdout_is_tty < 0)
color_stdout_is_tty = isatty(1); color_stdout_is_tty = isatty(1);
if (color_stdout_is_tty || (pager_in_use() && pager_use_color)) { if (color_stdout_is_tty || (pager_in_use() && pager_use_color)) {
char *term = getenv("TERM"); if (!is_terminal_dumb())
if (term && strcmp(term, "dumb"))
return 1; return 1;
} }
return 0; return 0;

View File

@ -7,11 +7,16 @@
#define DEFAULT_EDITOR "vi" #define DEFAULT_EDITOR "vi"
#endif #endif
int is_terminal_dumb(void)
{
const char *terminal = getenv("TERM");
return !terminal || !strcmp(terminal, "dumb");
}
const char *git_editor(void) const char *git_editor(void)
{ {
const char *editor = getenv("GIT_EDITOR"); const char *editor = getenv("GIT_EDITOR");
const char *terminal = getenv("TERM"); int terminal_is_dumb = is_terminal_dumb();
int terminal_is_dumb = !terminal || !strcmp(terminal, "dumb");
if (!editor && editor_program) if (!editor && editor_program)
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 }; const char *args[] = { editor, real_path(path), NULL };
struct child_process p = CHILD_PROCESS_INIT; struct child_process p = CHILD_PROCESS_INIT;
int ret, sig; 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.argv = args;
p.env = env; p.env = env;
@ -58,6 +80,13 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en
if (ret) if (ret)
return error("There was a problem with the editor '%s'.", return error("There was a problem with the editor '%s'.",
editor); 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) if (!buffer)

View File

@ -20,13 +20,12 @@
int recv_sideband(const char *me, int in_stream, int out) int recv_sideband(const char *me, int in_stream, int out)
{ {
const char *term, *suffix; const char *suffix;
char buf[LARGE_PACKET_MAX + 1]; char buf[LARGE_PACKET_MAX + 1];
struct strbuf outbuf = STRBUF_INIT; struct strbuf outbuf = STRBUF_INIT;
int retval = 0; int retval = 0;
term = getenv("TERM"); if (isatty(2) && !is_terminal_dumb())
if (isatty(2) && term && strcmp(term, "dumb"))
suffix = ANSI_SUFFIX; suffix = ANSI_SUFFIX;
else else
suffix = DUMB_SUFFIX; suffix = DUMB_SUFFIX;