Subject: bug#56637: 28.1.90; [FR] Allow a way around font-lock-mode being unconditionally disabled in " *hidden*" buffers

From: Stefan Monnier <[email-masked]>
Date: Wed, 20 Jul 2022 11:15:20 -0400

>>    (defun really-turn-on-font-lock ()
>>      (unwind-protect
>>          (let ((noninteractive nil))
>>            (rename-buffer (concat "\0" (buffer-name)))
>>            (font-lock-mode 1))
>>        (when (eq ?\0 (aref (buffer-name) 0))
>>          (rename-buffer (substring (buffer-name) 1)))))
>> 
>> But I can't see why we shouldn't accommodate those needs more directly.
>
> I can: we don't need, and really shouldn't, attempt to cater to each
> corner use case in core.  Doing that (and we've been doing that for
> quite some time) makes Emacs a larger and less maintainable monster
> than it needs to be or already is.

I can't see why adding the patch below would make it less maintainable.
It sure seems much cleaner than the horror quoted above (which suffers
from all kinds of corner case misbehaviors).

> You already have one symptom of the monster's size: I already cannot
> tell which hooks are and aren't running in temporary buffers without
> consulting the sources.  Way to go, Emacs!

And for that reason, I think we should try and avoid such special cases
(such the special case of not enabling font-lock in temp buffers), by
replacing them with other measures which give similar results but
without such special casing.

Regarding `inhibit-buffer-hooks`, I wonder if we shouldn't instead
change `with-temp-buffer` so it sets `kill-buffer-hook` (and the other
2 hooks) buffer-locally to nil.
This way, we get pretty much the same end result (in terms of
performance benefits when there are many buffers) yet the hooks get run
normally.

>> >> If you don't like `font-lock-allow-in-temporary-buffer`, we could have
>> >> a new function `font-lock-enable-unconditionally` which does the same as
>> >> `font-lock-mode` but skips the (or noninteractive (eq (aref
>> >> (buffer-name) 0) ?\s)) test.
>> > Ouch!
>> I don't understand this reaction.
> See above.

"Ouch" to me implies something like an ugly code or the introduction of
something that breaks an abstraction or some such.  Having to write the
above quote would qualify, whereas the patch below doesn't seem
to qualify.

        Stefan

diff --git a/lisp/font-core.el b/lisp/font-core.el
index f92d1e38306..dc6aac98828 100644
--- a/lisp/font-core.el
+++ b/lisp/font-core.el
@@ -133,6 +133,12 @@ font-lock-mode
   ;; batch job) or if the buffer is invisible (the name starts with a space).
   (when (or noninteractive (eq (aref (buffer-name) 0) ?\s))
     (setq font-lock-mode nil))
+  (font-lock-mode-unconditionally (not font-lock-mode)))
+
+(defun font-lock-mode-unconditionally (&optional disable)
+  "Enable font-lock unconditionally.
+If DISABLE is non-nil, then disable unconditionally."
+  (setq font-lock-mode (not disable)
   (funcall font-lock-function font-lock-mode)
   ;; Arrange to unfontify this buffer if we change major mode later.
   (if font-lock-mode