From 171c7fd6df861ab71f6cc8faedb8ff68bfac4bae Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Tue, 14 Oct 2025 11:21:29 -0400 Subject: [PATCH] (define-minor-mode): Update `global-minor-modes` if init-value is non-nil When a global minor mode is enabled by init-value rather than by calling the major mode function, we failed to register it in `global-minor-modes` (bug#79518). * lisp/emacs-lisp/easy-mmode.el (define-minor-mode): Register ourselves in `global-minor-modes` at top-level for global modes with a non-nil init-value. Also in the `modefun`, simply the code with `not` and `add-to-list` and consolidate the local/global paths to update `*-minor-modes`. * lisp/simple.el (global-minor-modes): Move to... * lisp/subr.el (global-minor-modes): ...here so it's defined early enough for `auto-compression-mode` to register itself. --- lisp/emacs-lisp/easy-mmode.el | 53 ++++++++++++++++------------------- lisp/simple.el | 4 --- lisp/subr.el | 4 +++ 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 25e4f882295..0aa1fe2ce9d 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -332,12 +332,16 @@ for a description of this minor mode." Setting this variable directly does not take effect; either customize it (see the info node `Easy Customization') or call the function `%s'.")))) - `(defcustom ,mode ,init-value - ,(format base-doc-string pretty-name mode mode) - ,@set - ,@initialize - ,@type - ,@(nreverse extra-keywords))))) + `(progn + (defcustom ,mode ,init-value + ,(format base-doc-string pretty-name mode mode) + ,@set + ,@initialize + ,@type + ,@(nreverse extra-keywords)) + ,(when init-value + `(when (bound-and-true-p ,mode) + (add-to-list 'global-minor-modes ',modefun))))))) ;; The actual function. ,(funcall @@ -360,30 +364,21 @@ or call the function `%s'.")))) 'toggle))))) (let ((,last-message (current-message))) (,@setter - (cond ((eq arg 'toggle) - (not ,getter)) - ((and (numberp arg) - (< arg 1)) - nil) - (t - t))) + (cond ((eq arg 'toggle) (not ,getter)) + (t (not (and (numberp arg) (< arg 1)))))) ;; Keep minor modes list up to date. - ,@(if globalp - ;; When running this byte-compiled code in earlier - ;; Emacs versions, these variables may not be defined - ;; there. So check defensively, even if they're - ;; always defined in Emacs 28 and up. - `((when (boundp 'global-minor-modes) - (setq global-minor-modes - (delq ',modefun global-minor-modes)) - (when ,getter - (push ',modefun global-minor-modes)))) - ;; Ditto check. - `((when (boundp 'local-minor-modes) - (setq local-minor-modes - (delq ',modefun local-minor-modes)) - (when ,getter - (push ',modefun local-minor-modes))))) + ,(let ((minor-modes-var (if globalp + 'global-minor-modes + 'local-minor-modes))) + ;; When running this byte-compiled code in earlier + ;; Emacs versions, these variables may not be defined + ;; there. So check defensively, even if they're + ;; always defined in Emacs 28 and up. + `(when (boundp ',minor-modes-var) + (if ,getter + (add-to-list ',minor-modes-var ',modefun) + (setq ,minor-modes-var + (delq ',modefun ,minor-modes-var))))) ,@body ;; The on/off hooks are here for backward compatibility only. (run-hooks ',hook (if ,getter ',hook-on ',hook-off)) diff --git a/lisp/simple.el b/lisp/simple.el index 824f7c5a1a0..589b136a008 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -157,10 +157,6 @@ messages are highlighted; this helps to see what messages were visited." nil "Overlay highlighting the current error message in the `next-error' buffer.") -(defvar global-minor-modes nil - "A list of the currently enabled global minor modes. -This is a list of symbols.") - (defcustom next-error-hook nil "List of hook functions run by `next-error' after visiting source file." :type 'hook diff --git a/lisp/subr.el b/lisp/subr.el index 9f1680f3896..891663f7640 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3064,6 +3064,10 @@ though trying to avoid AVOIDED-MODES." hs-minor-mode) "List of all minor mode functions.") +(defvar global-minor-modes nil + "A list of the currently enabled global minor modes. +This is a list of symbols.") + (defun add-minor-mode (toggle name &optional keymap after toggle-fun) "Register a new minor mode.