emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 9506b9392e8: (define-globalized-minor-mode): Fix bug#69431


From: Stefan Monnier
Subject: master 9506b9392e8: (define-globalized-minor-mode): Fix bug#69431
Date: Mon, 8 Apr 2024 08:19:21 -0400 (EDT)

branch: master
commit 9506b9392e8c3548b769d9951a1c9d4abad9ee21
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    (define-globalized-minor-mode): Fix bug#69431
    
    * lisp/emacs-lisp/easy-mmode.el (define-globalized-minor-mode):
    When `after-change-major-mode-hook` runs, enable the mode only
    in the current buffer and not in other pending buffers.
---
 lisp/emacs-lisp/easy-mmode.el | 47 +++++++++++++++++++++++++++++++++----------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index 4fa05008dd8..095bd5faa03 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -493,6 +493,8 @@ on if the hook has explicitly disabled it.
         (extra-keywords nil)
          (MODE-variable mode)
         (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
@@ -559,10 +561,10 @@ Disable the mode if ARG is a negative number.\n\n"
         (if ,global-mode
             (progn
               (add-hook 'after-change-major-mode-hook
-                        #',MODE-enable-in-buffers)
+                        #',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-buffers)
+          (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))
 
@@ -609,6 +611,36 @@ list."
        ;; List of buffers left to process.
        (defvar ,MODE-buffers nil)
 
+       ;; The function that calls TURN-ON in the current buffer.
+       (defun ,MODE-enable-in-buffer ()
+         ;; Remove ourselves from the list of pending buffers.
+         (setq ,MODE-buffers (delq (current-buffer) ,MODE-buffers))
+         (unless ,MODE-set-explicitly
+           (unless (eq ,MODE-major-mode major-mode)
+             (if ,MODE-variable
+                 (progn
+                   (,mode -1)
+                   (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))
@@ -618,15 +650,8 @@ list."
            (setq ,MODE-buffers nil)
            (dolist (buf buffers)
              (when (buffer-live-p buf)
-               (with-current-buffer buf
-                 (unless ,MODE-set-explicitly
-                   (unless (eq ,MODE-major-mode major-mode)
-                     (if ,MODE-variable
-                         (progn
-                           (,mode -1)
-                           (funcall ,turn-on-function))
-                       (funcall ,turn-on-function))))
-                 (setq ,MODE-major-mode major-mode))))))
+              (with-current-buffer buf
+                (,MODE-enable-in-buffer))))))
        (put ',MODE-enable-in-buffers 'definition-name ',global-mode)
 
        (defun ,MODE-check-buffers ()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]