aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2008-12-11 17:17:44 +0000
committerMartin Rudalics2008-12-11 17:17:44 +0000
commitf7baca2087406d3d45d2662a8b3fca43f938d537 (patch)
treeb4bfbabf366e9725b2b816f9c27414dfb077599c
parent8ec71e2341172ad01138c2b5c80623eb99a35549 (diff)
downloademacs-f7baca2087406d3d45d2662a8b3fca43f938d537.tar.gz
emacs-f7baca2087406d3d45d2662a8b3fca43f938d537.zip
(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)
-rw-r--r--lisp/window.el162
1 files changed, 88 insertions, 74 deletions
diff --git a/lisp/window.el b/lisp/window.el
index 6373185ffaa..6b1cc9a2d4e 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -1294,86 +1294,100 @@ in some window."
1294 1294
1295(defun fit-window-to-buffer (&optional window max-height min-height) 1295(defun fit-window-to-buffer (&optional window max-height min-height)
1296 "Adjust height of WINDOW to display its buffer's contents exactly. 1296 "Adjust height of WINDOW to display its buffer's contents exactly.
1297WINDOW defaults to the selected window. 1297WINDOW defaults to the selected window. Return nil.
1298Optional argument MAX-HEIGHT specifies the maximum height of the 1298Optional argument MAX-HEIGHT specifies the maximum height of the
1299window and defaults to the height of WINDOW's frame. 1299window and defaults to the maximum permissible height of a window
1300on WINDOW's frame.
1300Optional argument MIN-HEIGHT specifies the minimum height of the 1301Optional argument MIN-HEIGHT specifies the minimum height of the
1301window and defaults to `window-min-height'. 1302window and defaults to `window-min-height'.
1302Both, MAX-HEIGHT and MIN-HEIGHT are specified in lines and 1303Both, MAX-HEIGHT and MIN-HEIGHT are specified in lines and
1303include the mode line and header line, if any. 1304include the mode line and header line, if any.
1304Always return nil."
1305 (interactive)
1306 1305
1307 (when (null window) 1306Caution: This function can delete WINDOW and/or other windows
1308 (setq window (selected-window))) 1307when their height shrinks to less than MIN-HEIGHT."
1309 (when (null max-height) 1308 (interactive)
1310 (setq max-height (frame-height (window-frame window)))) 1309 ;; Do all the work in WINDOW and its buffer and restore the selected
1311 1310 ;; window and the current buffer when we're done.
1312 (let* ((buf 1311 (let ((old-buffer (current-buffer)))
1313 ;; Buffer that is displayed in WINDOW 1312 (with-selected-window (or window (setq window (selected-window)))
1314 (window-buffer window)) 1313 (set-buffer (window-buffer))
1315 (window-height 1314 ;; Use `condition-case' to handle any fixed-size windows and other
1316 ;; The current height of WINDOW 1315 ;; pitfalls nearby.
1317 (window-height window)) 1316 (condition-case nil
1318 (desired-height 1317 (let* (;; MIN-HEIGHT must not be less than 1 and defaults to
1319 ;; The height necessary to show the buffer displayed by WINDOW 1318 ;; `window-min-height'.
1320 ;; (`count-screen-lines' always works on the current buffer). 1319 (min-height (max (or min-height window-min-height) 1))
1321 (with-current-buffer buf 1320 (max-window-height
1322 (+ (count-screen-lines) 1321 ;; Maximum height of any window on this frame.
1323 ;; If the buffer is empty, (count-screen-lines) is 1322 (min (window-height (frame-root-window)) (frame-height)))
1324 ;; zero. But, even in that case, we need one text line 1323 ;; MAX-HEIGHT must not be larger than max-window-height and
1325 ;; for cursor. 1324 ;; defaults to max-window-height.
1326 (if (= (point-min) (point-max)) 1325 (max-height
1327 1 0) 1326 (min (or max-height max-window-height) max-window-height))
1328 ;; For non-minibuffers, count the mode-line, if any 1327 (desired-height
1329 (if (and (not (window-minibuffer-p window)) 1328 ;; The height necessary to show all of WINDOW's buffer,
1330 mode-line-format) 1329 ;; constrained by MIN-HEIGHT and MAX-HEIGHT.
1331 1 0) 1330 (max
1332 ;; Count the header-line, if any 1331 (min
1333 (if header-line-format 1 0)))) 1332 ;; For an empty buffer `count-screen-lines' returns zero.
1334 (delta 1333 ;; Even in that case we need one line for the cursor.
1335 ;; Calculate how much the window height has to change to show 1334 (+ (max (count-screen-lines) 1)
1336 ;; desired-height lines, constrained by MIN-HEIGHT and MAX-HEIGHT. 1335 ;; For non-minibuffers count the mode line, if any.
1337 (- (max (min desired-height max-height) 1336 (if (and (not (window-minibuffer-p)) mode-line-format)
1338 (or min-height window-min-height)) 1337 1 0)
1339 window-height))) 1338 ;; Count the header line, if any.
1340 1339 (if header-line-format 1 0))
1341 ;; Don't try to redisplay with the cursor at the end 1340 max-height)
1342 ;; on its own line--that would force a scroll and spoil things. 1341 min-height))
1343 (when (with-current-buffer buf 1342 (delta
1344 (and (eobp) (bolp) (not (bobp)))) 1343 ;; How much the window height has to change.
1345 (set-window-point window (1- (window-point window)))) 1344 (if (= (window-height) (window-height (frame-root-window)))
1346 1345 ;; Don't try to resize a full-height window.
1347 (save-selected-window 1346 0
1348 (select-window window 'norecord) 1347 (- desired-height (window-height))))
1349 1348 ;; Do something reasonable so `enlarge-window' can make
1350 ;; Adjust WINDOW to the nominally correct size (which may actually 1349 ;; windows as small as MIN-HEIGHT.
1351 ;; be slightly off because of variable height text, etc). 1350 (window-min-height (min min-height window-min-height)))
1352 (unless (zerop delta) 1351 ;; Don't try to redisplay with the cursor at the end on its
1353 (enlarge-window delta)) 1352 ;; own line--that would force a scroll and spoil things.
1354 1353 (when (and (eobp) (bolp) (not (bobp)))
1355 ;; Check if the last line is surely fully visible. If not, 1354 (set-window-point window (1- (window-point))))
1356 ;; enlarge the window. 1355 ;; Adjust WINDOW's height to the nominally correct one
1357 (let ((end (with-current-buffer buf 1356 ;; (which may actually be slightly off because of variable
1358 (save-excursion 1357 ;; height text, etc).
1359 (goto-char (point-max)) 1358 (unless (zerop delta)
1360 (when (and (bolp) (not (bobp))) 1359 (enlarge-window delta))
1361 ;; Don't include final newline 1360 ;; `enlarge-window' might have deleted WINDOW, so make sure
1362 (backward-char 1)) 1361 ;; WINDOW's still alive for the remainder of this.
1363 (when truncate-lines 1362 ;; Note: Deleting WINDOW is clearly counter-intuitive in
1364 ;; If line-wrapping is turned off, test the 1363 ;; this context, but we can't do much about it given the
1365 ;; beginning of the last line for visibility 1364 ;; current semantics of `enlarge-window'.
1366 ;; instead of the end, as the end of the line 1365 (when (window-live-p window)
1367 ;; could be invisible by virtue of extending past 1366 ;; Check if the last line is surely fully visible. If
1368 ;; the edge of the window. 1367 ;; not, enlarge the window.
1369 (forward-line 0)) 1368 (let ((end (save-excursion
1370 (point))))) 1369 (goto-char (point-max))
1371 (set-window-vscroll window 0) 1370 (when (and (bolp) (not (bobp)))
1372 (while (and (< desired-height max-height) 1371 ;; Don't include final newline.
1373 (= desired-height (window-height window)) 1372 (backward-char 1))
1374 (not (pos-visible-in-window-p end window))) 1373 (when truncate-lines
1375 (enlarge-window 1) 1374 ;; If line-wrapping is turned off, test the
1376 (setq desired-height (1+ desired-height))))))) 1375 ;; beginning of the last line for
1376 ;; visibility instead of the end, as the
1377 ;; end of the line could be invisible by
1378 ;; virtue of extending past the edge of the
1379 ;; window.
1380 (forward-line 0))
1381 (point))))
1382 (set-window-vscroll window 0)
1383 (while (and (< desired-height max-height)
1384 (= desired-height (window-height))
1385 (not (pos-visible-in-window-p end)))
1386 (enlarge-window 1)
1387 (setq desired-height (1+ desired-height))))))
1388 (error nil)))
1389 (when (buffer-live-p old-buffer)
1390 (set-buffer old-buffer))))
1377 1391
1378(defun window-safely-shrinkable-p (&optional window) 1392(defun window-safely-shrinkable-p (&optional window)
1379 "Return t if WINDOW can be shrunk without shrinking other windows. 1393 "Return t if WINDOW can be shrunk without shrinking other windows.