(window-body-width window pixelwise)
(window-body-height window pixelwise)))
+(declare-function font-info "font.c" (name &optional frame))
+
(defun window-font-width (&optional window face)
"Return average character width for the font of FACE used in WINDOW.
WINDOW must be a live window and defaults to the selected one.
(aref info 3))
(frame-char-height))))
+(defvar overflow-newline-into-fringe)
+
(defun window-max-chars-per-line (&optional window face)
"Return the number of characters that can be displayed on one line in WINDOW.
WINDOW must be a live window and defaults to the selected one.
(defcustom switch-to-visible-buffer t
"If non-nil, allow switching to an already visible buffer.
If this variable is non-nil, `switch-to-prev-buffer' and
-`switch-to-next-buffer' may switch to an already visible buffer
-provided the buffer was shown before in the window specified as
-argument to those functions. If this variable is nil,
-`switch-to-prev-buffer' and `switch-to-next-buffer' always try to
-avoid switching to a buffer that is already visible in another
-window on the same frame."
+`switch-to-next-buffer' may switch to an already visible buffer.
+If this variable is nil, `switch-to-prev-buffer' and
+`switch-to-next-buffer' always try to avoid switching to a buffer
+that is already visible in another window on the same frame."
:type 'boolean
:version "24.1"
:group 'windows)
(or (null pred) (funcall pred buffer))
(not (eq (aref (buffer-name buffer) 0) ?\s))
(or bury-or-kill (not (memq buffer next-buffers))))
- (if (get-buffer-window buffer frame)
+ (if (and (not switch-to-visible-buffer)
+ (get-buffer-window buffer frame))
;; Try to avoid showing a buffer visible in some other window.
(unless visible
(setq visible buffer))
(or (null pred) (funcall pred buffer))
(not (eq (aref (buffer-name buffer) 0) ?\s))
(not (assq buffer (window-prev-buffers window))))
- (if (get-buffer-window buffer frame)
+ (if (and (not switch-to-visible-buffer)
+ (get-buffer-window buffer frame))
;; Try to avoid showing a buffer visible in some other window.
(setq visible buffer)
(setq new-buffer buffer)
Optional second argument BURY-OR-KILL tells how to proceed with
the buffer of WINDOW. The following values are handled:
-`nil' means to not handle the buffer in a particular way. This
+nil means to not handle the buffer in a particular way. This
means that if WINDOW is not deleted by this function, invoking
`switch-to-prev-buffer' will usually show the buffer again.
(eq (nth 3 quit-restore) buffer))
;; Show another buffer stored in quit-restore parameter.
(when (and (integerp (nth 3 quad))
- (/= (nth 3 quad) (window-total-height window)))
+ (if (window-combined-p window)
+ (/= (nth 3 quad) (window-total-height window))
+ (/= (nth 3 quad) (window-total-width window))))
;; Try to resize WINDOW to its old height but don't signal an
;; error.
(condition-case nil
- (window-resize window (- (nth 3 quad) (window-total-height window)))
+ (window-resize
+ window
+ (- (nth 3 quad) (if (window-combined-p window)
+ (window-total-height window)
+ (window-total-width window)))
+ (window-combined-p window t))
(error nil)))
(set-window-dedicated-p window nil)
;; Restore WINDOW's previous buffer, start and point position.
root))))
(delete-other-windows-internal window root)))
+ (set-window-dedicated-p window nil)
+
(let* ((frame (window-frame window))
(head (car state))
;; We check here (1) whether the total sizes of root window of
(cond
((eq type 'reuse)
(if (eq (window-buffer window) buffer)
- ;; WINDOW shows BUFFER already.
- (when (consp (window-parameter window 'quit-restore))
- ;; If WINDOW has a quit-restore parameter, reset its car.
- (setcar (window-parameter window 'quit-restore) 'same))
+ ;; WINDOW shows BUFFER already. Update WINDOW's quit-restore
+ ;; parameter, if any.
+ (let ((quit-restore (window-parameter window 'quit-restore)))
+ (when (consp quit-restore)
+ (setcar quit-restore 'same)
+ ;; The selected-window might have changed in
+ ;; between (Bug#20353).
+ (unless (or (eq window (selected-window))
+ (eq window (nth 2 quit-restore)))
+ (setcar (cddr quit-restore) (selected-window)))))
;; WINDOW shows another buffer.
(with-current-buffer (window-buffer window)
(set-window-parameter
;; Preserve window-point-insertion-type (Bug#12588).
(copy-marker
(window-point window) window-point-insertion-type)
- (window-total-height window))
+ (if (window-combined-p window)
+ (window-total-height window)
+ (window-total-width window)))
(selected-window) buffer)))))
((eq type 'window)
;; WINDOW has been created on an existing frame.
))
frame))))
-(defcustom even-window-heights t
- "If non-nil `display-buffer' will try to even window heights.
+(defcustom even-window-sizes t
+ "If non-nil `display-buffer' will try to even window sizes.
Otherwise `display-buffer' will leave the window configuration
-alone. Heights are evened only when `display-buffer' chooses a
-window that appears above or below the selected window."
- :type 'boolean
+alone. Special values are `height-only' to even heights only and
+`width-only' to even widths only. Any other value means to even
+any of them."
+ :type '(choice
+ (const :tag "Never" nil)
+ (const :tag "Side-by-side windows only" width-only)
+ (const :tag "Windows above or below only" height-only)
+ (const :tag "Always" t))
+ :version "25.1"
:group 'windows)
-
-(defun window--even-window-heights (window)
- "Even heights of WINDOW and selected window.
-Do this only if these windows are vertically adjacent to each
-other, `even-window-heights' is non-nil, and the selected window
-is higher than WINDOW."
- (when (and even-window-heights
- ;; Even iff WINDOW forms a vertical combination with the
- ;; selected window, and WINDOW's height exceeds that of the
- ;; selected window, see also bug#11880.
- (window-combined-p window)
- (= (window-child-count (window-parent window)) 2)
- (eq (window-parent) (window-parent window))
- (> (window-total-height) (window-total-height window)))
- ;; Don't throw an error if we can't even window heights for
- ;; whatever reason.
- (condition-case nil
- (enlarge-window
- (/ (- (window-total-height window) (window-total-height)) 2))
- (error nil))))
+(defvaralias 'even-window-heights 'even-window-sizes)
+
+(defun window--even-window-sizes (window)
+ "Even sizes of WINDOW and selected window.
+Even only if these windows are the only children of their parent,
+`even-window-sizes' has the appropriate value and the selected
+window is larger than WINDOW."
+ (when (and (= (window-child-count (window-parent window)) 2)
+ (eq (window-parent) (window-parent window)))
+ (cond
+ ((and (not (memq even-window-sizes '(nil height-only)))
+ (window-combined-p window t)
+ (> (window-total-width) (window-total-width window)))
+ (condition-case nil
+ (enlarge-window
+ (/ (- (window-total-width window) (window-total-width)) 2) t)
+ (error nil)))
+ ((and (not (memq even-window-sizes '(nil width-only)))
+ (window-combined-p window)
+ (> (window-total-height) (window-total-height window)))
+ (condition-case nil
+ (enlarge-window
+ (/ (- (window-total-height window) (window-total-height)) 2))
+ (error nil))))))
(defun window--display-buffer (buffer window type &optional alist dedicated)
"Display BUFFER in WINDOW.
(const display-buffer-at-bottom)
(const display-buffer-in-previous-window)
(const display-buffer-use-some-window)
+ (const display-buffer-use-some-frame)
(function :tag "Other function"))
"Custom type for `display-buffer' action functions.")
`display-buffer-pop-up-window'
`display-buffer-in-previous-window'
`display-buffer-use-some-window'
+ `display-buffer-use-some-frame'
Recognized alist entries include:
;;; `display-buffer' action functions:
+(defun display-buffer-use-some-frame (buffer alist)
+ "Display BUFFER in an existing frame that meets a predicate
+\(by default any frame other than the current frame). If
+successful, return the window used; otherwise return nil.
+
+If ALIST has a non-nil `inhibit-switch-frame' entry, avoid
+raising the frame.
+
+If ALIST has a non-nil `frame-predicate' entry, its value is a
+function taking one argument (a frame), returning non-nil if the
+frame is a candidate; this function replaces the default
+predicate.
+
+If ALIST has a non-nil `inhibit-same-window' entry, avoid using
+the currently selected window (only useful with a frame-predicate
+that allows the selected frame)."
+ (let* ((predicate (or (cdr (assq 'frame-predicate alist))
+ (lambda (frame)
+ (and
+ (not (eq frame (selected-frame)))
+ (not (window-dedicated-p
+ (or
+ (get-lru-window frame)
+ (frame-first-window frame)))))
+ )))
+ (frame (car (filtered-frame-list predicate)))
+ (window (and frame (get-lru-window frame nil (cdr (assq 'inhibit-same-window alist))))))
+ (when window
+ (prog1
+ (window--display-buffer
+ buffer window 'frame alist display-buffer-mark-dedicated)
+ (unless (cdr (assq 'inhibit-switch-frame alist))
+ (window--maybe-raise-frame frame))))
+ ))
+
(defun display-buffer-same-window (buffer alist)
"Display BUFFER in the selected window.
This fails if ALIST has a non-nil `inhibit-same-window' entry, or
(prog1
(window--display-buffer buffer window 'reuse alist)
- (window--even-window-heights window)
+ (window--even-window-sizes window)
(unless (cdr (assq 'inhibit-switch-frame alist))
(window--maybe-raise-frame (window-frame window)))))))
:group 'windows
:version "24.3")
+(defcustom switch-to-buffer-in-dedicated-window nil
+ "Allow switching to buffer in strongly dedicated windows.
+If non-nil, allow `switch-to-buffer' to proceed when called
+interactively and the selected window is strongly dedicated to
+its buffer.
+
+The following values are recognized:
+
+nil - disallow switching; signal an error
+
+prompt - prompt user whether to allow switching
+
+pop - perform `pop-to-buffer' instead
+
+t - undedicate selected window and switch
+
+When called non-interactively, `switch-to-buffer' always signals
+an error when the selected window is dedicated to its buffer and
+FORCE-SAME-WINDOW is non-nil."
+ :type '(choice
+ (const :tag "Disallow" nil)
+ (const :tag "Prompt" prompt)
+ (const :tag "Pop" pop)
+ (const :tag "Allow" t))
+ :group 'windows
+ :version "25.1")
+
(defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
"Display buffer BUFFER-OR-NAME in the selected window.
within a Lisp program! Use `set-buffer' instead. That avoids
messing with the window-buffer correspondences.
-If the selected window cannot display the specified
-buffer (e.g. if it is a minibuffer window or strongly dedicated
-to another buffer), call `pop-to-buffer' to select the buffer in
-another window.
+If the selected window cannot display the specified buffer
+because it is a minibuffer window or strongly dedicated to
+another buffer, call `pop-to-buffer' to select the buffer in
+another window. In interactive use, if the selected window is
+strongly dedicated to its buffer, the value of the option
+`switch-to-buffer-in-dedicated-window' specifies how to proceed.
If called interactively, read the buffer name using the
minibuffer. The variable `confirm-nonexistent-file-or-buffer'
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; if that is impossible,
-signal an error rather than calling `pop-to-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'.
The option `switch-to-buffer-preserve-window-point' can be used
to make the buffer appear at its last position in the selected
Return the buffer switched to."
(interactive
- (list (read-buffer-to-switch "Switch to buffer: ") nil 'force-same-window))
+ (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))))))
+ (list (read-buffer-to-switch "Switch to buffer: ") nil force-same-window)))
(let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
(cond
;; Don't call set-window-buffer if it's not needed since it
(<= left (- right margin)) (<= margin right))
margin))
+(declare-function tool-bar-height "xdisp.c" (&optional frame pixelwise))
+
(defun fit-frame-to-buffer (&optional frame max-height min-height max-width min-width only)
"Adjust size of FRAME to display the contents of its buffer exactly.
FRAME can be any live frame and defaults to the selected one.
\f
(defvar recenter-last-op nil
"Indicates the last recenter operation performed.
-Possible values: `top', `middle', `bottom', integer or float numbers.")
+Possible values: `top', `middle', `bottom', integer or float numbers.
+It can also be nil, which means the first value in `recenter-positions'.")
(defcustom recenter-positions '(middle top bottom)
"Cycling order for `recenter-top-bottom'.
displayed windows and returning a cons (WIDTH . HEIGHT)
describing the width and height with which Emacs will call
`set-process-window-size' for that process. If the function
-returns `nil', Emacs does not call `set-process-window-size'.
+returns nil, Emacs does not call `set-process-window-size'.
This function is called with the process buffer as the current
buffer and with two arguments: the process and a list of windows