Subject: bug#79412: 30.2; `define-globalized-minor-mode' does not respect `:variable'

From: [email-masked]
Date: Thu, 11 Sep 2025 23:29:18 +0800

Eli Zaretskii <[email-masked]> writes:

> What this means is that using :variable leaves the mode variable, in
> this case bidi-display-reordering-mode, undefined.  Therefore, I think
> you must define some non-trivial BODY for your minor mode, because the
> default body will try to reference bidi-display-reordering-mode, and
> will fail, as this backtrace shows:

Did you mean to add back the variable `bidi-display-reordering-mode'
like this? It does eliminate the bug for now:

(define-minor-mode bidi-display-reordering-mode
  nil
  :variable bidi-display-reordering
  (setq-local bidi-display-reordering-mode bidi-display-reordering))

Actually my intention is to "mode-ify" those plain buffer-local
variables such that they can be easily toggled on and off (either on a
per-buffer basis or globally). I had tried utilizing `define-minor-mode'
and `define-globalized-minor-mode' without appealing to `:variable', but
as my code got complicated I doubted whether I was on the right track.

(defvar-local binding-bidi-display-reordering nil)

(define-minor-mode bidi-display-reordering-mode
  nil
  :ignored ignored
  (if (not binding-bidi-display-reordering)
    (dlet ((binding-bidi-display-reordering t))
      (setq bidi-display-reordering bidi-display-reordering-mode))))

(add-variable-watcher 'bidi-display-reordering
  (lambda (sym val op buf)
    (if (not (null buf))
      (with-current-buffer buf
        (if (not binding-bidi-display-reordering)
          (dlet ((binding-bidi-display-reordering t))
            (bidi-display-reordering-mode (if val 1 0))))))))

(define-globalized-minor-mode global-bidi-display-reordering-mode
  bidi-display-reordering-mode
  (lambda () (bidi-display-reordering-mode 1)))

(setq-default bidi-display-reordering nil)

(global-bidi-display-reordering-mode 1)

(keymap-global-set "C-c b" 'global-bidi-display-reordering-mode)

Or should I stop playing with modes and just `set-all' everything?

(defun set-all (variable value)
  (set-default variable value)
  (dolist (buffer (buffer-list))
    (with-current-buffer buffer
      (if (local-variable-p variable)
        (set variable value)))))

Any thoughts are appreciated!