Subject: bug#2034: [PATCH] 27.0.50; Support mode line constructs for `mode-name' in c-mode

From: Phil Sainty <[email-masked]>
Date: Thu, 05 Jul 2018 09:13:38 +1200

Hi Alan,

On 2018-07-05 08:11, Alan Mackenzie wrote:
> But I must confess, I'm not filled with enthusiasm by this change.  
> What
> is the problem it is fixing?  The original problem (use of a CC Mode
> command by a non CC Mode mode) went away when cc-subword.el became just
> subword-mode.

I believe the original problem was the same as the problem I'm aiming to 
fix,
which is that `c-update-modeline' imposes a non-standard restriction 
upon
`mode-name' that it be a simple string (as opposed to containing 
arbitrary
mode line constructs, as it should be able to do).

It seems that the original symptom of the problem in this bug report 
went
away as a side-effect of the change to subword-mode, but the bug itself
remained.

`c-update-modeline' even contains a "FIXME" comment about it:

         ;; FIXME: Derived modes might want to use something else
         ;; than a string for `mode-name'.

> This change introduces complexity, even if, perhaps, not very much.  Do
> we really need a buffer local variable for the display of these flags?
> (That's a real question, not a rhetorical one.)  It seems to be 
> inviting
> misuse, given that it prevails for ever, but is really only valid for
> the short time between it being calculated and the mode line being
> displayed.

In the current version of the patch, the buffer-local variable is used 
every
time the mode line is rendered, as the variable *symbol* is incorporated 
into
`mode-name'.  However Stefan made the suggestion that the flags 
themselves
could become a list of mode line constructs, which would then mean it 
could
be a global value rather than a buffer-local one, as each buffer would 
render
that single construct into the appropriate flags for its own buffer.

>     +(defvar-local c-modeline-flags-major-modes-processed nil
>     +  "Major modes for which `c-update-modeline' has processed 
> `mode-name'.
> 
> .... seems confused.

That was a mistake on my part, and I was intending to change it from a 
list
to a single value record of the most recent `major-mode' to be 
processed.

The reason for having a record in the first place is that a major mode 
which
is *derived* from, say, `c-mode' can trigger `c-update-modeline' 
repeatedly
with different values for `major-mode', and if we see a *new* 
`major-mode'
value then `mode-name' will also have been reset (to a string, in the 
existing
cases), and needs to be processed again, as each major mode body resets
`mode-name'.

i.e. We need to process `mode-name' exactly once for whatever the final
major mode is.

Something like: (unless (eq major-mode c-modeline-major-mode)...), with
buffer-local `c-modeline-major-mode' then set to the value of 
`major-mode'.

> I'm rather sceptical about
> 
>     (setq mode-name (list mode-name .....
> 
> , which is just screaming out for an unbounded appending of other
> things, many times over, if anything goes wrong with the enclosing
> `unless' form. What happens to it when the major mode is changed?

Hopefully you find the aforementioned proposed change less concerning.

> Would it not be possible, somehow, either to leave mode-name 
> unmolested,
> or calculate it unrecursively when needed?

Not that I can think of.  AFAIK using mode line constructs in 
`mode-name'
is exactly how these kinds of things are supposed to be done.

> As a final point, how is the backward compatibility of this change?  
> How
> many former Emacsen will it work in?

I've not checked.  I think these mode line constructs have been stable 
for
a long time?  If a new third-party derived mode was written to have a 
fancy
`mode-name' then obviously that would only work with an Emacs version 
which
contained these changes.  I'm not sure what you're getting at here, 
though...
Are you saying that people will use newer cc-mode code with older 
emacsen?
I can do some testing if I know what the use-case is.

-Phil