Subject: bug#36803: 27.0.50; Update mode-line of every window when compilation ends

From: Eli Zaretskii <[email-masked]>
Date: Sat, 27 Jul 2019 10:46:38 +0300

> From: Stefan Monnier <[email-masked]>
> Cc: [email-masked],  [email-masked],  [email-masked]
> Date: Fri, 26 Jul 2019 17:10:40 -0400
> 
> >> Right: there are 2 windows displaying the original buffer, plus a third
> >> one displaying the compilation buffer.  The C code for process sentinels
> >> makes sure that the mode-line of the window showing the compilation
> >> buffer get updated (for the benefit of mode-line-process, presumably),
> >> but none of the others.
> >> As it so happens, one of the others also gets updated because it's the
> >> currently selected_window.
> >
> > That's not what happens.  What happens is that one of the windows
> > still shows "Compiling" after the process exits.
> 
> AFAIK this is indeed just what I describe in the previous paragraph
> (i.e. at the end of the compilation, when the sentinel is run, the
> C part of the sentinel processing causes the refresh of the mode-line
> of the window showing the compilation buffer, the redisplay itself will
> on its own accord decide to refresh the selected window's mode-line,
> but the third window's mode-line is not refreshed because noone tells
> the C code that all mode-lines indicated the status of this specific
> process).

Yes.  And if you add to the recipe yet another, unrelated buffer
displayed in the 4th window, then its mode line will also show
"Compiling" if that buffer is not the current buffer when "M-x
compile" is invoked.

> > But right now the mode line of *scratch* does show "Compiling"
> > in all of its windows, so there's a global setting that is updated
> > when the process starts and ends,
> 
> Indeed.
> 
> > and that change isn't triggering the update of mode lines in all the
> > windows showing *scratch*.  I still don't understand how you explain
> > that inconsistency.
> 
> Very simple: the change in the mode-line is caused by a change to the
> `compilation-in-progress` global variable.  Yet, the mode-line
> infrastructure is not setup to track dependencies on variables; instead
> it's traditionally the responsability of the code which sets this
> variable to explicitly call force-mode-line-update (as is done, for
> example in all minor-modes (from within `define-minor-mode`)).

The variable compilation-in-progress is specific to compile.el.
However, the problem its use exposes is more general, and the general
problem cannot IMO be reasonably put under the responsibility of the
code which could cause it (and I don't really agree with the
"traditional" part above).  More about this below.

> > If the call to force-mode-line-update is the solution you suggest,
> > then I think it is not a good solution.  We cannot rely in a call to
> > force-mode-line-update, because there's the default sentinel, and
> 
> The default sentinel does not modify `compilation-in-progress` (nor any
> other global variable for that matter), so there's never any need to
> update all the mode-lines at the end of a process using the default sentinel.
> 
> > because it's unreasonable to request each sentinel written in Lisp to
> > make that call.  If every sentinel must do that, then the core should
> > do that for them.
> 
> Not all sentinels must so that.  Only those which set global variables
> whose content affects the mode-line of "all" windows (not necessarily
> all, tho, but at least more than just the mode lines of the current
> buffer).

And that brings me right back to the beginning.  In response to my
original question, you said:

> Hmm... AFAIK the "process status" normally only indicates the status of
> the process running in the buffer to which this mode line belongs.
> Which is why I made the change to only bset_update_mode_line rather than
> set the global update_mode_lines.

This is true only if the process status is modified via
mode-line-process, which is a buffer-local variable.  If a Lisp
program modifies the mode line directly, the result will be global.
That's what compile.el does via compilation-in-progress, but the most
basic operation is simply to add %s to mode-line-format (or to
header-line-format or even to frame-title-format).  When a Lisp
program or the user does that, I see no way of keeping that indicator
up to date except trigger mode-line updates in all windows in
status_notify.  Any other method will be simply unreliable.

Am I missing something?