]> git.eshelyaron.com Git - emacs.git/commitdiff
Make winner restore point in all windows that display a buffer
authorTino Calancha <f92capac@gmail.com>
Tue, 25 Jun 2019 13:42:17 +0000 (15:42 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Tue, 25 Jun 2019 13:42:17 +0000 (15:42 +0200)
* lisp/window.el (window--before-delete-windows): New defun.
(delete-window, delete-other-windows): Use it.
* lisp/winner.el (winner-set): Use marker in 'window-prev-buffers'
when available and different than the value returned by
'winner-get-point' (bug#23621).

lisp/window.el
lisp/winner.el

index a2335a6798c93c0933218651ddd69eb536c8285b..726d022dfe99c8e86c55a6da1edbcc72912af4fa 100644 (file)
@@ -3706,6 +3706,8 @@ WINDOW must be a valid window and defaults to the selected one.
 If the option `window-resize-pixelwise' is non-nil minimize
 WINDOW pixelwise."
   (interactive)
+  (when switch-to-buffer-preserve-window-point
+    (window--before-delete-windows window))
   (setq window (window-normalize-window window))
   (window-resize
    window
@@ -4043,6 +4045,41 @@ frame can be safely deleted."
                (throw 'done t)
              (setq parent (window-parent parent))))))))
 
+;; This function is called by `delete-window' and
+;; `delete-other-windows' when `switch-to-buffer-preserve-window-point'
+;; evaluates non-nil: it allows `winner-undo' to restore the
+;; buffer point from deleted windows (Bug#23621).
+(defun window--before-delete-windows (&optional window)
+  "Update `window-prev-buffers' before delete a window.
+Optional arg WINDOW, if non-nil, update WINDOW-START and POS
+in `window-prev-buffers' for all windows displaying same
+buffer as WINDOW.  Otherwise, update `window-prev-buffers' for
+all windows.
+
+The new values for WINDOW-START and POS are those
+returned by `window-start' and `window-point' respectively.
+
+This function is called only if `switch-to-buffer-preserve-window-point'
+evaluates non-nil."
+  (dolist (win (window-list))
+    (let* ((buf   (window-buffer (or window win)))
+           (start (window-start win))
+           (pos   (window-point win))
+           (entry (assq buf (window-prev-buffers win))))
+      (cond (entry
+             (let ((marker (nth 2 entry)))
+               (unless (= pos marker)
+                 (set-marker (nth 1 entry) start buf)
+                 (set-marker marker pos buf))))
+            (t
+             (let ((prev-buf (window-prev-buffers win))
+                   (start-m  (make-marker))
+                   (pos-m    (make-marker)))
+               (set-marker start-m start buf)
+               (set-marker pos-m pos buf)
+               (push (list buf start-m pos-m) prev-buf)
+               (set-window-prev-buffers win prev-buf)))))))
+
 (defun delete-window (&optional window)
   "Delete WINDOW.
 WINDOW must be a valid window and defaults to the selected one.
@@ -4061,6 +4098,8 @@ argument.  Signal an error if WINDOW is either the only window on
 its frame, the last non-side window, or part of an atomic window
 that is its frame's root window."
   (interactive)
+  (when switch-to-buffer-preserve-window-point
+    (window--before-delete-windows))
   (setq window (window-normalize-window window))
   (let* ((frame (window-frame window))
         (function (window-parameter window 'delete-window))
index 7a5f0df0b70dfab51fce606b45fe98507d1e5272..cee98b98e505ec74d99bcbc37089f2ff7215d5e2 100644 (file)
@@ -297,8 +297,17 @@ You may want to include buffer names such as *Help*, *Apropos*,
       ;; Restore points
       (dolist (win (winner-sorted-window-list))
         (unless (and (pop alive)
-                     (setf (window-point win)
-                           (winner-get-point (window-buffer win) win))
+                     (let* ((buf   (window-buffer win))
+                            (pos   (winner-get-point (window-buffer win) win))
+                            (entry (assq buf (window-prev-buffers win))))
+                       ;; Try to restore point of buffer in the selected
+                       ;; window (Bug#23621).
+                       (let ((marker (nth 2 entry)))
+                         (when (and switch-to-buffer-preserve-window-point
+                                    marker
+                                    (not (= marker pos)))
+                           (setq pos marker))
+                         (setf (window-point win) pos)))
                      (not (member (buffer-name (window-buffer win))
                                   winner-boring-buffers)))
           (push win xwins)))            ; delete this window