Skip to content

Commit d913076

Browse files
committed
Shrink terminal when tall glyphs push content off-screen
Emoji and other Unicode characters can fall back to taller fonts in Emacs, expanding line height beyond what window-body-height assumes. After enough such lines the bottom rows are pushed below the visible window area. After each redraw, check whether the last buffer position is still visible. When it is not, reduce the terminal by one row and re-render so all content fits. The adjustment is reset on window resize so the terminal reclaims full height when possible. Benchmarks show no regression (pos-visible-in-window-p is essentially free for content that fits).
1 parent ff6dc1b commit d913076

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

ghostel.el

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,9 @@ DIR is the module directory."
548548
(defvar-local ghostel--resize-timer nil
549549
"Timer for debounced SIGWINCH on alt screen.")
550550

551+
(defvar-local ghostel--height-adjustment 0
552+
"Rows subtracted from window-body-height to fit tall lines (emoji).")
553+
551554

552555
(defvar-local ghostel--last-directory nil
553556
"Last known working directory from OSC 7, used for dedup.")
@@ -1716,10 +1719,26 @@ frame after idle to improve interactive responsiveness."
17161719
(ghostel--pin-window-start)))))))
17171720

17181721
(defun ghostel--pin-window-start ()
1719-
"Pin the window so terminal row 1 stays at the top."
1722+
"Pin the window so terminal row 1 stays at the top.
1723+
When tall glyphs (emoji) cause content to overflow the window,
1724+
shrink the terminal by one row and re-render."
17201725
(let ((win (get-buffer-window)))
17211726
(when win
1722-
(set-window-start win (point-min)))))
1727+
(set-window-start win (point-min))
1728+
(when (and ghostel--term
1729+
(> (point-max) (point-min))
1730+
(not (pos-visible-in-window-p (1- (point-max)) win)))
1731+
;; Content overflows — reduce terminal by one row.
1732+
(cl-incf ghostel--height-adjustment)
1733+
(let* ((height (- (window-body-height win)
1734+
ghostel--height-adjustment))
1735+
(width (window-max-chars-per-line win)))
1736+
(when (> height 0)
1737+
(ghostel--set-size ghostel--term height width)
1738+
(when (and ghostel--process (process-live-p ghostel--process))
1739+
(set-process-window-size ghostel--process height width))
1740+
(ghostel--redraw ghostel--term ghostel-full-redraw)
1741+
(set-window-start win (point-min))))))))
17231742

17241743
(defun ghostel-force-redraw ()
17251744
"Force a full terminal redraw (for debugging)."
@@ -1738,6 +1757,7 @@ PROCESS is the shell process, WINDOWS is the list of windows."
17381757
(let* ((window (car windows))
17391758
(width (window-max-chars-per-line window))
17401759
(height (window-body-height window)))
1760+
(setq ghostel--height-adjustment 0)
17411761
(when ghostel--term
17421762
(if (ghostel--mode-enabled ghostel--term 1049)
17431763
;; Alt screen: debounce the entire resize (terminal + SIGWINCH)

0 commit comments

Comments
 (0)