;;; 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
;; 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
(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.
(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))
(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)
- nil
- 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.
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)))
(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,
(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))))
(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