From 56be41218c0bd457e3411f5d1f83892fd85d6f00 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Tue, 21 Apr 2026 18:41:48 +0900 Subject: [PATCH] Redraw when change-footer changes line count Mirror of the earlier change-header fix. The inline footer slot's row budget depends on footer content length, but resizeIfNeeded() tolerates a shorter-than-wanted inline window, so extra lines get clipped. Drive a redraw on length change to re-run the layout. --- src/terminal.go | 11 +++++++++-- test/test_layout.rb | 14 +++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/terminal.go b/src/terminal.go index b7d83577..3ff4cf72 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -1816,14 +1816,16 @@ func (t *Terminal) changeHeader(header string) bool { return needFullRedraw } -func (t *Terminal) changeFooter(footer string) { +func (t *Terminal) changeFooter(footer string) bool { var lines []string if len(footer) > 0 { lines = strings.Split(strings.TrimSuffix(footer, "\n"), "\n") } + needFullRedraw := len(t.footer) != len(lines) t.footer = lines t.clickFooterLine = 0 t.clickFooterColumn = 0 + return needFullRedraw } // UpdateHeader updates the header @@ -6796,7 +6798,12 @@ func (t *Terminal) Loop() error { }) case actChangeFooter, actTransformFooter, actBgTransformFooter: capture(false, func(footer string) { - t.changeFooter(footer) + if t.changeFooter(footer) && t.footerBorderShape == tui.BorderInline { + // resizeIfNeeded() tolerates a shorter-than-wanted inline + // window, so a length change can leave the inline slot + // stale. Force a redraw to re-run the layout. + req(reqRedraw) + } req(reqFooter) }) case actChangeHeaderLabel, actTransformHeaderLabel, actBgTransformHeaderLabel: diff --git a/test/test_layout.rb b/test/test_layout.rb index 429de28d..e968226b 100644 --- a/test/test_layout.rb +++ b/test/test_layout.rb @@ -1534,12 +1534,24 @@ class TestLayout < TestInteractive def test_inline_change_header_grows_slot tmux.send_keys %(seq 5 | #{FZF} --style full --header-lines 1 --header-border inline --bind space:change-header:tada), :Enter tmux.until { |lines| lines.any_include?(/\A│\s+1\s+│\z/) } - tmux.send_keys ' ' + tmux.send_keys :Space tmux.until do |lines| lines.any_include?(/\A│\s+1\s+│\z/) && lines.any_include?(/\A│\s+tada\s+│\z/) end end + # Regression: with --footer-border=inline, change-footer that grows the + # footer line count left the inline slot sized for the old length, so + # extra lines were clipped. + def test_inline_change_footer_grows_slot + tmux.send_keys %(seq 5 | #{FZF} --style full --footer-border inline --footer one --bind $'space:change-footer:one\\ntwo'), :Enter + tmux.until { |lines| lines.any_include?(/\A│\s+one\s+│\z/) } + tmux.send_keys :Space + tmux.until do |lines| + lines.any_include?(/\A│\s+one\s+│\z/) && lines.any_include?(/\A│\s+two\s+│\z/) + end + end + # Invalid inline combinations must be rejected at startup. def test_inline_rejected_on_unsupported_options [