]> git.eshelyaron.com Git - emacs.git/commitdiff
(define-globalized-minor-mode): Require the use of `run-mode-hooks`
authorStefan Monnier <monnier@iro.umontreal.ca>
Sat, 13 Apr 2024 14:31:28 +0000 (10:31 -0400)
committerEshel Yaron <me@eshelyaron.com>
Sun, 14 Apr 2024 17:11:27 +0000 (19:11 +0200)
When `define-globalized-minor-mode` was introduced (Emacs-22),
`run-mode-hooks` was brand new, so we could not expect all major
modes to use it and we had to rely on brittle workarounds to try
and approximate `after-change-major-mode-hook`.

These workarounds have undesirable side effects, and (we hope)
they're not needed any more now that virtually all major modes
have been changed to use `run-mode-hooks` (or
`define-derived-mode`).

* lisp/emacs-lisp/easy-mmode.el (define-globalized-minor-mode):
Rely only on `after-change-major-mode-hook`, remove the "cmhh"
[typo for the intended "cmmh", BTW] workaround.

* doc/lispref/modes.texi (Mode Hooks): Clarify the importance of
`after-change-major-mode-hook` w.r.t `define-globalized-minor-mode`.
(Defining Minor Modes): Rewrite the explanation of which buffers
are affected, including adjusting it to the fact that
`fundamental-mode` has used run `run-mode-hooks` for last 10 years.

(cherry picked from commit 17e26cf57e18c5df2172a7049591d89fc53b3fb6)

doc/lispref/modes.texi
etc/NEWS
lisp/emacs-lisp/easy-mmode.el

index b034fecd77b84d2517c056b938c0ae1d661cd37f..ffede9e86f5b8af5c1eb18da05b4df9edd6e6781 100644 (file)
@@ -1109,7 +1109,10 @@ Versions before 24 did not have @code{change-major-mode-after-body-hook}.
 When user-implemented major modes do not use @code{run-mode-hooks} and
 have not been updated to use these newer features, they won't entirely
 follow these conventions: they may run the parent's mode hook too early,
-or fail to run @code{after-change-major-mode-hook}.  If you encounter
+or fail to run @code{after-change-major-mode-hook}.  This will
+have undesirable effects such as preventing minor modes defined
+with @code{define-globalized-minor-mode} from being enabled in
+buffers using these major modes.  If you encounter
 such a major mode, please correct it to follow these conventions.
 
   When you define a major mode using @code{define-derived-mode}, it
@@ -1985,10 +1988,10 @@ turn on the minor mode in a buffer, it uses the function
 function so it could determine whether to enable the minor mode or not
 when it is not a priori clear that it should always be enabled.)
 
-Globally enabling the mode also affects buffers subsequently created
-by visiting files, and buffers that use a major mode other than
-Fundamental mode; but it does not detect the creation of a new buffer
-in Fundamental mode.
+Globally enabling the mode affects only those buffers subsequently
+created that use a major mode which follows the convention to run
+@code{run-mode-hooks}.  The minor mode will not be enabled in those
+major modes which fail to follow this convention.
 
 This macro defines the customization option @var{global-mode}
 (@pxref{Customization}), which can be toggled via the Customize
index 69dfc9643ef7e71b6faa42c41ba06e0ef47bc88a..09d47ccaafa23bbfe25e8238cf31b15e09282644 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1782,6 +1782,14 @@ documentation and examples.
 \f
 * Incompatible Lisp Changes in Emacs 30.1
 
++++
+** 'define-globalized-minor-mode' requires that modes use 'run-mode-hooks'.
+Minor modes defined with 'define-globalized-minor-mode', such as
+'global-font-lock-mode', will not be enabled any more in those buffers
+whose major modes fails to use 'run-mode-hooks'.  Major modes defined
+with 'define-derived-mode' are not affected.  `run-mode-hooks` has been the
+recommended way to run major mode hooks since Emacs-22.
+
 ---
 ** Old derived.el functions removed.
 The following functions have been deleted because they were only used
index b09466d79fc3ec3e1e188c9512a8f2dea42442ca..eaad96469854c2cde6b702eb6758ec32518f1cb2 100644 (file)
@@ -495,11 +495,6 @@ on if the hook has explicitly disabled it.
         (MODE-buffers (intern (concat global-mode-name "-buffers")))
         (MODE-enable-in-buffer
          (intern (concat global-mode-name "-enable-in-buffer")))
-        (MODE-enable-in-buffers
-         (intern (concat global-mode-name "-enable-in-buffers")))
-        (MODE-check-buffers
-         (intern (concat global-mode-name "-check-buffers")))
-        (MODE-cmhh (intern (concat global-mode-name "-cmhh")))
         (minor-MODE-hook (intern (concat mode-name "-hook")))
         (MODE-set-explicitly (intern (concat mode-name "-set-explicitly")))
         (MODE-major-mode (intern (concat (symbol-name mode) "-major-mode")))
@@ -559,14 +554,9 @@ Disable the mode if ARG is a negative number.\n\n"
 
         ;; Setup hook to handle future mode changes and new buffers.
         (if ,global-mode
-            (progn
-              (add-hook 'after-change-major-mode-hook
-                        #',MODE-enable-in-buffer)
-              (add-hook 'find-file-hook #',MODE-check-buffers)
-              (add-hook 'change-major-mode-hook #',MODE-cmhh))
-          (remove-hook 'after-change-major-mode-hook #',MODE-enable-in-buffer)
-          (remove-hook 'find-file-hook #',MODE-check-buffers)
-          (remove-hook 'change-major-mode-hook #',MODE-cmhh))
+            (add-hook 'after-change-major-mode-hook
+                      #',MODE-enable-in-buffer)
+          (remove-hook 'after-change-major-mode-hook #',MODE-enable-in-buffer))
 
         ;; Go through existing buffers.
         (dolist (buf (buffer-list))
@@ -623,51 +613,7 @@ list."
                    (funcall ,turn-on-function))
                (funcall ,turn-on-function))))
          (setq ,MODE-major-mode major-mode))
-       (put ',MODE-enable-in-buffer 'definition-name ',global-mode)
-
-       ;; In the normal case, major modes run `after-change-major-mode-hook'
-       ;; which will have called `MODE-enable-in-buffer' for us.  But some
-       ;; major modes don't use `run-mode-hooks' (customarily used via
-       ;; `define-derived-mode') and thus fail to run
-       ;; `after-change-major-mode-hook'.
-       ;; The functions below try to handle those major modes, with
-       ;; a combination of ugly hacks to try and catch those corner
-       ;; cases by listening to `change-major-mode-hook' to discover
-       ;; potential candidates and then checking in `post-command-hook'
-       ;; and `find-file-hook' if some of those still haven't run
-       ;; `after-change-major-mode-hook'.  FIXME: We should try and get
-       ;; rid of this ugly hack and rely purely on
-       ;; `after-change-major-mode-hook' because they can (and do) end
-       ;; up running `MODE-enable-in-buffer' too early (when the major
-       ;; isn't yet fully setup) in some cases (see bug#58888).
-
-       ;; The function that calls TURN-ON in each buffer.
-       (defun ,MODE-enable-in-buffers ()
-         (let ((buffers ,MODE-buffers))
-           ;; Clear MODE-buffers to avoid scanning the same list of
-           ;; buffers in recursive calls to MODE-enable-in-buffers.
-           ;; Otherwise it could lead to infinite recursion.
-           (setq ,MODE-buffers nil)
-           (dolist (buf buffers)
-             (when (buffer-live-p buf)
-              (with-current-buffer buf
-                (,MODE-enable-in-buffer))))))
-       (put ',MODE-enable-in-buffers 'definition-name ',global-mode)
-
-       (defun ,MODE-check-buffers ()
-        (,MODE-enable-in-buffers)
-        (remove-hook 'post-command-hook #',MODE-check-buffers))
-       (put ',MODE-check-buffers 'definition-name ',global-mode)
-
-       ;; The function that catches kill-all-local-variables.
-       (defun ,MODE-cmhh ()
-         ;; If `delay-mode-hooks' is set, it indicates that the current
-         ;; buffer's mode will run `run-mode-hooks' afterwards anyway,
-         ;; so we don't need to keep this buffer in MODE-buffers.
-        (unless delay-mode-hooks
-          (add-to-list ',MODE-buffers (current-buffer))
-          (add-hook 'post-command-hook #',MODE-check-buffers)))
-       (put ',MODE-cmhh 'definition-name ',global-mode))))
+       (put ',MODE-enable-in-buffer 'definition-name ',global-mode))))
 
 (defun easy-mmode--globalized-predicate-p (predicate)
   (cond