Subject: bug#76248: [Feature Request] user-option for killing buffer in `quit-window'.

From: martin rudalics <[email-masked]>
Date: Sat, 15 Feb 2025 11:35:32 +0100

> Shouldn't it be something like this?
 >
 > +  :type '(choice (repeat (symbol :tag "Major mode")) boolean)
 > +  :version "31.1"
 > +  :group 'windows)
 >
 > Otherwise it would give a warning due type.

Right.

 >> +  (let (kill-from-mode)
 >> +    (with-current-buffer (window-buffer (window-normalize-window window))
 >> +      ;; Run the hook from the buffer implied to get any buffer-local
 >> +      ;; values.
 >> +      (run-hooks 'quit-window-hook)
 >> +
 >> +      (setq kill-from-mode
 >> +	    (or (eq quit-window-kill-buffer-modes t)
 >> +		(and (listp quit-window-kill-buffer-modes)
 >> +		     (derived-mode-p quit-window-kill-buffer-modes)))))
 >
 > Wouldn't it be more convenient to put this into the let varlist?

It would be more convenient ...

 > +  (let ((kill-from-mode
 > +         (or (eq quit-window-kill-buffer-modes t)
 > +		      (and (listp quit-window-kill-buffer-modes)
 > +		           (derived-mode-p quit-window-kill-buffer-modes)))))
 >
 >
 > ... or is there something i'm missing?

... but 'derived-mode-p' says to

  "Return non-nil if the current major mode is derived from one of MODES.

so I have to make the buffer current first via 'with-current-buffer' and
only then I can call 'derived-mode-p'.

martin

diff --git a/lisp/window.el b/lisp/window.el
index 290b5cae64d..e655e0431d4 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -5446,6 +5446,19 @@ quit-restore-window
      ((eq bury-or-kill 'bury)
       (bury-buffer-internal buffer)))))
 
+(defcustom quit-window-kill-buffer-modes nil
+  "Non-nil means `quit-window' may try to kill WINDOW's buffer.
+If this is t, `quit-window' will also try to kill WINDOW's buffer.
+Otherwise, this should be a list of major modes.  `quit-window' will
+kill the buffer of its WINDOW argument when that buffer's major mode is
+either a member of this list or is derived from a member of this list.
+In either case it will kill the buffer regardless of the value of the
+KILL argument."
+  :type '(choice (const :tag "All major modes" t)
+		 (repeat (symbol :tag "Major mode")))
+  :version "31.1"
+  :group 'windows)
+
 (defun quit-window (&optional kill window)
   "Quit WINDOW and bury its buffer.
 WINDOW must be a live window and defaults to the selected one.
@@ -5459,11 +5472,19 @@ quit-window
 The functions in `quit-window-hook' will be run before doing
 anything else."
   (interactive "P")
-  ;; Run the hook from the buffer implied to get any buffer-local
-  ;; values.
-  (with-current-buffer (window-buffer (window-normalize-window window))
-    (run-hooks 'quit-window-hook))
-  (quit-restore-window window (if kill 'kill 'bury)))
+  (let (kill-from-mode)
+    (with-current-buffer (window-buffer (window-normalize-window window))
+      ;; Run the hook from the buffer implied to get any buffer-local
+      ;; values.
+      (run-hooks 'quit-window-hook)
+
+      (setq kill-from-mode
+	    (or (eq quit-window-kill-buffer-modes t)
+		(and (listp quit-window-kill-buffer-modes)
+		     (derived-mode-p quit-window-kill-buffer-modes)))))
+
+    (quit-restore-window
+     window (if (or kill kill-from-mode) 'kill 'bury))))
 
 (defun quit-windows-on (&optional buffer-or-name kill frame)
   "Quit all windows showing BUFFER-OR-NAME.