[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#23621: PATCH (25.1.50; Buffer in >1 window; winner-undo recover wind
From: |
Tino Calancha |
Subject: |
bug#23621: PATCH (25.1.50; Buffer in >1 window; winner-undo recover window point) |
Date: |
Fri, 27 May 2016 01:40:47 +0900 (JST) |
User-agent: |
Alpine 2.20 (LRH 67 2015-01-07) |
Allow users editing same buffer in diferent windows to restore
the window point with `winner-undo'.
This report is related with Bug#4041: the behaviour of
`winner-undo' just change if an user has set the option
`switch-to-buffer-preserve-window-point' non-nil.
Following patch restore the buffer point from deleted windows in the
2 previous examples (if `switch-to-buffer-preserve-window-point' evaluates
non-nil).
From 37c088a3cc0ae303dda570e4d93195131f6a9892 Mon Sep 17 00:00:00 2001
From: Tino Calancha <f92capac@gmail.com>
Date: Fri, 27 May 2016 01:27:18 +0900
Subject: [PATCH] Editing same buffer in >1 window; winner-undo enhancement
Allow winner-undo to restore the buffer point from deleted
windows (Bug#23621).
* 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'.
---
lisp/window.el | 39 +++++++++++++++++++++++++++++++++++++++
lisp/winner.el | 13 +++++++++++--
2 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/lisp/window.el b/lisp/window.el
index bd5275b..7a7f9ac 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -3775,6 +3775,41 @@ window--in-subtree-p
(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.
@@ -3793,6 +3828,8 @@ delete-window
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 window))
(setq window (window-normalize-window window))
(let* ((frame (window-frame window))
(function (window-parameter window 'delete-window))
@@ -3875,6 +3912,8 @@ delete-other-windows
on the frame. Side windows are not deleted. If WINDOW is a side
window signal an error."
(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-other-windows))
diff --git a/lisp/winner.el b/lisp/winner.el
index 9a6f5d5..2a213ab 100644
--- a/lisp/winner.el
+++ b/lisp/winner.el
@@ -297,8 +297,17 @@ winner-set
;; 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
--
2.8.1