+\f;;;; Restoring configurations
+
+;; Works almost as `set-window-configuration',
+;; but doesn't change the contents or the size of the minibuffer.
+(defun winner-set-conf (winconf)
+ (let ((miniwin (minibuffer-window))
+ (minisel (window-minibuffer-p (selected-window))))
+ (let ((minibuf (window-buffer miniwin))
+ (minipoint (window-point miniwin))
+ (minisize (window-height miniwin)))
+ (set-window-configuration winconf)
+ (setf (window-buffer miniwin) minibuf
+ (window-point miniwin) minipoint)
+ (when (/= minisize (window-height miniwin))
+ (letf (((selected-window) miniwin) )
+ ;; Clumsy due to cl-macs-limitation
+ (setf (window-height) minisize)))
+ (cond
+ (minisel (select-window miniwin))
+ ((window-minibuffer-p (selected-window))
+ (other-window 1))))))
+
+
+(defvar winner-point-alist nil)
+;; `set-window-configuration' restores old points and marks. This is
+;; not what we want, so we make a list of the "real" (i.e. new) points
+;; and marks before undoing window configurations.
+;;
+;; Format of entries: (buffer (mark . mark-active) (window . point) ..)
+
+(defun winner-make-point-alist ()
+ (letf (((current-buffer)))
+ (loop with alist
+ with entry
+ for win being the windows
+ do (cond
+ ((window-minibuffer-p win))
+ ((setq entry (assq win alist))
+ ;; Update existing entry
+ (push (cons win (window-point win))
+ (cddr entry)))
+ (t;; Else create new entry
+ (push (list (set-buffer (window-buffer win))
+ (cons (mark t) (winner-active-region))
+ (cons win (window-point win)))
+ alist)))
+ finally return alist)))
+
+
+(defun winner-get-point (buf win)
+ ;; Consult (and possibly extend) `winner-point-alist'.
+ (when (buffer-name buf)
+ (let ((entry (assq buf winner-point-alist)))
+ (cond
+ (entry
+ (or (cdr (assq win (cddr entry)))
+ (cdr (assq nil (cddr entry)))
+ (letf (((current-buffer) buf))
+ (push (cons nil (point)) (cddr entry))
+ (point))))
+ (t (letf (((current-buffer) buf))
+ (push (list buf
+ (cons (mark t) (winner-active-region))
+ (cons nil (point)))
+ winner-point-alist)
+ (point)))))))
+
+\f;; Make sure point doesn't end up in the minibuffer and