From 8305210da9e2215a8b38cd5cf88cd4c6c856fa0b Mon Sep 17 00:00:00 2001 From: Trust me I am a doctor Date: Wed, 26 May 2021 15:40:39 +0200 Subject: [PATCH] Better handling of side-windows * lisp/window.el (switch-to-prev-buffer) : Return nil when prev-buffer unavailable (switch-to-next-buffer) : Return nil when next-buffer unavailable (replace-buffer-in-windows) : Does not systematically delete side-windows, instead try to `switch-to-prev-buffer' and delete the window only if prev-buffer was unavailable (quit-restore-window) : Add exceptions for side-windows, so it try to to `switch-to-prev-buffer' and delete the window only if prev-buffer was unavailable (bug#48493) --- lisp/window.el | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/lisp/window.el b/lisp/window.el index fd1c617d6b..33f4409fcf 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -4559,11 +4559,11 @@ This function is called by `prev-buffer'." ;; Scan WINDOW's previous buffers first, skipping entries of next ;; buffers. (dolist (entry (window-prev-buffers window)) - (when (and (setq new-buffer (car entry)) + (when (and (not (eq (car entry) old-buffer)) + (setq new-buffer (car entry)) (or (buffer-live-p new-buffer) (not (setq killed-buffers (cons new-buffer killed-buffers)))) - (not (eq new-buffer old-buffer)) (or (null pred) (funcall pred new-buffer)) ;; When BURY-OR-KILL is nil, avoid switching to a ;; buffer in WINDOW's next buffers list. @@ -4726,11 +4726,11 @@ This function is called by `next-buffer'." ;; Scan WINDOW's reverted previous buffers last (must not use ;; nreverse here!) (dolist (entry (reverse (window-prev-buffers window))) - (when (and (setq new-buffer (car entry)) + (when (and (not (eq (car entry) old-buffer)) + (setq new-buffer (car entry)) (or (buffer-live-p new-buffer) (not (setq killed-buffers (cons new-buffer killed-buffers)))) - (not (eq new-buffer old-buffer)) (or (null pred) (funcall pred new-buffer))) (if (switch-to-prev-buffer-skip-p skip window new-buffer) (setq skipped (or skipped new-buffer)) @@ -4989,10 +4989,14 @@ all window-local buffer lists." (let ((buffer (window-normalize-buffer buffer-or-name))) (dolist (window (window-list-1 nil nil t)) (if (eq (window-buffer window) buffer) - (unless (window--delete window t t) - ;; Switch to another buffer in window. - (set-window-dedicated-p window nil) - (switch-to-prev-buffer window 'kill)) + (let ((dedicated-side (eq (window-dedicated-p window) 'side))) + ;; Try to delete the window, with the exception of side-windows + (when (or dedicated-side (not (window--delete window t t))) + ;; Switch to another buffer in window. + (set-window-dedicated-p window nil) + (if (switch-to-prev-buffer window 'kill) + (and dedicated-side (set-window-dedicated-p window 'side)) + (window--delete window nil 'kill)))) ;; Unrecord BUFFER in WINDOW. (unrecord-window-buffer window buffer))))) @@ -5040,6 +5044,7 @@ nil means to not handle the buffer in a particular way. This (dolist (buf (window-prev-buffers window)) (unless (eq (car buf) buffer) (throw 'prev-buffer (car buf)))))) + (dedicated (window-dedicated-p window)) quad entry) (cond ((and (not prev-buffer) @@ -5084,6 +5089,8 @@ nil means to not handle the buffer in a particular way. This ;; Restore WINDOW's previous buffer, start and point position. (set-window-buffer-start-and-point window (nth 0 quad) (nth 1 quad) (nth 2 quad)) + ;; Preserve the side-window dedication + (when (eq dedicated 'side) (set-window-dedicated-p window 'side)) ;; Deal with the buffer we just removed from WINDOW. (setq entry (and (eq bury-or-kill 'append) (assq buffer (window-prev-buffers window)))) @@ -5110,9 +5117,18 @@ nil means to not handle the buffer in a particular way. This (set-window-parameter window 'quit-restore nil) ;; Make sure that WINDOW is no more dedicated. (set-window-dedicated-p window nil) - (unless (switch-to-prev-buffer window bury-or-kill) - ;; Delete WINDOW if there is no previous buffer (Bug#48367). - (window--delete window nil (eq bury-or-kill 'kill))))) + (if (and prev-buffer (eq dedicated 'side)) + ;; If a previous buffer exists, try to switch to it and + ;; to preserve the side-window dedication. If that + ;; fails for whatever reason, try to delete the window. + (if (switch-to-prev-buffer window bury-or-kill) + (set-dedicated-window-p window 'side) + (window--delete window nil (eq bury-or-kill 'kill))) + ;; If no previous buffer exists, try to delete the window. If + ;; that fails for whatever reason, try to switch to some other + ;; buffer. + (unless (window--delete window nil (eq bury-or-kill 'kill)) + (switch-to-prev-buffer window bury-or-kill))))) ;; Deal with the buffer. (cond -- 2.20.1