(tex-command-end): New variable.
[bpt/emacs.git] / lisp / window.el
index a47a1ea..bd3727c 100644 (file)
@@ -198,6 +198,9 @@ new mode line."
                  (select-window new-w)))))
     (split-window-save-restore-data new-w old-w)))
 
+;; This is to avoid compiler warnings.
+(defvar view-return-to-alist)
+
 (defun split-window-save-restore-data (new-w old-w)
   (save-excursion
     (set-buffer (window-buffer))
@@ -239,57 +242,45 @@ or if the window is not the full width of the frame,
 or if the window is the only window of its frame."
   (interactive)
   (or window (setq window (selected-window)))
-  (save-excursion
-    (set-buffer (window-buffer window))
-    (let* ((w (selected-window))       ;save-window-excursion can't win
-          (buffer-file-name buffer-file-name)
-          (p (point))
-          (n 0)
-          (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))))))
-          (buffer-read-only nil)
-          (modified (buffer-modified-p))
-          (buffer (current-buffer))
-          (params (frame-parameters (window-frame window)))
-          (mini (cdr (assq 'minibuffer params)))
-          (edges (window-edges (selected-window))))
-      (if (and (< 1 (let ((frame (selected-frame)))
-                     (select-frame (window-frame window))
-                     (unwind-protect
-                         (count-windows)
-                       (select-frame frame))))
-              (= (window-width window) (frame-width (window-frame window)))
-              (pos-visible-in-window-p (point-min) window)
-              (not (eq mini 'only))
-              (or (not mini)
-                  (< (nth 3 edges)
-                     (nth 1 (window-edges mini)))
-                  (> (nth 1 edges)
-                     (cdr (assq 'menu-bar-lines params)))))
-         (unwind-protect
-             (progn
-               (select-window (or window w))
-               (goto-char (point-min))
-               (while (pos-visible-in-window-p
-                       (- (point-max)
-                          (if ignore-final-newline 1 0)))
-                 ;; defeat file locking... don't try this at home, kids!
-                 (setq buffer-file-name nil)
-                 (insert ?\n) (setq n (1+ n)))
-               (if (> n 0)
-                   (shrink-window (min (1- n)
-                                       (- (window-height)
-                                          window-min-height)))))
-           (delete-region (point-min) (point))
-           (set-buffer-modified-p modified)
-           (goto-char p)
-           (select-window w)
-           ;; Make sure we unbind buffer-read-only
-           ;; with the proper current buffer.
-           (set-buffer buffer))))))
+  (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))))))
+        (params (frame-parameters (window-frame window)))
+        (mini (cdr (assq 'minibuffer params)))
+        (edges (window-edges (selected-window)))
+        text-height)
+    (if (and (< 1 (save-selected-window
+                   (select-window window)
+                   (count-windows)))
+            (= (window-width window) (frame-width (window-frame window)))
+            (pos-visible-in-window-p (point-min) window)
+            (not (eq mini 'only))
+            (or (not mini)
+                (< (nth 3 edges)
+                   (nth 1 (window-edges mini)))
+                (> (nth 1 edges)
+                   (cdr (assq 'menu-bar-lines params)))))
+       (save-selected-window
+         (select-window window)
+         (let (result height)
+           (save-excursion
+             (set-buffer (window-buffer window))
+             (goto-char (point-min))
+             (setq result
+                   (compute-motion (point-min) '(0 . 0)
+                                   (- (point-max)
+                                      (if ignore-final-newline 1 0))
+                                   (cons 0 (window-height))
+                                   (window-width) nil
+                                   window))
+             ;; Get number of screen lines that the text needs.
+             (setq text-height (+ 1 (nth 2 result)))
+             ;; Shrink down to that, or as far as we can go.
+             (if (> (window-height) (1+ text-height))
+                 (shrink-window (- (window-height)
+                                   (max (1+ text-height) window-min-height))))))))))
 
 (defun kill-buffer-and-window ()
   "Kill the current buffer and delete the selected window."
@@ -300,6 +291,53 @@ or if the window is the only window of its frame."
        (kill-buffer buffer))
     (error "Aborted")))
 
+(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.)
+With a prefix argument, kill the buffer instead.
+
+Noninteractively, if KILL is non-nil, then kill the current buffer,
+otherwise bury it.
+
+If WINDOW is non-nil, it specifies a window; we delete that window,
+and the buffer that is killed or buried is the one in that window."
+  (interactive "P")
+  (let ((buffer (window-buffer window))
+       (frame (window-frame (or window (selected-window))))
+       (window-solitary
+        (save-selected-window
+          (if window
+              (select-window window))
+          (one-window-p t)))
+       window-handled)
+
+    (save-selected-window
+      (if window
+         (select-window window))
+      (or (window-minibuffer-p)
+         (window-dedicated-p (selected-window))
+         (switch-to-buffer (other-buffer))))
+
+    ;; Get rid of the frame, if it has just one dedicated window
+    ;; and other visible frames exist.
+    (and (or (window-minibuffer-p) (window-dedicated-p window))
+        (delq frame (visible-frame-list))
+        window-solitary
+        (if (and (eq default-minibuffer-frame frame)
+                 (= 1 (length (minibuffer-frame-list))))
+            (setq window nil)
+          (delete-frame frame)
+          (setq window-handled t)))
+
+    ;; Deal with the buffer.
+    (if kill
+       (kill-buffer buffer)
+      (bury-buffer buffer))
+
+    ;; Maybe get rid of the window.
+    (and window (not window-handled) (not window-solitary)
+        (delete-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)