changeset 99275:0ecdd7e63016

(window-body-height, window-current-scroll-bars) (walk-windows, get-window-with-predicate, get-buffer-window-list) (minibuffer-window-active-p, count-windows) (window-safely-shrinkable-p, window--splittable-p) (window--try-to-split-window, window--frame-usable-p) (window--even-window-heights, window--display-buffer-1) (window--display-buffer-2, set-window-text-height) (fit-window-to-buffer, shrink-window-if-larger-than-buffer) (truncated-partial-width-window-p): Rewrite doc-string. (window-fixed-size-p): Simplify code. Rewrite doc-string. (split-window-vertically, split-window-horizontally): Rename args, rewrite doc-string, and simplify code. (split-window-save-restore-data): Rename args and use when instead of if.
author Martin Rudalics <rudalics@gmx.at>
date Fri, 31 Oct 2008 13:39:06 +0000
parents 513b8a9da6b0
children a4d60fa85641
files lisp/window.el
diffstat 1 files changed, 178 insertions(+), 162 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/window.el	Fri Oct 31 10:56:30 2008 +0000
+++ b/lisp/window.el	Fri Oct 31 13:39:06 2008 +0000
@@ -70,8 +70,14 @@
 	     (select-window save-selected-window-window))))))
 
 (defun window-body-height (&optional window)
-  "Return number of lines in window WINDOW for actual buffer text.
-This does not include the mode line (if any) or the header line (if any)."
+  "Return number of lines in WINDOW available for actual buffer text.
+WINDOW defaults to the selected window.
+
+The return value does not include the mode line or the header
+line, if any.  If a line at the bottom of the window is only
+partially visible, that line is included in the return value.  If
+you do not want to include a partially visible bottom line in the
+return value, use `window-text-height' instead."
   (or window (setq window (selected-window)))
   (if (window-minibuffer-p window)
       (window-height window)
@@ -99,11 +105,18 @@
 	(next-window base-window (if nomini 'arg) all-frames))))
 
 (defun window-current-scroll-bars (&optional window)
-  "Return the current scroll-bar settings in window WINDOW.
-Value is a cons (VERTICAL . HORIZONTAL) where VERTICAL specifies the
-current location of the vertical scroll-bars (left, right, or nil),
-and HORIZONTAL specifies the current location of the horizontal scroll
-bars (top, bottom, or nil)."
+  "Return the current scroll bar settings for WINDOW.
+WINDOW defaults to the selected window.
+
+The return value is a cons cell (VERTICAL . HORIZONTAL) where
+VERTICAL specifies the current location of the vertical scroll
+bars (`left', `right', or nil), and HORIZONTAL specifies the
+current location of the horizontal scroll bars (`top', `bottom',
+or nil).
+
+Unlike `window-scroll-bars', this function reports the scroll bar
+type actually used, once frame defaults and `scroll-bar-mode' are
+taken into account."
   (let ((vert (nth 2 (window-scroll-bars window)))
 	(hor nil))
     (when (or (eq vert t) (eq hor t))
@@ -116,28 +129,40 @@
     (cons vert hor)))
 
 (defun walk-windows (proc &optional minibuf all-frames)
-  "Cycle through all visible windows, calling PROC for each one.
-PROC is called with a window as argument.
+  "Cycle through all windows, calling PROC for each one.
+PROC must specify a function with a window as its sole argument.
+The optional arguments MINIBUF and ALL-FRAMES specify the set of
+windows to include in the walk, see also `next-window'.
 
-Optional second arg MINIBUF t means count the minibuffer window even
-if not active.  MINIBUF nil or omitted means count the minibuffer only if
-it is active.  MINIBUF neither t nor nil means not to count the
-minibuffer even if it is active.
+MINIBUF t means include the minibuffer window even if the
+minibuffer is not active.  MINIBUF nil or omitted means include
+the minibuffer window only if the minibuffer is active.  Any
+other value means do not include the minibuffer window even if
+the minibuffer is active.
 
 Several frames may share a single minibuffer; if the minibuffer
-counts, all windows on all frames that share that minibuffer count
-too.  Therefore, if you are using a separate minibuffer frame
-and the minibuffer is active and MINIBUF says it counts,
-`walk-windows' includes the windows in the frame from which you
-entered the minibuffer, as well as the minibuffer window.
+is active, all windows on all frames that share that minibuffer
+are included too.  Therefore, if you are using a separate
+minibuffer frame and the minibuffer is active and MINIBUF says it
+counts, `walk-windows' includes the windows in the frame from
+which you entered the minibuffer, as well as the minibuffer
+window.
 
-ALL-FRAMES is the optional third argument.
-ALL-FRAMES nil or omitted means cycle within the frames as specified above.
-ALL-FRAMES = `visible' means include windows on all visible frames.
-ALL-FRAMES = 0 means include windows on all visible and iconified frames.
-ALL-FRAMES = t means include windows on all frames including invisible frames.
-If ALL-FRAMES is a frame, it means include windows on that frame.
-Anything else means restrict to the selected frame."
+ALL-FRAMES nil or omitted means cycle through all windows on
+ WINDOW's frame, plus the minibuffer window if specified by the
+ MINIBUF argument, see above.  If the minibuffer counts, cycle
+ through all windows on all frames that share that minibuffer
+ too.
+ALL-FRAMES t means cycle through all windows on all existing
+ frames.
+ALL-FRAMES `visible' means cycle through all windows on all
+ visible frames.
+ALL-FRAMES 0 means cycle through all windows on all visible and
+ iconified frames.
+ALL-FRAMES a frame means cycle through all windows on that frame
+ only.
+Anything else means cycle through all windows on WINDOW's frame
+ and no others."
   ;; If we start from the minibuffer window, don't fail to come back to it.
   (if (window-minibuffer-p (selected-window))
       (setq minibuf t))
@@ -157,32 +182,15 @@
 (defun get-window-with-predicate (predicate &optional minibuf
 					    all-frames default)
   "Return a window satisfying PREDICATE.
-
-This function cycles through all visible windows using `walk-windows',
-calling PREDICATE on each one.  PREDICATE is called with a window as
-argument.  The first window for which PREDICATE returns a non-nil
-value is returned.  If no window satisfies PREDICATE, DEFAULT is
-returned.
-
-Optional second arg MINIBUF t means count the minibuffer window even
-if not active.  MINIBUF nil or omitted means count the minibuffer only if
-it is active.  MINIBUF neither t nor nil means not to count the
-minibuffer even if it is active.
+More precisely, cycle through all windows using `walk-windows',
+calling the function PREDICATE on each one of them with the
+window as its sole argument.  Return the first window for which
+PREDICATE returns non-nil.  If no window satisfies PREDICATE,
+return DEFAULT.
 
-Several frames may share a single minibuffer; if the minibuffer
-counts, all windows on all frames that share that minibuffer count
-too.  Therefore, if you are using a separate minibuffer frame
-and the minibuffer is active and MINIBUF says it counts,
-`walk-windows' includes the windows in the frame from which you
-entered the minibuffer, as well as the minibuffer window.
-
-ALL-FRAMES is the optional third argument.
-ALL-FRAMES nil or omitted means cycle within the frames as specified above.
-ALL-FRAMES = `visible' means include windows on all visible frames.
-ALL-FRAMES = 0 means include windows on all visible and iconified frames.
-ALL-FRAMES = t means include windows on all frames including invisible frames.
-If ALL-FRAMES is a frame, it means include windows on that frame.
-Anything else means restrict to the selected frame."
+The optional arguments MINIBUF and ALL-FRAMES specify the set of
+windows to include.  See `walk-windows' for the meaning of these
+arguments."
   (catch 'found
     (walk-windows #'(lambda (window)
 		      (when (funcall predicate window)
@@ -196,8 +204,11 @@
 (defun get-buffer-window-list (&optional buffer-or-name minibuf all-frames)
   "Return list of all windows displaying BUFFER-OR-NAME, or nil if none.
 BUFFER-OR-NAME may be a buffer or the name of an existing buffer
-and defaults to nil.
-See `walk-windows' for the meaning of MINIBUF and ALL-FRAMES."
+and defaults to the current buffer.
+
+The optional arguments MINIBUF and ALL-FRAMES specify the set of
+windows to consider.  See `walk-windows' for the precise meaning
+of these arguments."
   (let ((buffer (cond
 		 ((not buffer-or-name) (current-buffer))
 		 ((bufferp buffer-or-name) buffer-or-name)
@@ -210,23 +221,22 @@
     windows))
 
 (defun minibuffer-window-active-p (window)
-  "Return t if WINDOW (a minibuffer window) is now active."
+  "Return t if WINDOW is the currently active minibuffer window."
   (eq window (active-minibuffer-window)))
 
 (defun count-windows (&optional minibuf)
    "Return the number of visible windows.
-This counts the windows in the selected frame and (if the minibuffer is
-to be counted) its minibuffer frame (if that's not the same frame).
-The optional arg MINIBUF non-nil means count the minibuffer
-even if it is inactive."
+The optional argument MINIBUF specifies whether the minibuffer
+window shall be counted.  See `walk-windows' for the precise
+meaning of this argument."
    (let ((count 0))
      (walk-windows (lambda (w) (setq count (+ count 1)))
 		   minibuf)
      count))
 
 (defun window-safely-shrinkable-p (&optional window)
-  "Non-nil if the WINDOW can be shrunk without shrinking other windows.
-If WINDOW is nil or omitted, it defaults to the currently selected window."
+  "Return t if WINDOW can be shrunk without shrinking other windows.
+WINDOW defaults to the selected window."
   (with-selected-window (or window (selected-window))
     (let ((edges (window-edges)))
       (or (= (nth 2 edges) (nth 2 (window-edges (previous-window))))
@@ -429,17 +439,17 @@
       (dolist (c childs)
         (bw-balance-sub c cw ch)))))
 
-;;; A different solution to balance-windows
-
 (defun window-fixed-size-p (&optional window direction)
-  "Non-nil if WINDOW cannot be resized in DIRECTION.
-DIRECTION can be nil (i.e. any), `height' or `width'."
+  "Return t if WINDOW cannot be resized in DIRECTION.
+WINDOW defaults to the selected window.  DIRECTION can be
+nil (i.e. any), `height' or `width'."
   (with-current-buffer (window-buffer window)
-    (let ((fixed (and (boundp 'window-size-fixed) window-size-fixed)))
-      (when fixed
-	(not (and direction
-		  (member (cons direction window-size-fixed)
-			  '((height . width) (width . height)))))))))
+    (when (and (boundp 'window-size-fixed) window-size-fixed)
+      (not (and direction
+		(member (cons direction window-size-fixed)
+			'((height . width) (width . height))))))))
+
+;;; A different solution to balance-windows.
 
 (defvar window-area-factor 1
   "Factor by which the window area should be over-estimated.
@@ -449,7 +459,8 @@
 
 (defun balance-windows-area ()
   "Make all visible windows the same area (approximately).
-See also `window-area-factor' to change the relative size of specific buffers."
+See also `window-area-factor' to change the relative size of
+specific buffers."
   (interactive)
   (let* ((unchanged 0) (carry 0) (round 0)
          ;; Remove fixed-size windows.
@@ -773,7 +784,7 @@
   :group 'windows)
 
 (defun window--splittable-p (window &optional horizontal)
-  "Return non-nil if window WINDOW can be split evenly.
+  "Return non-nil if WINDOW can be split evenly.
 Optional argument HORIZONTAL non-nil means check whether WINDOW
 can be split horizontally.
 
@@ -788,7 +799,7 @@
 
 - When WINDOW is split evenly, the emanating windows are at least
   `window-min-height' lines tall and can accommodate at least one
-  line plus - if WINDOW has one - a modeline.
+  line plus - if WINDOW has one - a mode line.
 
 WINDOW can be split horizontally when the following conditions
 hold:
@@ -828,10 +839,10 @@
 				(if mode-line-format 2 1))))))))))
 
 (defun window--try-to-split-window (window)
-  "Split window WINDOW if it is splittable.
+  "Split WINDOW if it is splittable.
 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'."
+by `split-window' (or `split-window-preferred-function')."
   (when (and (window-live-p window)
 	     (not (frame-parameter (window-frame window) 'unsplittable)))
     (if (functionp split-window-preferred-function)
@@ -853,8 +864,8 @@
 		      (split-window window))))))))
 
 (defun window--frame-usable-p (frame)
-  "Return frame FRAME if it can be used to display another buffer."
-  (when (framep frame)
+  "Return FRAME if it can be used to display a buffer."
+  (when (frame-live-p 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
@@ -873,7 +884,7 @@
   :group 'windows)
 
 (defun window--even-window-heights (window)
-  "Even heights of window WINDOW and selected 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."
@@ -897,7 +908,7 @@
 	(error nil)))))
 
 (defun window--display-buffer-1 (window)
-  "Raise the frame containing the window WINDOW.
+  "Raise the frame containing WINDOW.
 Do not raise the selected frame.  Return WINDOW."
   (let* ((frame (window-frame window))
 	 (visible (frame-visible-p frame)))
@@ -912,7 +923,7 @@
     window))
 
 (defun window--display-buffer-2 (buffer window)
-  "Display buffer BUFFER in window WINDOW and make its frame visible.
+  "Display BUFFER in WINDOW and make its frame visible.
 Return WINDOW."
   (when (and (buffer-live-p buffer) (window-live-p window))
     (set-window-buffer window buffer)
@@ -1093,16 +1104,17 @@
   :type 'boolean
   :group 'windows)
 
-(defun split-window-vertically (&optional arg)
-  "Split current window into two windows, one above the other.
-The uppermost window gets ARG lines and the other gets the rest.
-Negative ARG means select the size of the lowermost window instead.
-With no argument, split equally or close to it.
-Both windows display the same buffer now current.
+(defun split-window-vertically (&optional size)
+  "Split selected window into two windows, one above the other.
+The upper window gets SIZE lines and the lower one gets the rest.
+SIZE negative means the lower window gets -SIZE lines and the
+upper one the rest.  With no argument, split windows equally or
+close to it.  Both windows display the same buffer, now current.
 
-If the variable `split-window-keep-point' is non-nil, both new windows
-will get the same value of point as the current window.  This is often
-more convenient for editing.  The upper window is the selected window.
+If the variable `split-window-keep-point' is non-nil, both new
+windows will get the same value of point as the selected window.
+This is often more convenient for editing.  The upper window is
+the selected window.
 
 Otherwise, we choose window starts so as to minimize the amount of
 redisplay; this is convenient on slow terminals.  The new selected
@@ -1114,77 +1126,76 @@
 window is the original one and the return value is the new, lower
 window."
   (interactive "P")
-  (let ((old-w (selected-window))
+  (let ((old-window (selected-window))
 	(old-point (point))
-	(size (and arg (prefix-numeric-value arg)))
-        (window-full-p nil)
-	new-w bottom moved)
-    (and size (< size 0) (setq size (+ (window-height) size)))
-    (setq new-w (split-window nil size))
-    (or split-window-keep-point
-	(progn
-	  (save-excursion
-	    (set-buffer (window-buffer))
-	    (goto-char (window-start))
-            (setq moved (vertical-motion (window-height)))
-	    (set-window-start new-w (point))
-	    (if (> (point) (window-point new-w))
-		(set-window-point new-w (point)))
-            (and (= moved (window-height))
-                 (progn
-                   (setq window-full-p t)
-                   (vertical-motion -1)))
-            (setq bottom (point)))
-          (and window-full-p
-               (<= bottom (point))
-               (set-window-point old-w (1- bottom)))
-	  (and window-full-p
-               (<= (window-start new-w) old-point)
-               (progn
-                 (set-window-point new-w old-point)
-                 (select-window new-w)))))
-    (split-window-save-restore-data new-w old-w)))
+	(size (and size (prefix-numeric-value size)))
+        moved-by-window-height moved new-window bottom)
+    (and size (< size 0)
+	 ;; Handle negative SIZE value.
+	 (setq size (+ (window-height) size)))
+    (setq new-window (split-window nil size))
+    (unless split-window-keep-point
+      (save-excursion
+	(set-buffer (window-buffer))
+	(goto-char (window-start))
+	(setq moved (vertical-motion (window-height)))
+	(set-window-start new-window (point))
+	(when (> (point) (window-point new-window))
+	  (set-window-point new-window (point)))
+	(when (= moved (window-height))
+	  (setq moved-by-window-height t)
+	  (vertical-motion -1))
+	(setq bottom (point)))
+      (and moved-by-window-height
+	   (<= bottom (point))
+	   (set-window-point old-window (1- bottom)))
+      (and moved-by-window-height
+	   (<= (window-start new-window) old-point)
+	   (set-window-point new-window old-point)
+	   (select-window new-window)))
+    (split-window-save-restore-data new-window old-window)))
 
 ;; This is to avoid compiler warnings.
 (defvar view-return-to-alist)
 
-(defun split-window-save-restore-data (new-w old-w)
+(defun split-window-save-restore-data (new-window old-window)
   (with-current-buffer (window-buffer)
-    (if view-mode
-	(let ((old-info (assq old-w view-return-to-alist)))
-	  (if old-info
-	      (push (cons new-w (cons (car (cdr old-info)) t))
-		    view-return-to-alist))))
-    new-w))
+    (when view-mode
+      (let ((old-info (assq old-window view-return-to-alist)))
+	(when old-info
+	  (push (cons new-window (cons (car (cdr old-info)) t))
+		view-return-to-alist))))
+    new-window))
+
+(defun split-window-horizontally (&optional size)
+  "Split selected window into two windows side by side.
+The selected window becomes the left one and gets SIZE columns.
+SIZE negative means the right window gets -SIZE lines.
 
-(defun split-window-horizontally (&optional arg)
-  "Split current window into two windows side by side.
-This window becomes the leftmost of the two, and gets ARG columns.
-Negative ARG means select the size of the rightmost window instead.
-The argument includes the width of the window's scroll bar; if there
-are no scroll bars, it includes the width of the divider column
-to the window's right, if any.  No ARG means split equally.
+SIZE includes the width of the window's scroll bar; if there are
+no scroll bars, it includes the width of the divider column to
+the window's right, if any.  SIZE omitted or nil means split
+window equally.
 
-The original, leftmost window remains selected.
-The return value is the new, rightmost window."
+The selected window remains selected.  Return the new window."
   (interactive "P")
-  (let ((old-w (selected-window))
-	(size (and arg (prefix-numeric-value arg))))
+  (let ((old-window (selected-window))
+	(size (and size (prefix-numeric-value size))))
     (and size (< size 0)
+	 ;; Handle negative SIZE value.
 	 (setq size (+ (window-width) size)))
-    (split-window-save-restore-data (split-window nil size t) old-w)))
+    (split-window-save-restore-data (split-window nil size t) old-window)))
 
 
 (defun set-window-text-height (window height)
   "Sets the height in lines of the text display area of WINDOW to HEIGHT.
-This doesn't include the mode-line (or header-line if any) or any
-partial-height lines in the text display area.
+HEIGHT doesn't include the mode line or header line, if any, or
+any partial-height lines in the text display area.
 
-If WINDOW is nil, the selected window is used.
-
-Note that the current implementation of this function cannot always set
-the height exactly, but attempts to be conservative, by allocating more
-lines than are actually needed in the case where some error may be present."
+Note that the current implementation of this function cannot
+always set the height exactly, but attempts to be conservative,
+by allocating more lines than are actually needed in the case
+where some error may be present."
   (let ((delta (- height (window-text-height window))))
     (unless (zerop delta)
       ;; Setting window-min-height to a value like 1 can lead to very
@@ -1260,15 +1271,15 @@
         (1+ (vertical-motion (buffer-size) window))))))
 
 (defun fit-window-to-buffer (&optional window max-height min-height)
-  "Make WINDOW the right height to display its contents exactly.
-If WINDOW is omitted or nil, it defaults to the selected window.
-If the optional argument MAX-HEIGHT is supplied, it is the maximum height
-  the window is allowed to be, defaulting to the frame height.
-If the optional argument MIN-HEIGHT is supplied, it is the minimum
-  height the window is allowed to be, defaulting to `window-min-height'.
-
-The heights in MAX-HEIGHT and MIN-HEIGHT include the mode-line and/or
-header-line."
+  "Adjust height of WINDOW to display its buffer's contents exactly.
+WINDOW defaults to the selected window.
+Optional argument MAX-HEIGHT specifies the maximum height of the
+window and defaults to the height of WINDOW's frame.
+Optional argument MIN-HEIGHT specifies the minimum height of the
+window and defaults to `window-min-height'.
+Both, MAX-HEIGHT and MIN-HEIGHT are specified in lines and
+include the mode line and header line, if any.
+Always return nil."
   (interactive)
 
   (when (null window)
@@ -1343,13 +1354,18 @@
 	  (setq desired-height (1+ desired-height)))))))
 
 (defun shrink-window-if-larger-than-buffer (&optional window)
-  "Shrink the WINDOW to be as small as possible to display its contents.
-If WINDOW is omitted or nil, it defaults to the selected window.
-Do not shrink to less than `window-min-height' lines.
-Do nothing if the buffer contains more lines than the present window height,
-or if some of the window's contents are scrolled out of view,
-or if shrinking this window would also shrink another window,
-or if the window is the only window of its frame."
+  "Shrink height of WINDOW if its buffer doesn't need so many lines.
+More precisely, shrink WINDOW vertically to be as small as
+possible, while still showing the full contents of its buffer.
+WINDOW defaults to the selected window.
+
+Do not shrink to less than `window-min-height' lines.  Do nothing
+if the buffer contains more lines than the present window height,
+or if some of the window's contents are scrolled out of view, or
+if shrinking this window would also shrink another window, or if
+the window is the only window of its frame.
+
+Return non-nil if the window was shrunk, nil otherwise."
   (interactive)
   (when (null window)
     (setq window (selected-window)))
@@ -1619,12 +1635,12 @@
     (mapc 'delete-window delenda)))
 
 (defun truncated-partial-width-window-p (&optional window)
-  "Non-nil if lines in WINDOW are specifically truncated due to its width.
-This returns nil if WINDOW is not a partial-width window
+  "Return non-nil if lines in WINDOW are specifically truncated due to its width.
+WINDOW defaults to the selected window.
+Return nil if WINDOW is not a partial-width window
  (regardless of the value of `truncate-lines').
 Otherwise, consult the value of `truncate-partial-width-windows'
- for the buffer shown in WINDOW.
-If WINDOW is nil, use the selected window."
+ for the buffer shown in WINDOW."
   (unless window
     (setq window (selected-window)))
   (unless (window-full-width-p window)