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
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
(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")))
;; 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))
(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