(define-globalized-minor-mode): Require the use of run-mode-hooks
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.
This commit is contained in:
parent
3f7e26e2be
commit
17e26cf57e
3 changed files with 20 additions and 63 deletions
|
@ -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
|
||||
|
|
8
etc/NEWS
8
etc/NEWS
|
@ -1680,6 +1680,14 @@ documentation and examples.
|
|||
|
||||
* 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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue