git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: lars.schneider@autodesk.com
Cc: git@vger.kernel.org, sbeller@google.com, sunshine@sunshineco.com,
	kaartic.sivaraam@gmail.com,
	Lars Schneider <larsxschneider@gmail.com>
Subject: Re: [PATCH v3] launch_editor(): indicate that Git waits for user input
Date: Tue, 28 Nov 2017 08:18:30 +0900	[thread overview]
Message-ID: <xmqqefojb9a1.fsf@gitster.mtv.corp.google.com> (raw)
In-Reply-To: <20171127134716.69471-1-lars.schneider@autodesk.com> (lars schneider's message of "Mon, 27 Nov 2017 14:47:16 +0100")

lars.schneider@autodesk.com writes:

> diff to v2:
>     - shortened and localized the "waiting" message
>     - detect "emacsclient" and suppress "waiting" message

Thanks for moving this forward.


> +		static const char *close_notice = NULL;

Because this thing is "static", the variable is NULL when the first
call to this function is made, and the value left in the variable
when a call returns will be seen by the next call.

> +		if (isatty(2) && !close_notice) {

Declaring a "static" variable initialized to NULL and checking its
NULL-ness upfront is a common pattern to make sure that the code
avoids repeated computation of the same thing.  The body of the if
statement is run only when standard error stream is a tty (hinting
an interactive session) *and* close_notice is (still) NULL.

> +			char *term = getenv("TERM");
> +
> +			if (term && strcmp(term, "dumb"))
> +				/*
> +				 * go back to the beginning and erase the
> +				 * entire line if the terminal is capable
> +				 * to do so, to avoid wasting the vertical
> +				 * space.
> +				 */
> +				close_notice = "\r\033[K";
> +			else if (term && strstr(term, "emacsclient"))
> +				/*
> +				 * `emacsclient` (or `emacsclientw` on Windows) already prints
> +				 * ("Waiting for Emacs...") if a file is opened for editing.
> +				 * Therefore, we don't need to print the editor launch info.
> +				 */
> +				;
> +			else
> +				/* otherwise, complete and waste the line */
> +				close_notice = _("done.\n");
> +		}

It assigns a non-NULL value to close_notice unless the editor is
emacsclient (modulo the bug that "emacsclient" is to be compared
with EDITOR, GIT_EDITOR, core.editor etc. -- git_editor() can be
used to pick the right one).  For a user of that particular editor,
it is left as NULL.  Because it is unlikely that EDITOR etc. would
change across calls to this function, for them, and only for them,
the above is computed to yield the same result every time this
function is called.

That feels a bit uneven, doesn't it?

There are two possible solutions:

1. drop "static" from the declaration to stress the fact that the
   variable and !close_notice in the upfront if() statement is not
   avoiding repeated computation of the same thing, or

2. arrange that "emacsclient" case also participates in "avoid
   repeated computation" dance.  While at it, swap the order of
   checking isatty(2) and !close_notice (aka "have we done this
   already?)--because we do not expect us swapping file descriptor
   #2 inside this single process, we'd be repeatedly asking
   isatty(2) for the same answer.

The former may be simpler and easier, as an editor invocation would
not be a performance critical codepath.

If we want to do the latter, a cleaner way may be to have another
static "static int use_notice_checked = 0;" declared, and then

	if (!use_notice_checked && isatty(2)) {
		... what you currently have, modulo the
		... fix for the editor thing, and set
		... close_notice to a string (or NULL).
                use_notice_checked = 1;
	}

The users of close_notice after this part that use !close_notice
as "do not give the notice at all" flag and also as "this is the
string to show after editor comes back" can stay the same if you go
this route.  That would be solution 2a.

Of course, you can instead use close_notice = "" (empty string) as a
signal "we checked and we know that we are not using the notice
thing".  If you go that route, then the users after this if statement
that sets up close_notice upon the first call would say !*close_notice
instead of !close_notice when they try to see if the notice is in use.
That would be solution 2b.

I personally think any one of 1., 2a., or 2b. is fine.


  parent reply	other threads:[~2017-11-27 23:18 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-27 13:47 [PATCH v3] launch_editor(): indicate that Git waits for user input lars.schneider
2017-11-27 17:17 ` Kaartic Sivaraam
2017-11-27 18:36 ` Eric Sunshine
2017-11-27 20:04   ` Lars Schneider
2017-11-27 20:09 ` brian m. carlson
2017-11-27 23:05   ` Jeff King
2017-11-28  4:29     ` Junio C Hamano
2017-11-28 12:31     ` Lars Schneider
2017-11-29  2:06     ` brian m. carlson
2017-11-27 23:18 ` Junio C Hamano [this message]
2017-11-28 12:39   ` Lars Schneider

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqefojb9a1.fsf@gitster.mtv.corp.google.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=kaartic.sivaraam@gmail.com \
    --cc=lars.schneider@autodesk.com \
    --cc=larsxschneider@gmail.com \
    --cc=sbeller@google.com \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).