From 1372d04f79bde0daa3bab4b96a068baafa808e67 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Sun, 6 Sep 2026 11:21:53 +0900 Subject: [PATCH] Fix adaptive height with an inline header or footer border - extraLines() used borderLines(), which reports zero for BorderInline - Divider drawn for an inline section still takes a line, and resizeWindows() reserves it via addInline() - So adaptive height came up one line short per inline section and the list scrolled - Affects --header-lines-border, --header-border and --footer-border alike. All three set came up three lines short - Without a list border the shape normalizes to BorderTop or BorderBottom, which report a line, hence --no-list-border looked like a fix seq 10 | fzf --height=~100% --list-border \ --header-lines=1 --header-lines-border=inline Fix #4904 --- CHANGELOG.md | 2 ++ src/terminal.go | 14 +++++++++++--- test/test_layout.rb | 22 ++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index beb43563..2fbe7661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ CHANGELOG - Fixed an escape sequence split across reads being parsed as a fragment, which leaked the rest into the query (#4899) - e.g. A terminal answering the startup `DECRQM` query late left `?2004;2$y`, CTRL-UP left `5A`, and SGR mouse input left `0;1;1M` - Fixed `--tiebreak=pathname` not detecting the last path separator when the line contains a non-ASCII character before it (#4902) +- Fixed adaptive height not reserving a line for the divider of an inline header or footer border, so the list came up one line short for each of them (#4904) + - e.g. `seq 10 | fzf --height=~100% --list-border --header-lines=1 --header-lines-border=inline` - Vim plugin - fzf no longer blocks the editor, so live previews keep working while fzf is open - `fzf#run` returns an empty list when it runs fzf asynchronously. Use `sink`, `sinklist`, or `exit` to get the result diff --git a/src/terminal.go b/src/terminal.go index 640f5be8..59016476 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -1547,6 +1547,14 @@ func (t *Terminal) visibleInputLinesInList() int { // Extra number of lines needed to display fzf func (t *Terminal) extraLines() int { + // borderLines() reports zero for BorderInline, but addInline() still + // reserves a divider line for it + sectionLines := func(shape tui.BorderShape) int { + if shape == tui.BorderInline { + return 1 + } + return borderLines(shape) + } extra := 0 if !t.inputless { extra++ @@ -1562,16 +1570,16 @@ func (t *Terminal) extraLines() int { } if t.headerVisible { if t.hasHeaderWindow() { - extra += borderLines(t.headerBorderShape) + extra += sectionLines(t.headerBorderShape) } extra += len(t.header0) if w, shape := t.determineHeaderLinesShape(); w { - extra += borderLines(shape) + extra += sectionLines(shape) } extra += t.headerLines } if len(t.footer) > 0 { - extra += borderLines(t.footerBorderShape) + extra += sectionLines(t.footerBorderShape) extra += len(t.footer) } return extra diff --git a/test/test_layout.rb b/test/test_layout.rb index 9e208ba7..a9075bc1 100644 --- a/test/test_layout.rb +++ b/test/test_layout.rb @@ -882,6 +882,28 @@ class TestLayout < TestInteractive tmux.until { assert_block(block, it) } end + def test_adaptive_height_with_inline_sections + tmux.send_keys %(seq 10 | #{FZF} --height=~100% --list-border --header-lines=1 --header-lines-border=inline), :Enter + block = <<~BLOCK + ╭────── + │ 10 + │ 9 + │ 8 + │ 7 + │ 6 + │ 5 + │ 4 + │ 3 + │ > 2 + ├────── + │ 1 + ╰────── + 9/9 + > + BLOCK + tmux.until { assert_block(block, it) } + end + def test_style_full_adaptive_height tmux.send_keys %(seq 1| #{FZF} --style=full:rounded --height=~100% --header-lines=1 --info=default), :Enter block = <<~BLOCK