Subject: bug#68352: 29.1; gnus-message-citation-mode removes values from font-lock-keywords

From: Morgan Willcock <[email-masked]>
Date: Wed, 10 Jan 2024 19:20:15 +0000

Eric Abrahamsen <[email-masked]> writes:

> Eric Abrahamsen <[email-masked]> writes:
>
>> Eric Abrahamsen <[email-masked]> writes:
>>
>>> Morgan Willcock <[email-masked]> writes:
>>>
>>>> Eric Abrahamsen <[email-masked]> writes:
>>>>
>>>>> Morgan Willcock <[email-masked]> writes:
>>>>>
>>>>>> When Gnus enables gnus-message-citation-mode in message buffers, as it
>>>>>> does by default, it calls the function `font-lock-set-defaults' and
>>>>>> loses any additional font-lock rules which may have been added by global
>>>>>> minor-modes.
>>>>>
>>>>> Thanks for the report. I don't know font locking well enough to know
>>>>> what the right solution is here. It looks calling `font-lock-flush' will
>>>>> also end up calling `font-lock-set-defaults' as well, at least with
>>>>> default values:
>>>>>
>>>>> font-lock-flush-function ->
>>>>> font-lock-after-change-function ->
>>>>> font-lock-fontify-region ->
>>>>> font-lock-set-defaults
>>>>>
>>>>> Is the problem setting `font-lock-set-defaults' to nil? Is there
>>>>> anything else you can recommend?
>>>>
>>>> I think that I did test not setting `font-lock-set-defaults' to nil to
>>>> see if that made a difference, but the same problem was still there.
>>>>
>>>> I don't know very much myself, but in that section of code there is a
>>>> comment left by Stefan Monnier:
>>>>
>>>>   ;; FIXME: Use font-lock-add-keywords!
>>>
>>> Ha, my eyes went right by that comment.
>>>
>>>> So I would guess that the correct solution would be to add the citation
>>>> font-locking rules with `font-lock-add-keywords' and then remove them
>>>> again with `font-lock-remove-keywords' if the mode is ever disabled, and
>>>> if the highlighting needs an update after those changes, call
>>>> `font-lock-flush'.
>>>
>>> So maybe this is enough?
>>>
>>> (define-minor-mode gnus-message-citation-mode
>>>   "Minor mode providing more font-lock support for nested citations.
>>> When enabled, it automatically turns on `font-lock-mode'."
>>>   :lighter ""
>>>   (when (derived-mode-p 'message-mode)
>>>     (if gnus-message-citation-mode
>>> 	(font-lock-add-keywords nil gnus-message-citation-keywords)
>>>       (font-lock-remove-keywords nil gnus-message-citation-keywords))
>>>     (if font-lock-mode
>>> 	(font-lock-flush)
>>>       (gnus-message-citation-mode (font-lock-mode 1)))))
>>
>> No, that doesn't do it. The thing is, even if you defuse this minor mode
>> entirely (I replaced the body with `(message "Whee!")'),
>> global-whitespace-mode has already been overridden by the time we come
>> to run this minor-mode function. It's already getting clobbered at some
>> earlier point.
>
> Actually, it might just be that something about message-mode suppresses
> whitespace-mode altogether. Even if I turn it on *after* starting a
> reply, no font-locking of whitespace is done.

I haven't had a chance to re-test anything yet (I'm fairly sure that
removing the call to `font-lock-set-defaults' kept the whitespace
font-lock rules in-place), but if you are seeing issues with
whitespace-mode being turned on then it is probably because the value of
`whitespace-enable-predicate' has not been modified.

Because of the default predicate value, whitespace-mode does not apply
to any buffer where the name begins with an asterisk (with the exception
of the scratch buffer), and the message buffer is usually named
something like "*unsent mail*".  That is why the example to recreate the
problem needed a change to the predicate value:

  (add-function :before-until whitespace-enable-predicate
                (lambda () (eq major-mode 'message-mode)))

This might look a bit like I've hacked my way into creating the problem
that I'm reporting, but this is actually what the docstring for the
value instructs you to do to change the behaviour, and I don't think any
of the default restrictions are there to avoid font-lock problems.

-- 
Morgan Willcock