=== modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-10-04 12:56:14 +0000 +++ lisp/ChangeLog 2012-10-05 09:40:16 +0000 @@ -1,3 +1,10 @@ +2012-10-05 Martin Rudalics + + * window.el (switch-to-buffer-preserve-window-point): New + option. + (switch-to-buffer): Optionally preserve window point if buffer + appeared earlier in the selected window (Bug#4041). + 2012-10-04 Martin Rudalics * emacs-lisp/edebug.el (edebug-pop-to-buffer): Select window === modified file 'lisp/window.el' --- lisp/window.el 2012-09-30 10:44:43 +0000 +++ lisp/window.el 2012-10-05 09:47:10 +0000 @@ -5812,6 +5812,25 @@ buffer)) (other-buffer))) +(defcustom switch-to-buffer-preserve-window-point nil + "If non-nil, `switch-to-buffer' tries to preserve `window-point'. +If this is nil, `switch-to-buffer' displays the buffer at that +buffer's `point'. If this is `already-displayed', it tries to +display the buffer at its last position in the selected window +provided the buffer is curently displayed in some other window on +a visible or iconified frame. If this is t, it always tries to +display the buffer at its last position in the selected window. + +If the window used for display is either new, or the buffer +already appears in it, or the buffer never appeared in that +window, the setting of this variable has no impact." + :type '(choice + (const :tag "Never" nil) + (const :tag "If already displayed elsewhere" already-displayed) + (const :tag "Always" t)) + :group 'windows + :version "24.3") + (defun switch-to-buffer (buffer-or-name &optional norecord force-same-window) "Switch to buffer BUFFER-OR-NAME in the selected window. If the selected window cannot display the specified @@ -5837,6 +5856,10 @@ must be displayed in the selected window; if that is impossible, signal an error rather than calling `pop-to-buffer'. +The option `switch-to-buffer-preserve-window-point' can be used +to make the buffer appear at its last position in the selected +window. + Return the buffer switched to." (interactive (list (read-buffer-to-switch "Switch to buffer: ") nil 'force-same-window)) @@ -5853,7 +5876,21 @@ (if force-same-window (user-error "Cannot switch buffers in a dedicated window") (pop-to-buffer buffer norecord))) - (t (set-window-buffer nil buffer))) + (t + (let* ((entry (assq buffer (window-prev-buffers))) + (displayed (and (eq switch-to-buffer-preserve-window-point + 'already-displayed) + (get-buffer-window buffer 0))) + (start (and entry (nth 1 entry))) + (pos (and entry (nth 2 entry)))) + (set-window-buffer nil buffer) + (when (and entry + (or (eq switch-to-buffer-preserve-window-point t) + displayed)) + ;; Try to restore start and point of buffer in the selected + ;; window (Bug#4041). + (set-window-start (selected-window) start t) + (set-window-point nil pos))))) (unless norecord (select-window (selected-window)))