Subject: bug#55169: Can't combine window-min-height with window-height

From: martin rudalics <[email-masked]>
Date: Mon, 9 May 2022 09:24:52 +0200

>>> (pop-to-buffer (generate-new-buffer "*edit string*")
 >>>                  '(display-buffer-below-selected
 >>>                    (window-height . (lambda (window)
 >>>                                       (fit-window-to-buffer window nil 10)))))
 >>
 >> Sounds too complicated IMO.
 >
 > Actually a lambda is already supported, so no changes are required.

We have to find a suitable way to explain that in the manual.

 > A special case for fit-window-to-buffer, shrink-window-* and other similar
 > could be implemented only when you are sure that a `window-min-height' entry
 > is not going to be used for other purposes besides of using it as an argument
 > of a window-height entry.

You said that this is the case for 'fit-window-to-buffer' and that
function is the canonical client for a 'window-height' function.  So why
bother about the rest?

 > BTW, fit-window-to-buffer has also other arguments: MAX-WIDTH and MIN-WIDTH.
 > Would they be useful for a window-width entry?

Maybe.  But let's talk about MAX-HEIGHT first.

 >> And if we really want to, we can always add a MIN-HEIGHT argument to
 >> 'shrink-window-if-larger-than-buffer' and handle it the same way.
 >
 > This is very much needed, thanks.

See below (this should also fix the lie about the return value).

martin

(defun shrink-window-if-larger-than-buffer (&optional window min-height)
   "Shrink height of WINDOW if its buffer doesn't need so many lines.
More precisely, shrink WINDOW vertically to be as small as
possible, while still showing the full contents of its buffer.
WINDOW must be a live window and defaults to the selected one.

The optional argument MIN-HEIGHT specifies the minimum number of
lines to which WINDOW may be shrunk and defaults to
`window-min-height'.

Do nothing if the buffer contains more lines than the present
height of WINDOW, some of WINDOW's contents are scrolled out of
view, shrinking WINDOW would also shrink another window, or
WINDOW is the root window of its frame.

Return non-nil if WINDOW was shrunk, nil otherwise."
   (interactive)
   (setq window (window-normalize-window window t))
   ;; Make sure that WINDOW is vertically combined and `point-min' is
   ;; visible (for whatever reason that's needed).  The remaining issues
   ;; should be taken care of by `fit-window-to-buffer'.
   (when (and (window-combined-p window)
	     (pos-visible-in-window-p (point-min) window))
     (let ((old-height (window-pixel-height window)))
       (fit-window-to-buffer
        window (window-total-height window) nil min-height)
       (/= old-height (window-pixel-height window)))))