Package: emacs;
Reported by: inet0 <at> qq.com
Date: Tue, 9 Sep 2025 02:01:03 UTC
Severity: normal
Found in version 30.2
Done: Eli Zaretskii <eliz <at> gnu.org>
View this message in rfc822 format
From: help-debbugs <at> gnu.org (GNU bug Tracking System) To: inet0 <at> qq.com Subject: bug#79412: closed (Re: bug#79412: 30.2; `define-globalized-minor-mode' does not respect `:variable') Date: Sat, 13 Sep 2025 19:25:02 +0000
[Message part 1 (text/plain, inline)]
Your bug report #79412: 30.2; `define-globalized-minor-mode' does not respect `:variable' which was filed against the emacs package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 79412 <at> debbugs.gnu.org. -- 79412: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=79412 GNU Bug Tracking System Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
From: Eli Zaretskii <eliz <at> gnu.org> To: Stefan Monnier <monnier <at> iro.umontreal.ca> Cc: inet0 <at> qq.com, 79412-done <at> debbugs.gnu.org Subject: Re: bug#79412: 30.2; `define-globalized-minor-mode' does not respect `:variable' Date: Sat, 13 Sep 2025 22:24:25 +0300> From: Stefan Monnier <monnier <at> iro.umontreal.ca> > Cc: inet0 <at> qq.com, 79412 <at> debbugs.gnu.org > Date: Sat, 13 Sep 2025 13:50:25 -0400 > > >> > So you mean this: > >> > > >> > diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el > >> > index ca92130..de77eb3 100644 > >> > --- a/lisp/emacs-lisp/easy-mmode.el > >> > +++ b/lisp/emacs-lisp/easy-mmode.el > >> > @@ -570,7 +570,7 @@ define-globalized-minor-mode > >> > (dolist (buf (buffer-list)) > >> > (with-current-buffer buf > >> > (if ,global-mode (funcall ,turn-on-function) > >> > - (when ,mode (,mode -1))))) > >> > + (when ,mode (,MODE-variable -1))))) > >> > ,@body) > >> > > >> > ,(when predicate > >> > >> No, like > >> > >> (when ,MODE-variable (,mode -1)) > > > > And what about this one: > > > > ;; Go through existing buffers. > > (dolist (buf (buffer-list)) > > (with-current-buffer buf > > (if ,global-mode (funcall ,turn-on-function) > > (when ,mode (,MODE-variable -1))))) > > ,@body) > > Hmm... actually this is the same as the one further above. > AFAICT there's only one such piece of code in `easy-mmode.el`. Thanks, I hope I've fixed this now.
[Message part 3 (message/rfc822, inline)]
From: inet0 <at> qq.com To: bug-gnu-emacs <at> gnu.org Subject: 30.2; `define-globalized-minor-mode' does not respect `:variable' Date: Tue, 09 Sep 2025 03:40:36 +0800Hi there, I am using Emacs as a GUI application on Android (distributed by F-Droid if that matters) so `emacs -Q' is not an option, but the symptoms should be reproduced by (1) evaluating the program segments below, then (2) typing `C-c b' twice. (define-minor-mode bidi-display-reordering-mode nil :variable bidi-display-reordering) (define-globalized-minor-mode global-bidi-display-reordering-mode bidi-display-reordering-mode (lambda () (bidi-display-reordering-mode 1)) :variable bidi-display-reordering) (keymap-global-set "C-c b" 'global-bidi-display-reordering-mode) Buffer *Messages*: Loading gnus...done For information about GNU Emacs and the GNU system, type C-h C-a. Global Bidi-Display-Reordering mode enabled if: Symbol’s value as variable is void: bidi-display-reordering-mode Buffer *Backtrace*: Debugger entered--Lisp error: (void-variable bidi-display-reordering-mode) (if bidi-display-reordering-mode (progn (bidi-display-reordering-mode -1))) (if global-bidi-display-reordering-mode (bidi-display-reordering-mode 1) (if bidi-display-reordering-mode (progn (bidi-display-reordering-mode -1)))) (save-current-buffer (set-buffer buf) (if global-bidi-display-reordering-mode (bidi-display-reordering-mode 1) (if bidi-display-reordering-mode (progn (bidi-display-reordering-mode -1))))) (let ((buf (car tail))) (save-current-buffer (set-buffer buf) (if global-bidi-display-reordering-mode (bidi-display-reordering-mode 1) (if bidi-display-reordering-mode (progn (bidi-display-reordering-mode -1))))) (setq tail (cdr tail))) (while tail (let ((buf (car tail))) (save-current-buffer (set-buffer buf) (if global-bidi-display-reordering-mode (bidi-display-reordering-mode 1) (if bidi-display-reordering-mode (progn (bidi-display-reordering-mode -1))))) (setq tail (cdr tail)))) (let ((tail (buffer-list))) (while tail (let ((buf (car tail))) (save-current-buffer (set-buffer buf) (if global-bidi-display-reordering-mode (bidi-display-reordering-mode 1) (if bidi-display-reordering-mode (progn (bidi-display-reordering-mode -1))))) (setq tail (cdr tail))))) (let ((last-message (current-message))) (progn (set-default 'global-bidi-display-reordering-mode (cond ((eq arg 'toggle) (not (default-value 'global-bidi-display-reordering-mode))) ((and (numberp arg) (< arg 1)) nil) (t t)))) (if (boundp 'global-minor-modes) (progn (setq global-minor-modes (delq 'global-bidi-display-reordering-mode global-minor-modes)) (if (default-value 'global-bidi-display-reordering-mode) (progn (setq global-minor-modes (cons 'global-bidi-display-reordering-mode global-minor-modes)))))) (if global-bidi-display-reordering-mode (add-hook 'after-change-major-mode-hook #'global-bidi-display-reordering-mode-enable-in-buffer) (remove-hook 'after-change-major-mode-hook #'global-bidi-display-reordering-mode-enable-in-buffer)) (let ((tail (buffer-list))) (while tail (let ((buf (car tail))) (save-current-buffer (set-buffer buf) (if global-bidi-display-reordering-mode (bidi-display-reordering-mode 1) (if bidi-display-reordering-mode (progn (bidi-display-reordering-mode -1))))) (setq tail (cdr tail))))) (run-hooks 'global-bidi-display-reordering-mode-hook (if (default-value 'global-bidi-display-reordering-mode) 'global-bidi-display-reordering-mode-on-hook 'global-bidi-display-reordering-mode-off-hook)) (if (called-interactively-p 'any) (progn (customize-mark-as-set 'global-bidi-display-reordering-mode) (if (and (current-message) (not (equal last-message (current-message)))) nil (let ((local "")) (message "%s %sabled%s" "Global Bidi-Display-Reordering mode" (if (default-value 'global-bidi-display-reordering-mode) "en" "dis") local)))))) global-bidi-display-reordering-mode(toggle) funcall-interactively(global-bidi-display-reordering-mode toggle) call-interactively(global-bidi-display-reordering-mode nil nil) command-execute(global-bidi-display-reordering-mode) One would expect a line `Global Glyphless-Display mode disabled' in buffer *Messages*, but Emacs only complains about the variable `bidi-display-reordering-mode' being void, and the corresponding buffer-local mode is not disabled either. After searching on the Internet and on the GNU Bug Tracker, I came across this related bug report: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=29081 Notice the use of keyword `:variable' in the form `define-globalized-minor-mode' whose paired value, according to info node `(elisp)Defining Minor Modes', should match that of the same keyword in the corresponding form `define-minor-mode'. With that in mind, I suspect that the buffer-local mode name is mistakenly referenced instead of the name specified by keyword `:variable', thus causing a void-variable error. I have found something suspicious at source code `lisp/emacs-lisp/easy-mmode.el:569:23': ;; Go through existing buffers. (dolist (buf (buffer-list)) (with-current-buffer buf (if ,global-mode (funcall ,turn-on-function) (when ,mode (,mode -1))))) It seems that `mode' at the predicate position of `when' should really be `MODE-variable'! As an aside, the docstring of `define-globalized-minor-mode' is a bit off the description in the ELisp manual. (Jumping between `C-h f' and `C-h i m el i' is annoying, isn't it?) The manual says: By default, the buffer-local minor mode variable that says whether the mode is switched on or off is the same as the name of the mode itself. Use ‘:variable VARIABLE’ if that’s not the case–some minor modes use a different variable to store this state information. While in docstring: Other keywords have the same meaning as in ‘define-minor-mode’, which see. Clearly, `:variable' in `define-globalized-minor-mode' does not have the same meaning as in `define-minor-mode', otherwise you would be specifying the mode variable of the global mode, which is not the case. In GNU Emacs 30.2 (build 1, aarch64-unknown-linux-android22) of 2025-08-18 built on bookworm Repository revision: 636f166cfc86aa90d63f592fd99f3fdd9ef95ebd Repository branch: HEAD Windowing system distributor 'Xiaomi', version 33.0.0 System Description: Redmi/alioth/alioth:13/TKQ1.220829.002/V14.0.8.0.TKHCNXM:user/release-keys Configured using: 'configure --with-png=yes --with-webp=yes --with-gif=yes --with-jpeg=yes --with-xml2=yes --with-sqlite3=yes --with-gnutls=yes --with-tiff=yes --with-selinux=yes --with-modules=yes --with-tree-sitter=yes --with-imagemagick=no --with-lcms2=yes --with-mailutils= --with-pop=no-by-default --with-harfbuzz=yes --with-threads=yes --with-rsvg=yes --enable-check-lisp-object-type= 'CFLAGS= -Werror=implicit-function-declaration'' Configured features: GIF GMP GNUTLS HARFBUZZ JPEG LIBSELINUX LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP THREADS TIFF TREE_SITTER WEBP ZLIB Important settings: value of $LANG: en_US.utf8 locale-coding-system: utf-8-unix Major mode: Group Minor modes in effect: cursor-sensor-mode: t gnus-undo-mode: t server-mode: t glyphless-display-mode: t global-glyphless-display-mode: t bidi-display-reordering: t tooltip-mode: t global-eldoc-mode: t show-paren-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t minibuffer-regexp-mode: t buffer-read-only: t size-indication-mode: t column-number-mode: t line-number-mode: t indent-tabs-mode: t transient-mark-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t Load-path shadows: None found. Features: (shadow sort gnus-cite mail-extr emacsbug cursor-sensor nndraft nnmh utf-7 network-stream nsm nnfolder nnnil gnus-agent gnus-srvr gnus-score score-mode nnvirtual gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime smime gnutls dig nntp gnus-cache gnus-sum shr pixel-fill kinsoku url-file svg dom gnus-group gnus-undo gnus-start gnus-dbus dbus xml gnus-cloud nnimap nnmail browse-url url url-proxy url-privacy url-expand url-methods url-history url-cookie generate-lisp-file url-domsuf url-util url-parse auth-source cl-seq eieio eieio-core json map byte-opt bytecomp byte-compile url-vars mail-source utf7 nnoo parse-time iso8601 gnus-spec gnus-int gnus-range gnus-win noutline outline server cl-macs message sendmail mailcap yank-media puny dired dired-loaddefs rfc822 mml mml-sec password-cache epa derived epg rfc6068 epg-config mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 ietf-drums mailabbrev gmm-utils mailheader gnus nnheader gnus-util text-property-search time-date subr-x mail-utils range mm-util mail-prsvr cus-edit pp cus-load icons wid-edit cl-loaddefs cl-lib disp-table glyphless-mode gv easy-mmode china-util rmc iso-transl tooltip cus-start cconv eldoc paren electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel android-win term/common-win touch-screen ls-lisp tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic indonesian philippine cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite emoji-zwj charscript charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp files window text-properties overlay sha1 md5 base64 format env code-pages mule custom widget keymap hashtable-print-readable backquote threads inotify android multi-tty move-toolbar make-network-process emacs) Memory information: ((conses 16 142708 12432) (symbols 48 15036 1) (strings 32 43127 1451) (string-bytes 1 1143115) (vectors 16 25917) (vector-slots 8 306696 18106) (floats 8 210 4) (intervals 56 578 0) (buffers 992 16))
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.