;;; window.el --- GNU Emacs window commands aside from those written in C
-;; Copyright (C) 1985, 1989, 1992, 1993, 1994, 2000, 2001
+;; Copyright (C) 1985, 1989, 1992, 1993, 1994, 2000, 2001, 2002, 2004
;; Free Software Foundation, Inc.
;; Maintainer: FSF
(defmacro save-selected-window (&rest body)
"Execute BODY, then select the window that was selected before BODY.
-However, if that window has become dead, don't get an error,
-just refrain from switching to it."
- `(let ((save-selected-window-window (selected-window)))
+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."
+ `(let ((save-selected-window-window (selected-window))
+ (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)))))
(eq base-window
(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 . HORISONTAL) 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
+bars (top, bottom, or nil)."
+ (let ((vert (nth 2 (window-scroll-bars window)))
+ (hor nil))
+ (when (or (eq vert t) (eq hor t))
+ (let ((fcsb (frame-current-scroll-bars
+ (window-frame (or window (selected-window))))))
+ (if (eq vert t)
+ (setq vert (car fcsb)))
+ (if (eq hor t)
+ (setq hor (cdr fcsb)))))
+ (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.
(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."
- (save-selected-window
- (when window (select-window window))
- (or (and (not (eq window (frame-first-window)))
- (= (car (window-edges))
- (car (window-edges (previous-window)))))
- (= (car (window-edges))
- (car (window-edges (next-window)))))))
+ (with-selected-window (or window (selected-window))
+ (let ((edges (window-edges)))
+ (or (= (nth 2 edges) (nth 2 (window-edges (previous-window))))
+ (= (nth 0 edges) (nth 0 (window-edges (next-window))))))))
+
(defun balance-windows ()
"Make all visible windows the same height (approximately)."
(if newbot
(setq newsizes
(cons (cons w (* level-size (- newbot newtop)))
- newsizes)))))))
+ newsizes))))))
'nomini)
;; Make walk-windows start with the topmost window.
(select-window (previous-window (frame-first-window (selected-frame))))
nil t)
(unless (= (window-height) newsize)
(setq done nil))))))
- 'nomini)))))
+ 'nomini))))))
\f
-;;; I think this should be the default; I think people will prefer it--rms.
+;; I think this should be the default; I think people will prefer it--rms.
(defcustom split-window-keep-point t
"*If non-nil, split windows keeps the original point in both children.
This is often more convenient for editing.
(defvar view-return-to-alist)
(defun split-window-save-restore-data (new-w old-w)
- (save-excursion
- (set-buffer (window-buffer))
+ (with-current-buffer (window-buffer)
(if view-mode
(let ((old-info (assq old-w view-return-to-alist)))
- (setq view-return-to-alist
- (cons (cons new-w (cons (and old-info (car (cdr old-info))) t))
- view-return-to-alist))))
+ (if old-info
+ (push (cons new-w (cons (car (cdr old-info)) t))
+ view-return-to-alist))))
new-w))
(defun split-window-horizontally (&optional arg)
(not (eq frame (window-frame mini-window)))
(< (nth 3 edges)
(nth 1 (window-edges mini-window)))
- (> (nth 1 edges)
+ (> (nth 1 edges)
(frame-parameter frame 'menu-bar-lines))))))
(fit-window-to-buffer window (window-height window)))))
(defun kill-buffer-and-window ()
"Kill the current buffer and delete the selected window."
(interactive)
- (if (yes-or-no-p (format "Kill buffer `%s'? " (buffer-name)))
- (let ((buffer (current-buffer)))
- (delete-window (selected-window))
- (kill-buffer buffer))
- (error "Aborted")))
+ (let ((window-to-delete (selected-window))
+ (delete-window-hook (lambda ()
+ (condition-case nil
+ (delete-window)
+ (error nil)))))
+ (add-hook 'kill-buffer-hook delete-window-hook t t)
+ (if (kill-buffer (current-buffer))
+ ;; If `delete-window' failed before, we rerun it to regenerate
+ ;; the error so it can be seen in the minibuffer.
+ (when (eq (selected-window) window-to-delete)
+ (delete-window))
+ (remove-hook 'kill-buffer-hook delete-window-hook t))))
(defun quit-window (&optional kill window)
"Quit the current buffer. Bury it, and maybe delete the selected frame.
(and window (not window-handled) (not window-solitary)
(delete-window window))))
+(defun handle-select-window (event)
+ "Handle select-window events."
+ (interactive "e")
+ (let ((window (posn-window (event-start event))))
+ (if (and (window-live-p window)
+ (or (not (window-minibuffer-p window))
+ (minibuffer-window-active-p window)))
+ (select-window window))))
+
(define-key ctl-x-map "2" 'split-window-vertically)
(define-key ctl-x-map "3" 'split-window-horizontally)
(define-key ctl-x-map "}" 'enlarge-window-horizontally)
(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
;;; window.el ends here