(vc-svn-registered): Catch all errors.
[bpt/emacs.git] / lisp / window.el
index 96bfc8b..48dd0f4 100644 (file)
@@ -1,7 +1,7 @@
 ;;; window.el --- GNU Emacs window commands aside from those written in C
 
-;; Copyright (C) 1985, 1989, 1992, 1993, 1994, 2000, 2001, 2002, 2004
-;;  Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1989, 1992, 1993, 1994, 2000, 2001, 2002,
+;;   2003, 2004, 2005 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: internal
@@ -20,8 +20,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
 
 ;;; Code:
 
+(defvar window-size-fixed nil
+ "*Non-nil in a buffer means windows displaying the buffer are fixed-size.
+If the value is `height', then only the window's height is fixed.
+If the value is `width', then only the window's width is fixed.
+Any other non-nil value fixes both the width and the height.
+Emacs won't change the size of any window displaying that buffer,
+unless you explicitly change the size, or Emacs has no other choice.")
+(make-variable-buffer-local 'window-size-fixed)
+
 (defmacro save-selected-window (&rest body)
   "Execute BODY, then select the window that was selected before BODY.
-Also restore the selected window of each frame as it was at the start
-of this construct.
-However, if a window has become dead, don't get an error,
-just refrain from reselecting it.
-Return the value of the last form in BODY."
+The value returned is the value of the last form in BODY.
+
+This macro saves and restores the current buffer, since otherwise
+its normal operation could potentially make a different
+buffer current.  It does not alter the buffer list ordering.
+
+This macro saves and restores the selected window, as well as
+the selected window in each frame.  If the previously selected
+window of some frame is no longer live at the end of BODY, that
+frame's selected window is left alone.  If the selected window is
+no longer live, then whatever window is selected at the end of
+BODY remains selected."
   `(let ((save-selected-window-window (selected-window))
         ;; It is necessary to save all of these, because calling
         ;; select-window changes frame-selected-window for whatever
@@ -43,14 +59,15 @@ Return the value of the last form in BODY."
         (save-selected-window-alist
          (mapcar (lambda (frame) (list frame (frame-selected-window frame)))
                  (frame-list))))
-     (unwind-protect
-        (progn ,@body)
-       (dolist (elt save-selected-window-alist)
-        (and (frame-live-p (car elt))
-             (window-live-p (cadr elt))
-             (set-frame-selected-window (car elt) (cadr elt))))
-       (if (window-live-p save-selected-window-window)
-          (select-window save-selected-window-window)))))
+     (save-current-buffer
+       (unwind-protect
+          (progn ,@body)
+        (dolist (elt save-selected-window-alist)
+          (and (frame-live-p (car elt))
+               (window-live-p (cadr elt))
+               (set-frame-selected-window (car elt) (cadr elt))))
+        (if (window-live-p save-selected-window-window)
+            (select-window save-selected-window-window))))))
 
 (defun window-body-height (&optional window)
   "Return number of lines in window WINDOW for actual buffer text.
@@ -83,9 +100,9 @@ If ALL-FRAMES is anything else, count only the selected frame."
 
 (defun window-current-scroll-bars (&optional window)
   "Return the current scroll-bar settings in window WINDOW.
-Value is a cons (VERTICAL . HORISONTAL) where VERTICAL specifies the
+Value is a cons (VERTICAL . HORIZONTAL) where VERTICAL specifies the
 current location of the vertical scroll-bars (left, right, or nil),
-and HORISONTAL specifies the current location of the horisontal scroll
+and HORIZONTAL specifies the current location of the horizontal scroll
 bars (top, bottom, or nil)."
   (let ((vert (nth 2 (window-scroll-bars window)))
        (hor nil))
@@ -175,6 +192,18 @@ Anything else means restrict to the selected frame."
 
 (defalias 'some-window 'get-window-with-predicate)
 
+;; This should probably be written in C (i.e., without using `walk-windows').
+(defun get-buffer-window-list (buffer &optional minibuf frame)
+  "Return list of all windows displaying BUFFER, or nil if none.
+BUFFER can be a buffer or a buffer name.
+See `walk-windows' for the meaning of MINIBUF and FRAME."
+  (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows)
+    (walk-windows (function (lambda (window)
+                             (if (eq (window-buffer window) buffer)
+                                 (setq windows (cons window windows)))))
+                 minibuf frame)
+    windows))
+
 (defun minibuffer-window-active-p (window)
   "Return t if WINDOW (a minibuffer window) is now active."
   (eq window (active-minibuffer-window)))
@@ -397,20 +426,13 @@ lines than are actually needed in the case where some error may be present."
 
 (defun window-buffer-height (window)
   "Return the height (in screen lines) of the buffer that WINDOW is displaying."
-  (save-excursion
-    (set-buffer (window-buffer window))
-    (goto-char (point-min))
-    (let ((ignore-final-newline
-           ;; If buffer ends with a newline, ignore it when counting height
-           ;; unless point is after it.
-           (and (not (eobp)) (eq ?\n (char-after (1- (point-max)))))))
-      (+ 1 (nth 2 (compute-motion (point-min)
-                                  '(0 . 0)
-                                  (- (point-max) (if ignore-final-newline 1 0))
-                                  (cons 0 100000000)
-                                  (window-width window)
-                                  nil
-                                  window))))))
+  (with-current-buffer (window-buffer window)
+    (max 1
+        (count-screen-lines (point-min) (point-max)
+                            ;; If buffer ends with a newline, ignore it when
+                            ;; counting height unless point is after it.
+                            (eobp)
+                            window))))
 
 (defun count-screen-lines (&optional beg end count-final-newline window)
   "Return the number of screen lines in the region.
@@ -540,9 +562,8 @@ 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.
-Return non-nil if the window was shrunk."
+or if shrinking this window would also shrink another window,
+or if the window is the only window of its frame."
   (interactive)
   (when (null window)
     (setq window (selected-window)))
@@ -581,7 +602,7 @@ Return non-nil if the window was shrunk."
 
 (defun quit-window (&optional kill window)
   "Quit the current buffer.  Bury it, and maybe delete the selected frame.
-\(The frame is deleted if it is contains a dedicated window for the buffer.)
+\(The frame is deleted if it contains a dedicated window for the buffer.)
 With a prefix argument, kill the buffer instead.
 
 Noninteractively, if KILL is non-nil, then kill the current buffer,
@@ -631,6 +652,12 @@ and the buffer that is killed or buried is the one in that window."
   (interactive "e")
   (let ((window (posn-window (event-start event))))
     (if (and (window-live-p window)
+            ;; Don't switch if we're currently in the minibuffer.
+            ;; This tries to work around problems where the minibuffer gets
+            ;; unselected unexpectedly, and where you then have to move
+            ;; your mouse all the way down to the minibuffer to select it.
+            (not (window-minibuffer-p (selected-window)))
+            ;; Don't switch to a minibuffer window unless it's active.
             (or (not (window-minibuffer-p window))
                 (minibuffer-window-active-p window)))
        (select-window window))))
@@ -643,5 +670,5 @@ and the buffer that is killed or buried is the one in that window."
 (define-key ctl-x-map "+" 'balance-windows)
 (define-key ctl-x-4-map "0" 'kill-buffer-and-window)
 
-;;; arch-tag: b508dfcc-c353-4c37-89fa-e773fe10cea9
+;; arch-tag: b508dfcc-c353-4c37-89fa-e773fe10cea9
 ;;; window.el ends here