emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] emacs/lisp window.el


From: Martin Rudalics
Subject: [Emacs-diffs] emacs/lisp window.el
Date: Thu, 11 Dec 2008 17:17:45 +0000

CVSROOT:        /sources/emacs
Module name:    emacs
Changes by:     Martin Rudalics <m061211>       08/12/11 17:17:45

Modified files:
        lisp           : window.el 

Log message:
        (fit-window-to-buffer): Use with-selected-window and
        condition-case.  Do not delete more windows than necessary in
        the shrinking (delta < 0) case.  Do not raise an error when the
        containing frame is too small to show all of buffer.  (Bug#1488)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/emacs/lisp/window.el?cvsroot=emacs&r1=1.169&r2=1.170

Patches:
Index: window.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/window.el,v
retrieving revision 1.169
retrieving revision 1.170
diff -u -b -r1.169 -r1.170
--- window.el   27 Nov 2008 13:19:36 -0000      1.169
+++ window.el   11 Dec 2008 17:17:44 -0000      1.170
@@ -1294,86 +1294,100 @@
 
 (defun fit-window-to-buffer (&optional window max-height min-height)
   "Adjust height of WINDOW to display its buffer's contents exactly.
-WINDOW defaults to the selected window.
+WINDOW defaults to the selected window.  Return nil.
 Optional argument MAX-HEIGHT specifies the maximum height of the
-window and defaults to the height of WINDOW's frame.
+window and defaults to the maximum permissible height of a window
+on 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)
-    (setq window (selected-window)))
-  (when (null max-height)
-    (setq max-height (frame-height (window-frame window))))
 
-  (let* ((buf
-         ;; Buffer that is displayed in WINDOW
-         (window-buffer window))
-        (window-height
-         ;; The current height of WINDOW
-         (window-height window))
+Caution: This function can delete WINDOW and/or other windows
+when their height shrinks to less than MIN-HEIGHT."
+  (interactive)
+  ;; Do all the work in WINDOW and its buffer and restore the selected
+  ;; window and the current buffer when we're done.
+  (let ((old-buffer (current-buffer)))
+    (with-selected-window (or window (setq window (selected-window)))
+      (set-buffer (window-buffer))
+      ;; Use `condition-case' to handle any fixed-size windows and other
+      ;; pitfalls nearby.
+      (condition-case nil
+         (let* (;; MIN-HEIGHT must not be less than 1 and defaults to
+                ;; `window-min-height'.
+                (min-height (max (or min-height window-min-height) 1))
+                (max-window-height
+                 ;; Maximum height of any window on this frame.
+                 (min (window-height (frame-root-window)) (frame-height)))
+                ;; MAX-HEIGHT must not be larger than max-window-height and
+                ;; defaults to max-window-height.
+                (max-height
+                 (min (or max-height max-window-height) max-window-height))
         (desired-height
-         ;; The height necessary to show the buffer displayed by WINDOW
-         ;; (`count-screen-lines' always works on the current buffer).
-         (with-current-buffer buf
-           (+ (count-screen-lines)
-              ;; If the buffer is empty, (count-screen-lines) is
-              ;; zero.  But, even in that case, we need one text line
-              ;; for cursor.
-              (if (= (point-min) (point-max))
-                  1 0)
-              ;; For non-minibuffers, count the mode-line, if any
-              (if (and (not (window-minibuffer-p window))
-                       mode-line-format)
+                 ;; The height necessary to show all of WINDOW's buffer,
+                 ;; constrained by MIN-HEIGHT and MAX-HEIGHT.
+                 (max
+                  (min
+                   ;; For an empty buffer `count-screen-lines' returns zero.
+                   ;; Even in that case we need one line for the cursor.
+                   (+ (max (count-screen-lines) 1)
+                      ;; For non-minibuffers count the mode line, if any.
+                      (if (and (not (window-minibuffer-p)) mode-line-format)
                   1 0)
-              ;; Count the header-line, if any
-              (if header-line-format 1 0))))
+                      ;; Count the header line, if any.
+                      (if header-line-format 1 0))
+                   max-height)
+                  min-height))
         (delta
-         ;; Calculate how much the window height has to change to show
-         ;; desired-height lines, constrained by MIN-HEIGHT and MAX-HEIGHT.
-         (- (max (min desired-height max-height)
-                 (or min-height window-min-height))
-            window-height)))
-
-    ;; Don't try to redisplay with the cursor at the end
-    ;; on its own line--that would force a scroll and spoil things.
-    (when (with-current-buffer buf
-           (and (eobp) (bolp) (not (bobp))))
-      (set-window-point window (1- (window-point window))))
-
-    (save-selected-window
-      (select-window window 'norecord)
-
-      ;; Adjust WINDOW to the nominally correct size (which may actually
-      ;; be slightly off because of variable height text, etc).
+                 ;; How much the window height has to change.
+                 (if (= (window-height) (window-height (frame-root-window)))
+                     ;; Don't try to resize a full-height window.
+                     0
+                   (- desired-height (window-height))))
+                ;; Do something reasonable so `enlarge-window' can make
+                ;; windows as small as MIN-HEIGHT.
+                (window-min-height (min min-height window-min-height)))
+           ;; Don't try to redisplay with the cursor at the end on its
+           ;; own line--that would force a scroll and spoil things.
+           (when (and (eobp) (bolp) (not (bobp)))
+             (set-window-point window (1- (window-point))))
+           ;; Adjust WINDOW's height to the nominally correct one
+           ;; (which may actually be slightly off because of variable
+           ;; height text, etc).
       (unless (zerop delta)
        (enlarge-window delta))
-
-      ;; Check if the last line is surely fully visible.  If not,
-      ;; enlarge the window.
-      (let ((end (with-current-buffer buf
-                  (save-excursion
+           ;; `enlarge-window' might have deleted WINDOW, so make sure
+           ;; WINDOW's still alive for the remainder of this.
+           ;; Note: Deleting WINDOW is clearly counter-intuitive in
+           ;; this context, but we can't do much about it given the
+           ;; current semantics of `enlarge-window'.
+           (when (window-live-p window)
+             ;; Check if the last line is surely fully visible.  If
+             ;; not, enlarge the window.
+             (let ((end (save-excursion
                     (goto-char (point-max))
                     (when (and (bolp) (not (bobp)))
-                      ;; Don't include final newline
+                            ;; Don't include final newline.
                       (backward-char 1))
                     (when truncate-lines
                       ;; If line-wrapping is turned off, test the
-                      ;; beginning of the last line for visibility
-                      ;; instead of the end, as the end of the line
-                      ;; could be invisible by virtue of extending past
-                      ;; the edge of the window.
+                            ;; beginning of the last line for
+                            ;; visibility instead of the end, as the
+                            ;; end of the line could be invisible by
+                            ;; virtue of extending past the edge of the
+                            ;; window.
                       (forward-line 0))
-                    (point)))))
+                          (point))))
        (set-window-vscroll window 0)
        (while (and (< desired-height max-height)
-                   (= desired-height (window-height window))
-                   (not (pos-visible-in-window-p end window)))
+                           (= desired-height (window-height))
+                           (not (pos-visible-in-window-p end)))
          (enlarge-window 1)
-         (setq desired-height (1+ desired-height)))))))
+                 (setq desired-height (1+ desired-height))))))
+       (error nil)))
+    (when (buffer-live-p old-buffer)
+      (set-buffer old-buffer))))
 
 (defun window-safely-shrinkable-p (&optional window)
   "Return t if WINDOW can be shrunk without shrinking other windows.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]