From b224480a98a40c670c8ed89abd52d4216a470032 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Thu, 10 Sep 2026 23:19:38 +0900 Subject: [PATCH] Do not erase the line the prompt was on (#4918) - When the cursor is not at column 0, Init() makes space so fzf draws on the next line and the prompt line is left intact - Close() undid that: it moved up onto the prompt line before ESC[J, so the erase wiped a line fzf never wrote on - Shells repaint afterwards, so it showed as a flicker of the last prompt line. Reported on fish, also seen on bash and nushell. zsh erases the same line but repaints fast enough to hide it - Erase our own area first, then step back and restore the column, so nothing on that line is touched, RPROMPT included Fix #4913 --- src/tui/light.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tui/light.go b/src/tui/light.go index 5ce64010..4f5ec4d5 100644 --- a/src/tui/light.go +++ b/src/tui/light.go @@ -175,6 +175,7 @@ type LightRenderer struct { width int height int yoffset int + xoffset int tabstop int escDelay int fullscreen bool @@ -277,6 +278,7 @@ func (r *LightRenderer) Init() error { // increased and we're left with unwanted extra new line. if x > 0 && r.clearOnExit { r.upOneLine = true + r.xoffset = x r.makeSpace() } // We assume that --no-clear is used for repetitive relaunching of fzf. @@ -1178,10 +1180,13 @@ func (r *LightRenderer) Close() { r.rmcup() } else { r.origin() + // Erase our own area first, then step back onto the line the + // prompt was on, so nothing on that line is touched + r.csi("J") if r.upOneLine { r.csi("A") + r.csi(fmt.Sprintf("%dG", r.xoffset+1)) } - r.csi("J") } } else if !r.fullscreen { r.stderr("\x1b8") // DECRC: restore cursor position