# HG changeset patch # User Martin Rudalics # Date 1212929979 0 # Node ID a1063beb10cfd57612607cf063235443494f0f4d # Parent d9b3cab423751d6e671d8d94fd572165e6b2ddb0 (split-height-threshold, split-width-threshold): Add choice nil. (split-window-preferred-function): Allow either nil or a function. (window--splittable-p, window--try-to-split-window): Handle changed option values. (window--frame-usable-p): Handle nil argument. (display-buffer): Call get-lru-window when pop-up-windows is nil and window can't be split. diff -r d9b3cab42375 -r a1063beb10cf lisp/window.el --- a/lisp/window.el Sun Jun 08 12:41:36 2008 +0000 +++ b/lisp/window.el Sun Jun 08 12:59:39 2008 +0000 @@ -544,19 +544,19 @@ `special-display-buffer-names' and `special-display-regexps' control this." (let (tmp) - (cond - ((not (stringp buffer-name))) - ;; Make sure to return t in the following two cases. - ((member buffer-name special-display-buffer-names) t) + (cond + ((not (stringp buffer-name))) + ;; Make sure to return t in the following two cases. + ((member buffer-name special-display-buffer-names) t) ((setq tmp (assoc buffer-name special-display-buffer-names)) (cdr tmp)) - ((catch 'found - (dolist (regexp special-display-regexps) - (cond - ((stringp regexp) - (when (string-match-p regexp buffer-name) - (throw 'found t))) - ((and (consp regexp) (stringp (car regexp)) - (string-match-p (car regexp) buffer-name)) + ((catch 'found + (dolist (regexp special-display-regexps) + (cond + ((stringp regexp) + (when (string-match-p regexp buffer-name) + (throw 'found t))) + ((and (consp regexp) (stringp (car regexp)) + (string-match-p (car regexp) buffer-name)) (throw 'found (cdr regexp)))))))))) (defcustom special-display-buffer-names nil @@ -742,32 +742,37 @@ :type 'boolean :group 'windows) -(defcustom split-window-preferred-function nil - "How `display-buffer' shall split windows. -Choices are `Vertically', `Horizontally', and `Sensibly' where -the latter attempts to split wide windows horizontally, narrow -ones vertically. Alternatively, you can set this to a function -called with a window as single argument to split that window in -two and return the new window." - :type '(choice - (const :tag "Vertically" nil) - (const :tag "Horizontally" horizontally) - (const :tag "Sensibly" sensibly) - (function :tag "Function")) - :version "23.1" - :group 'windows) +(defcustom split-height-threshold 80 + "Minimum height of window to be split vertically. +If the value is a number, `display-buffer' can split a window +only if it has at least as many lines. If the value is nil, +`display-buffer' cannot split a window vertically. -(defcustom split-height-threshold 80 - "Minimum height of window to be split vertically by `display-buffer'. -If there is only one window, it can be split regardless of this." +If the window is the only window on its frame, `display-buffer' +can split it regardless of this value." + :type '(choice (const nil) (number :tag "lines")) :type 'number :version "23.1" :group 'windows) (defcustom split-width-threshold 160 - "Minimum width of window to be split horizontally by `display-buffer'. -If there is only one window, it can be split regardless of this." - :type 'number + "Minimum width of window to be split horizontally. +If the value is a number, `display-buffer' can split a window +only if it has at least as many columns. If the value is nil, +`display-buffer' cannot split a window horizontally." + :type '(choice (const nil) (number :tag "columns")) + :version "23.1" + :group 'windows) + +(defcustom split-window-preferred-function nil + "Function used by `display-buffer' to split windows. +If non-nil, a function called with a window as single argument +supposed to split that window and return the new window. If the +function returns nil the window is not split. + +If nil, `display-buffer' will split the window respecting the +values of `split-height-threshold' and `split-width-threshold'." + :type '(choice (const nil) (function :tag "Function")) :version "23.1" :group 'windows) @@ -779,11 +784,11 @@ WINDOW can be split vertically when the following conditions hold: -- `window-size-fixed' is either nil or equals `width' for the buffer of - WINDOW. +- `window-size-fixed' is either nil or equals `width' for the + buffer of WINDOW. -- WINDOW is at least as high as `split-height-threshold' or it is - the only window on its frame. +- `split-height-threshold' is a number and WINDOW is at least as + high as `split-height-threshold'. - When WINDOW is split evenly, the emanating windows are at least `window-min-height' lines tall and can accomodate at least one @@ -795,7 +800,8 @@ - `window-size-fixed' is either nil or equals `height' for the buffer of WINDOW. -- WINDOW is at least as wide as `split-width-threshold'. +- `split-width-threshold' is a number and WINDOW is at least as + wide as `split-width-threshold'. - When WINDOW is split evenly, the emanating windows are at least `window-min-width' or two (whichever is larger) columns wide." @@ -807,57 +813,60 @@ ;; and at least twice as wide as `window-min-width' and 2 (the ;; latter value is hardcoded). (and (memq window-size-fixed '(nil height)) + ;; Testing `window-full-width-p' here hardly makes any + ;; sense nowadays. This can be done more intuitively by + ;; setting up `split-width-threshold' appropriately. + (numberp split-width-threshold) (>= (window-width window) (max split-width-threshold (* 2 (max window-min-width 2))))) ;; A window can be split vertically when its height is not - ;; fixed, it is at least `split-height-threshold' lines high or - ;; the only window on its frame, and it is at least twice as - ;; high as `window-min-height' and 2 if it has a modeline or 1. + ;; fixed, it is at least `split-height-threshold' lines high, + ;; and it is at least twice as high as `window-min-height' and 2 + ;; if it has a modeline or 1. (and (memq window-size-fixed '(nil width)) + (numberp split-height-threshold) (>= (window-height window) - (max (if (one-window-p 'nomini) 0 split-height-threshold) + (max split-height-threshold (* 2 (max window-min-height (if mode-line-format 2 1)))))))))) (defun window--try-to-split-window (window) "Split window WINDOW if it is splittable. -See `split-window-preferred-function' for how WINDOW shall be -split. See `window--splittable-p' for how to determine whether a -window is splittable. If WINDOW can be split, return the value -returned by `split-window' or `split-window-preferred-function'." +See `window--splittable-p' for how to determine whether a window +is splittable. If WINDOW can be split, return the value returned +by `split-window' or `split-window-preferred-function'." (when (and (window-live-p window) - ;; Testing `window-full-width-p' here hardly makes any - ;; sense nowadays. This can be done more intuitively by - ;; setting up `split-width-threshold' appropriately. (not (frame-parameter (window-frame window) 'unsplittable))) - (or (and (not split-window-preferred-function) - (window--splittable-p window) - (split-window window)) - (and (eq split-window-preferred-function 'horizontally) - (window--splittable-p window t) - (split-window window nil t)) - (and (eq split-window-preferred-function 'sensibly) - ;; The following naive aspect-ratio test should become - ;; more sensible. - (or (and (> (window-width window) (window-height window)) - (window--splittable-p window t) - (split-window window nil t)) - (and (window--splittable-p window) - (split-window window)))) - (and (functionp split-window-preferred-function) - (funcall split-window-preferred-function window))))) + (if (functionp split-window-preferred-function) + ;; `split-window-preferred-function' is specified, so use it. + (funcall split-window-preferred-function window) + (or (and (window--splittable-p window) + ;; Split window vertically. + (split-window window)) + (and (window--splittable-p window t) + ;; Split window horizontally. + (split-window window nil t)) + (and (with-selected-window window + (one-window-p 'nomini)) + ;; If WINDOW is the only window on its frame, attempt to + ;; split it vertically disregarding the current value of + ;; `split-height-threshold'. + (let ((split-height-threshold 0)) + (window--splittable-p window) + (split-window window))))))) (defun window--frame-usable-p (frame) "Return frame FRAME if it can be used to display another buffer." - (let ((window (frame-root-window frame))) - ;; `frame-root-window' may be an internal window which is considered - ;; "dead" by `window-live-p'. Hence if `window' is not live we - ;; implicitly know that `frame' has a visible window we can use. - (when (or (not (window-live-p window)) - (and (not (window-minibuffer-p window)) - (not (window-dedicated-p window)))) - frame))) + (when (framep frame) + (let ((window (frame-root-window frame))) + ;; `frame-root-window' may be an internal window which is considered + ;; "dead" by `window-live-p'. Hence if `window' is not live we + ;; implicitly know that `frame' has a visible window we can use. + (when (or (not (window-live-p window)) + (and (not (window-minibuffer-p window)) + (not (window-dedicated-p window)))) + frame)))) (defcustom even-window-heights t "If non-nil `display-buffer' will try to even window heights. @@ -1009,12 +1018,12 @@ (or (window--try-to-split-window (get-largest-window frame-to-use t)) (window--try-to-split-window - (get-lru-window frame-to-use t)) - (get-lru-window frame-to-use nil))) + (get-lru-window frame-to-use t)))) (window--display-buffer-2 buffer window-to-use))) ((setq window-to-use ;; Reuse an existing window. - (or (get-buffer-window buffer 'visible) + (or (get-lru-window frame-to-use) + (get-buffer-window buffer 'visible) (get-largest-window 'visible nil) (get-buffer-window buffer 0) (get-largest-window 0 nil)