summaryrefslogtreecommitdiff
path: root/lisp/window.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/window.el')
-rw-r--r--lisp/window.el436
1 files changed, 281 insertions, 155 deletions
diff --git a/lisp/window.el b/lisp/window.el
index 4b30609681c..37d82c060c6 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -2262,14 +2262,14 @@ SIDE can be any of the symbols `left', `top', `right' or
"Return window in DIRECTION as seen from WINDOW.
More precisely, return the nearest window in direction DIRECTION
as seen from the position of `window-point' in window WINDOW.
-DIRECTION must be one of `above', `below', `left' or `right'.
+DIRECTION should be one of 'above', 'below', 'left' or 'right'.
WINDOW must be a live window and defaults to the selected one.
-Do not return a window whose `no-other-window' parameter is
-non-nil. If the nearest window's `no-other-window' parameter is
+Do not return a window whose 'no-other-window' parameter is
+non-nil. If the nearest window's 'no-other-window' parameter is
non-nil, try to find another window in the indicated direction.
If, however, the optional argument IGNORE is non-nil, return that
-window even if its `no-other-window' parameter is non-nil.
+window even if its 'no-other-window' parameter is non-nil.
Optional argument SIGN a negative number means to use the right
or bottom edge of WINDOW as reference position instead of
@@ -2278,7 +2278,7 @@ top edge of WINDOW as reference position.
Optional argument WRAP non-nil means to wrap DIRECTION around
frame borders. This means to return for WINDOW at the top of the
-frame and DIRECTION `above' the minibuffer window if the frame
+frame and DIRECTION 'above' the minibuffer window if the frame
has one, and a window at the bottom of the frame otherwise.
Optional argument MINI nil means to return the minibuffer window
@@ -2288,8 +2288,13 @@ if WRAP is non-nil, always act as if MINI were nil.
Return nil if no suitable window can be found."
(setq window (window-normalize-window window t))
- (unless (memq direction '(above below left right))
- (error "Wrong direction %s" direction))
+ (cond
+ ((eq direction 'up)
+ (setq direction 'above))
+ ((eq direction 'down)
+ (setq direction 'below))
+ ((not (memq direction '(above below left right)))
+ (error "Wrong direction %s" direction)))
(let* ((frame (window-frame window))
(hor (memq direction '(left right)))
(first (if hor
@@ -2759,7 +2764,7 @@ as small) as possible, but don't signal an error."
"Return t when a window on FRAME shall be resized vertically.
Optional argument HORIZONTAL non-nil means return t when a window
shall be resized horizontally."
-(catch 'apply
+ (catch 'apply
(walk-window-tree
(lambda (window)
(unless (= (window-new-pixel window)
@@ -3084,11 +3089,12 @@ already set by this routine."
(while (and best-window (not (zerop delta)))
(setq sub last)
(setq best-window nil)
- (setq best-value most-negative-fixnum)
+ (setq best-value nil)
(while sub
(when (and (consp (window-new-normal sub))
(not (<= (car (window-new-normal sub)) 0))
- (> (cdr (window-new-normal sub)) best-value))
+ (or (not best-value)
+ (> (cdr (window-new-normal sub)) best-value)))
(setq best-window sub)
(setq best-value (cdr (window-new-normal sub))))
@@ -3113,10 +3119,11 @@ already set by this routine."
(while (and best-window (not (zerop delta)))
(setq sub last)
(setq best-window nil)
- (setq best-value most-positive-fixnum)
+ (setq best-value nil)
(while sub
(when (and (numberp (window-new-normal sub))
- (< (window-new-normal sub) best-value))
+ (or (not best-value)
+ (< (window-new-normal sub) best-value)))
(setq best-window sub)
(setq best-value (window-new-normal sub)))
@@ -4271,7 +4278,7 @@ WINDOW must be a live window and defaults to the selected one."
(list (copy-marker start)
(copy-marker
;; Preserve window-point-insertion-type
- ;; (Bug#12588).
+ ;; (Bug#12855).
point window-point-insertion-type)))))
(set-window-prev-buffers
window (cons entry (window-prev-buffers window)))))
@@ -4910,26 +4917,29 @@ absolute value can be less than `window-min-height' or
small as one line or two columns. SIZE defaults to half of
WINDOW's size.
-Optional third argument SIDE nil (or `below') specifies that the
-new window shall be located below WINDOW. SIDE `above' means the
+Optional third argument SIDE nil (or 'below') specifies that the
+new window shall be located below WINDOW. SIDE 'above' means the
new window shall be located above WINDOW. In both cases SIZE
specifies the new number of lines for WINDOW (or the new window
if SIZE is negative) including space reserved for the mode and/or
header line.
-SIDE t (or `right') specifies that the new window shall be
-located on the right side of WINDOW. SIDE `left' means the new
+SIDE t (or 'right') specifies that the new window shall be
+located on the right side of WINDOW. SIDE 'left' means the new
window shall be located on the left of WINDOW. In both cases
SIZE specifies the new number of columns for WINDOW (or the new
window provided SIZE is negative) including space reserved for
-fringes and the scrollbar or a divider column. Any other non-nil
-value for SIDE is currently handled like t (or `right').
+fringes and the scrollbar or a divider column.
+
+For compatibility reasons, SIDE 'up' and 'down' are interpreted
+as 'above' and 'below'. Any other non-nil value for SIDE is
+currently handled like t (or 'right').
PIXELWISE, if non-nil, means to interpret SIZE pixelwise.
If the variable `ignore-window-parameters' is non-nil or the
-`split-window' parameter of WINDOW equals t, do not process any
-parameters of WINDOW. Otherwise, if the `split-window' parameter
+'split-window' parameter of WINDOW equals t, do not process any
+parameters of WINDOW. Otherwise, if the 'split-window' parameter
of WINDOW specifies a function, call that function with all three
arguments and return the value returned by that function.
@@ -4945,6 +4955,8 @@ frame. The selected window is not changed by this function."
(setq window (window-normalize-window window))
(let* ((side (cond
((not side) 'below)
+ ((eq side 'up) 'above)
+ ((eq side 'down) 'below)
((memq side '(below above right left)) side)
(t 'right)))
(horizontal (not (memq side '(below above))))
@@ -4968,10 +4980,10 @@ frame. The selected window is not changed by this function."
(catch 'done
(cond
;; Ignore window parameters if either `ignore-window-parameters'
- ;; is t or the `split-window' parameter equals t.
+ ;; is t or the 'split-window' parameter equals t.
((or ignore-window-parameters (eq function t)))
((functionp function)
- ;; The `split-window' parameter specifies the function to call.
+ ;; The 'split-window' parameter specifies the function to call.
;; If that function is `ignore', do nothing.
(throw 'done (funcall function window size side)))
;; If WINDOW is part of an atomic window, split the root window
@@ -5004,10 +5016,10 @@ frame. The selected window is not changed by this function."
(setq window-combination-limit t))
(let* ((parent-pixel-size
- ;; `parent-pixel-size' is the pixel size of WINDOW's
+ ;; 'parent-pixel-size' is the pixel size of WINDOW's
;; parent, provided it has one.
(when parent (window-size parent horizontal t)))
- ;; `resize' non-nil means we are supposed to resize other
+ ;; 'resize' non-nil means we are supposed to resize other
;; windows in WINDOW's combination.
(resize
(and window-combination-resize
@@ -5016,9 +5028,9 @@ frame. The selected window is not changed by this function."
(not (eq window-combination-limit t))
;; Resize makes sense in iso-combinations only.
(window-combined-p window horizontal)))
- ;; `old-pixel-size' is the current pixel size of WINDOW.
+ ;; 'old-pixel-size' is the current pixel size of WINDOW.
(old-pixel-size (window-size window horizontal t))
- ;; `new-size' is the specified or calculated size of the
+ ;; 'new-size' is the specified or calculated size of the
;; new window.
new-pixel-size new-parent new-normal)
(cond
@@ -5305,11 +5317,12 @@ is non-nil)."
(total-sum parent-size)
failed size sub-total sub-delta sub-amount rest)
(while sub
- (setq number-of-children (1+ number-of-children))
- (when (window-size-fixed-p sub horizontal)
- (setq total-sum
- (- total-sum (window-size sub horizontal t)))
- (set-window-new-normal sub 'ignore))
+ (if (window-size-fixed-p sub horizontal)
+ (progn
+ (setq total-sum
+ (- total-sum (window-size sub horizontal t)))
+ (set-window-new-normal sub 'ignore))
+ (setq number-of-children (1+ number-of-children)))
(setq sub (window-right sub)))
(setq failed t)
@@ -5334,16 +5347,16 @@ is non-nil)."
(set-window-new-normal sub 'skip)))
(setq sub (window-right sub))))
- ;; How can we be sure that `number-of-children' is NOT zero here ?
- (setq rest (% total-sum number-of-children))
- ;; Fix rounding by trying to enlarge non-stuck windows by one line
- ;; (column) until `rest' is zero.
- (setq sub first)
- (while (and sub (> rest 0))
- (unless (window--resize-child-windows-skip-p window)
- (set-window-new-pixel sub (min rest char-size) t)
- (setq rest (- rest char-size)))
- (setq sub (window-right sub)))
+ (when (> number-of-children 0)
+ (setq rest (% total-sum number-of-children))
+ ;; Fix rounding by trying to enlarge non-stuck windows by one line
+ ;; (column) until `rest' is zero.
+ (setq sub first)
+ (while (and sub (> rest 0))
+ (unless (window--resize-child-windows-skip-p window)
+ (set-window-new-pixel sub (min rest char-size) t)
+ (setq rest (- rest char-size)))
+ (setq sub (window-right sub))))
;; Fix rounding by trying to enlarge stuck windows by one line
;; (column) until `rest' equals zero.
@@ -5539,9 +5552,18 @@ specific buffers."
(t 'leaf)))
(buffer (window-buffer window))
(selected (eq window (selected-window)))
+ (next-buffers (when (window-live-p window)
+ (delq nil (mapcar (lambda (buffer)
+ (and (buffer-live-p buffer) buffer))
+ (window-next-buffers window)))))
+ (prev-buffers (when (window-live-p window)
+ (delq nil (mapcar (lambda (entry)
+ (and (buffer-live-p (nth 0 entry))
+ entry))
+ (window-prev-buffers window)))))
(head
`(,type
- ,@(unless (window-next-sibling window) `((last . t)))
+ ,@(unless (window-next-sibling window) '((last . t)))
(pixel-width . ,(window-pixel-width window))
(pixel-height . ,(window-pixel-height window))
(total-width . ,(window-total-width window))
@@ -5573,7 +5595,7 @@ specific buffers."
(let ((point (window-point window))
(start (window-start window)))
`((buffer
- ,(buffer-name buffer)
+ ,(if writable (buffer-name buffer) buffer)
(selected . ,selected)
(hscroll . ,(window-hscroll window))
(fringes . ,(window-fringes window))
@@ -5591,7 +5613,22 @@ specific buffers."
(start . ,(if writable
start
(with-current-buffer buffer
- (copy-marker start))))))))))
+ (copy-marker start))))))))
+ ,@(when next-buffers
+ `((next-buffers
+ . ,(if writable
+ (mapcar (lambda (buffer) (buffer-name buffer))
+ next-buffers)
+ next-buffers))))
+ ,@(when prev-buffers
+ `((prev-buffers
+ . ,(if writable
+ (mapcar (lambda (entry)
+ (list (buffer-name (nth 0 entry))
+ (marker-position (nth 1 entry))
+ (marker-position (nth 2 entry))))
+ prev-buffers)
+ prev-buffers))))))
(tail
(when (memq type '(vc hc))
(let (list)
@@ -5734,7 +5771,9 @@ value can be also stored on disk and read back in a new session."
(let ((window (car item))
(combination-limit (cdr (assq 'combination-limit item)))
(parameters (cdr (assq 'parameters item)))
- (state (cdr (assq 'buffer item))))
+ (state (cdr (assq 'buffer item)))
+ (next-buffers (cdr (assq 'next-buffers item)))
+ (prev-buffers (cdr (assq 'prev-buffers item))))
(when combination-limit
(set-window-combination-limit window combination-limit))
;; Reset window's parameters and assign saved ones (we might want
@@ -5746,7 +5785,8 @@ value can be also stored on disk and read back in a new session."
(set-window-parameter window (car parameter) (cdr parameter))))
;; Process buffer related state.
(when state
- (let ((buffer (get-buffer (car state))))
+ (let ((buffer (get-buffer (car state)))
+ (state (cdr state)))
(if buffer
(with-current-buffer buffer
(set-window-buffer window buffer)
@@ -5815,7 +5855,30 @@ value can be also stored on disk and read back in a new session."
(set-window-point window (cdr (assq 'point state))))
;; Select window if it's the selected one.
(when (cdr (assq 'selected state))
- (select-window window)))
+ (select-window window))
+ (when next-buffers
+ (set-window-next-buffers
+ window
+ (delq nil (mapcar (lambda (buffer)
+ (setq buffer (get-buffer buffer))
+ (when (buffer-live-p buffer) buffer))
+ next-buffers))))
+ (when prev-buffers
+ (set-window-prev-buffers
+ window
+ (delq nil (mapcar (lambda (entry)
+ (let ((buffer (get-buffer (nth 0 entry)))
+ (m1 (nth 1 entry))
+ (m2 (nth 2 entry)))
+ (when (buffer-live-p buffer)
+ (list buffer
+ (if (markerp m1) m1
+ (set-marker (make-marker) m1
+ buffer))
+ (if (markerp m2) m2
+ (set-marker (make-marker) m2
+ buffer))))))
+ prev-buffers)))))
;; We don't want to raise an error in case the buffer does
;; not exist anymore, so we switch to a previous one and
;; save the window with the intention of deleting it later
@@ -5827,29 +5890,34 @@ value can be also stored on disk and read back in a new session."
"Put window state STATE into WINDOW.
STATE should be the state of a window returned by an earlier
invocation of `window-state-get'. Optional argument WINDOW must
-specify a valid window and defaults to the selected one. If
-WINDOW is not live, replace WINDOW by a live one before putting
-STATE into it.
+specify a valid window. If WINDOW is not a live window,
+replace WINDOW by a new live window created on the same frame.
+If WINDOW is nil, create a new window before putting STATE into it.
Optional argument IGNORE non-nil means ignore minimum window
sizes and fixed size restrictions. IGNORE equal `safe' means
windows can get as small as `window-safe-min-height' and
`window-safe-min-width'."
(setq window-state-put-stale-windows nil)
- (setq window (window-normalize-window window))
- ;; When WINDOW is internal, reduce it to a live one to put STATE into,
- ;; see Bug#16793.
+ ;; When WINDOW is internal or nil, reduce it to a live one,
+ ;; then create a new window on the same frame to put STATE into.
(unless (window-live-p window)
(let ((root window))
- (setq window (catch 'live
- (walk-window-subtree
- (lambda (window)
- (when (and (window-live-p window)
- (not (window-parameter window 'window-side)))
- (throw 'live window)))
- root)))
- (delete-other-windows-internal window root)))
+ (setq window (if root
+ (catch 'live
+ (walk-window-subtree
+ (lambda (window)
+ (when (and (window-live-p window)
+ (not (window-parameter
+ window 'window-side)))
+ (throw 'live window)))
+ root))
+ (selected-window)))
+ (delete-other-windows-internal window root)
+ ;; Create a new window to replace the existing one.
+ (setq window (prog1 (split-window window)
+ (delete-window window)))))
(set-window-dedicated-p window nil)
@@ -6042,7 +6110,7 @@ element is BUFFER."
(list 'other
;; A quadruple of WINDOW's buffer, start, point and height.
(list (current-buffer) (window-start window)
- ;; Preserve window-point-insertion-type (Bug#12588).
+ ;; Preserve window-point-insertion-type (Bug#12855).
(copy-marker
(window-point window) window-point-insertion-type)
(if (window-combined-p window)
@@ -6642,6 +6710,7 @@ represents a live window, nil otherwise."
))
frame))))
+(defvaralias 'even-window-heights 'even-window-sizes)
(defcustom even-window-sizes t
"If non-nil `display-buffer' will try to even window sizes.
Otherwise `display-buffer' will leave the window configuration
@@ -6655,7 +6724,6 @@ any of them."
(const :tag "Always" t))
:version "25.1"
:group 'windows)
-(defvaralias 'even-window-heights 'even-window-sizes)
(defun window--even-window-sizes (window)
"Even sizes of WINDOW and selected window.
@@ -7330,12 +7398,23 @@ text-only terminal), try with `display-buffer-pop-up-frame'.
If that cannot be done, and `pop-up-windows' is non-nil, try
again with `display-buffer-pop-up-window'."
- (or (and (if (eq pop-up-frames 'graphic-only)
- (display-graphic-p)
- pop-up-frames)
- (display-buffer-pop-up-frame buffer alist))
- (and pop-up-windows
- (display-buffer-pop-up-window buffer alist))))
+ (or (display-buffer--maybe-pop-up-frame buffer alist)
+ (display-buffer--maybe-pop-up-window buffer alist)))
+
+(defun display-buffer--maybe-pop-up-frame (buffer alist)
+ "Try displaying BUFFER based on `pop-up-frames'.
+If `pop-up-frames' is non-nil (and not `graphic-only' on a
+text-only terminal), try with `display-buffer-pop-up-frame'."
+ (and (if (eq pop-up-frames 'graphic-only)
+ (display-graphic-p)
+ pop-up-frames)
+ (display-buffer-pop-up-frame buffer alist)))
+
+(defun display-buffer--maybe-pop-up-window (buffer alist)
+ "Try displaying BUFFER based on `pop-up-windows'.
+If `pop-up-windows' is non-nil, try with `display-buffer-pop-up-window'."
+ (and pop-up-windows
+ (display-buffer-pop-up-window buffer alist)))
(defun display-buffer-in-child-frame (buffer alist)
"Display BUFFER in a child frame.
@@ -7384,22 +7463,56 @@ If there is a window below the selected one and that window
already displays BUFFER, use that window. Otherwise, try to
create a new window below the selected one and show BUFFER there.
If that attempt fails as well and there is a non-dedicated window
-below the selected one, use that window."
- (let (window)
+below the selected one, use that window.
+
+If ALIST contains a 'window-min-height' entry, this function
+ensures that the window used is or can become at least as high as
+specified by that entry's value. Note that such an entry alone
+will not resize the window per se. In order to do that, ALIST
+must also contain a 'window-height' entry with the same value."
+ (let ((min-height (cdr (assq 'window-min-height alist)))
+ window)
(or (and (setq window (window-in-direction 'below))
- (eq buffer (window-buffer window))
+ (eq buffer (window-buffer window))
+ (or (not (numberp min-height))
+ (>= (window-height window) min-height)
+ ;; 'window--display-buffer' can resize this window if
+ ;; and only if it has a 'quit-restore' parameter
+ ;; certifying that it always showed BUFFER before.
+ (let ((height (window-height window))
+ (quit-restore (window-parameter window 'quit-restore)))
+ (and quit-restore
+ (eq (nth 1 quit-restore) 'window)
+ (window-resizable-p window (- min-height height)))))
(window--display-buffer buffer window 'reuse alist))
(and (not (frame-parameter nil 'unsplittable))
- (let ((split-height-threshold 0)
+ (or (not (numberp min-height))
+ (window-sizable-p nil (- min-height)))
+ (let ((split-height-threshold 0)
split-width-threshold)
- (setq window (window--try-to-split-window
+ (setq window (window--try-to-split-window
(selected-window) alist)))
- (window--display-buffer
- buffer window 'window alist display-buffer-mark-dedicated))
+ (window--display-buffer
+ buffer window 'window alist display-buffer-mark-dedicated))
(and (setq window (window-in-direction 'below))
- (not (window-dedicated-p window))
+ (not (window-dedicated-p window))
+ (or (not (numberp min-height))
+ ;; A window that showed another buffer before cannot
+ ;; be resized.
+ (>= (window-height window) min-height))
(window--display-buffer
- buffer window 'reuse alist display-buffer-mark-dedicated)))))
+ buffer window 'reuse alist display-buffer-mark-dedicated)))))
+
+(defun display-buffer--maybe-at-bottom (buffer alist)
+ (let ((alist (append alist `(,(if temp-buffer-resize-mode
+ '(window-height . resize-temp-buffer-window)
+ '(window-height . fit-window-to-buffer))
+ ,(when temp-buffer-resize-mode
+ '(preserve-size . (nil . t)))))))
+ (or (display-buffer--maybe-same-window buffer alist)
+ (display-buffer-reuse-window buffer alist)
+ (display-buffer--maybe-pop-up-frame buffer alist)
+ (display-buffer-at-bottom buffer alist))))
(defun display-buffer-at-bottom (buffer alist)
"Try displaying BUFFER in a window at the bottom of the selected frame.
@@ -7417,8 +7530,8 @@ selected frame."
(setq bottom-window-shows-buffer t)
(setq bottom-window window))
((not bottom-window)
- (setq bottom-window window)))
- nil nil 'nomini))
+ (setq bottom-window window))))
+ nil nil 'nomini)
(or (and bottom-window-shows-buffer
(window--display-buffer
buffer bottom-window 'reuse alist display-buffer-mark-dedicated))
@@ -7653,7 +7766,9 @@ position in the selected window.
This variable is ignored if the buffer is already displayed in
the selected window or never appeared in it before, or if
-`switch-to-buffer' calls `pop-to-buffer' to display the buffer."
+`switch-to-buffer' calls `pop-to-buffer' to display the buffer,
+or non-nil `switch-to-buffer-obey-display-actions' displays it
+in another window."
:type '(choice
(const :tag "Never" nil)
(const :tag "If already displayed elsewhere" already-displayed)
@@ -7688,6 +7803,16 @@ FORCE-SAME-WINDOW is non-nil."
:group 'windows
:version "25.1")
+(defcustom switch-to-buffer-obey-display-actions nil
+ "If non-nil, `switch-to-buffer' runs `pop-to-buffer-same-window' instead.
+This means that when switching the buffer it respects display actions
+specified by `display-buffer-overriding-action', `display-buffer-alist'
+and other display related variables. So `switch-to-buffer' will display
+the buffer in the window specified by the rules from these variables."
+ :type 'boolean
+ :group 'windows
+ :version "27.1")
+
(defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
"Display buffer BUFFER-OR-NAME in the selected window.
@@ -7720,59 +7845,83 @@ displaying it the most recently selected one.
If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
must be displayed in the selected window when called
non-interactively; if that is impossible, signal an error rather
-than calling `pop-to-buffer'.
+than calling `pop-to-buffer'. It has no effect when the option
+`switch-to-buffer-obey-display-actions' is non-nil.
The option `switch-to-buffer-preserve-window-point' can be used
to make the buffer appear at its last position in the selected
window.
+If the option `switch-to-buffer-obey-display-actions' is non-nil,
+run the function `pop-to-buffer-same-window' instead.
+This may display the buffer in another window as specified by
+`display-buffer-overriding-action', `display-buffer-alist' and
+other display related variables. If this results in displaying
+the buffer in the selected window, window start and point are adjusted
+as prescribed by the option `switch-to-buffer-preserve-window-point'.
+Otherwise, these are left alone.
+
Return the buffer switched to."
(interactive
(let ((force-same-window
- (cond
- ((window-minibuffer-p) nil)
- ((not (eq (window-dedicated-p) t)) 'force-same-window)
- ((pcase switch-to-buffer-in-dedicated-window
- (`nil (user-error
- "Cannot switch buffers in a dedicated window"))
- (`prompt
- (if (y-or-n-p
- (format "Window is dedicated to %s; undedicate it"
- (window-buffer)))
- (progn
- (set-window-dedicated-p nil nil)
- 'force-same-window)
- (user-error
- "Cannot switch buffers in a dedicated window")))
- (`pop nil)
- (_ (set-window-dedicated-p nil nil) 'force-same-window))))))
+ (unless switch-to-buffer-obey-display-actions
+ (cond
+ ((window-minibuffer-p) nil)
+ ((not (eq (window-dedicated-p) t)) 'force-same-window)
+ ((pcase switch-to-buffer-in-dedicated-window
+ ('nil (user-error
+ "Cannot switch buffers in a dedicated window"))
+ ('prompt
+ (if (y-or-n-p
+ (format "Window is dedicated to %s; undedicate it"
+ (window-buffer)))
+ (progn
+ (set-window-dedicated-p nil nil)
+ 'force-same-window)
+ (user-error
+ "Cannot switch buffers in a dedicated window")))
+ ('pop nil)
+ (_ (set-window-dedicated-p nil nil) 'force-same-window)))))))
(list (read-buffer-to-switch "Switch to buffer: ") nil force-same-window)))
- (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
+ (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name))
+ (set-window-start-and-point (not switch-to-buffer-obey-display-actions)))
(cond
;; Don't call set-window-buffer if it's not needed since it
;; might signal an error (e.g. if the window is dedicated).
- ((eq buffer (window-buffer)))
- ((window-minibuffer-p)
+ ((and (eq buffer (window-buffer))
+ ;; pop-to-buffer-same-window might decide to display
+ ;; the same buffer in another window
+ (not switch-to-buffer-obey-display-actions)))
+ ((and (window-minibuffer-p)
+ (not switch-to-buffer-obey-display-actions))
(if force-same-window
(user-error "Cannot switch buffers in minibuffer window")
(pop-to-buffer buffer norecord)))
- ((eq (window-dedicated-p) t)
+ ((and (eq (window-dedicated-p) t)
+ (not switch-to-buffer-obey-display-actions))
(if force-same-window
(user-error "Cannot switch buffers in a dedicated window")
(pop-to-buffer buffer norecord)))
(t
- (let* ((entry (assq buffer (window-prev-buffers)))
- (displayed (and (eq switch-to-buffer-preserve-window-point
- 'already-displayed)
- (get-buffer-window buffer 0))))
- (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) (nth 1 entry) t)
- (set-window-point nil (nth 2 entry))))))
+ (when switch-to-buffer-obey-display-actions
+ (let ((selected-window (selected-window)))
+ (pop-to-buffer-same-window buffer norecord)
+ (when (eq (selected-window) selected-window)
+ (setq set-window-start-and-point t))))
+
+ (when set-window-start-and-point
+ (let* ((entry (assq buffer (window-prev-buffers)))
+ (displayed (and (eq switch-to-buffer-preserve-window-point
+ 'already-displayed)
+ (get-buffer-window buffer 0))))
+ (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) (nth 1 entry) t)
+ (set-window-point nil (nth 2 entry)))))))
(unless norecord
(select-window (selected-window)))
@@ -8790,7 +8939,7 @@ A prefix argument is handled like `recenter':
With plain `C-u', move current line to window center."
(interactive "P")
(cond
- (arg (recenter arg)) ; Always respect ARG.
+ (arg (recenter arg t)) ; Always respect ARG.
(t
(setq recenter-last-op
(if (eq this-command last-command)
@@ -8801,15 +8950,15 @@ A prefix argument is handled like `recenter':
(min (max 0 scroll-margin)
(truncate (/ (window-body-height) 4.0)))))
(cond ((eq recenter-last-op 'middle)
- (recenter))
+ (recenter nil t))
((eq recenter-last-op 'top)
- (recenter this-scroll-margin))
+ (recenter this-scroll-margin t))
((eq recenter-last-op 'bottom)
- (recenter (- -1 this-scroll-margin)))
+ (recenter (- -1 this-scroll-margin) t))
((integerp recenter-last-op)
- (recenter recenter-last-op))
+ (recenter recenter-last-op t))
((floatp recenter-last-op)
- (recenter (round (* recenter-last-op (window-height))))))))))
+ (recenter (round (* recenter-last-op (window-height))) t)))))))
(define-key global-map [?\C-l] 'recenter-top-bottom)
@@ -8947,35 +9096,17 @@ This is different from `scroll-down-command' that scrolls a full screen."
(put 'scroll-down-line 'scroll-command t)
-(defun scroll-other-window-down (&optional lines)
- "Scroll the \"other window\" down.
-For more details, see the documentation for `scroll-other-window'."
- (interactive "P")
- (scroll-other-window
- ;; Just invert the argument's meaning.
- ;; We can do that without knowing which window it will be.
- (if (eq lines '-) nil
- (if (null lines) '-
- (- (prefix-numeric-value lines))))))
-
(defun beginning-of-buffer-other-window (arg)
"Move point to the beginning of the buffer in the other window.
Leave mark at previous position.
With arg N, put point N/10 of the way from the true beginning."
(interactive "P")
- (let ((orig-window (selected-window))
- (window (other-window-for-scrolling)))
- ;; We use unwind-protect rather than save-window-excursion
- ;; because the latter would preserve the things we want to change.
- (unwind-protect
- (progn
- (select-window window)
- ;; Set point and mark in that window's buffer.
- (with-no-warnings
- (beginning-of-buffer arg))
- ;; Set point accordingly.
- (recenter '(t)))
- (select-window orig-window))))
+ (with-selected-window (other-window-for-scrolling)
+ ;; Set point and mark in that window's buffer.
+ (with-no-warnings
+ (beginning-of-buffer arg))
+ ;; Set point accordingly.
+ (recenter '(t))))
(defun end-of-buffer-other-window (arg)
"Move point to the end of the buffer in the other window.
@@ -8983,15 +9114,10 @@ Leave mark at previous position.
With arg N, put point N/10 of the way from the true end."
(interactive "P")
;; See beginning-of-buffer-other-window for comments.
- (let ((orig-window (selected-window))
- (window (other-window-for-scrolling)))
- (unwind-protect
- (progn
- (select-window window)
- (with-no-warnings
- (end-of-buffer arg))
- (recenter '(t)))
- (select-window orig-window))))
+ (with-selected-window (other-window-for-scrolling)
+ (with-no-warnings
+ (end-of-buffer arg))
+ (recenter '(t))))
(defvar mouse-autoselect-window-timer nil
"Timer used by delayed window autoselection.")