From 263f1b35de01cb04a6c2cbc635ae0258f8401a3f Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 28 Sep 2024 09:14:20 +0200 Subject: [PATCH] Reapply "Clear to eol before outputting line in multi-line prompt" In case a terminal resize[1] causes us to repaint a multi-line prompt that changes width like function fish_prompt for i in 1 2 3 random choice 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbb' end end we add a clr_eol after each line[2] , to make sure that a "b" line does not have leftover "a" letters (80aaae5b7 (Clear to end of each line in left prompt, 2020-10-25)). Unfortunately, if a prompt line takes up all the columns, clr_eol will wrongly clear the last column. Reproduce with function fish_prompt string repeat $COLUMNS - echo "$PWD> " end and observe that the last "-" is missing. Previous (reverted) attempt d3ceba107 (Clear to eol before outputting line in multi-line prompt, 2021-05-17) found the right fix but had an off-by-one error which reintroduced the leftover "a" letters in the "random choice" prompt above. Given prompt string "aa\nbb\ncc", it wrongly printed clr_eol "aa" clr_eol "\nbb" "\ncc" Observe that the first line is cleared twice, while the second line is never cleared. Fix that. [1]: or an async "commandline -f repaint" triggered by a uvar change / async prompt update [2]: except after the last line where we probably already emit clr_eol elsewhere.. Alternative fix: emit both clr_eol and clr_bol *before* drawing the current line. However, if fish and the terminal disagree on character width, that approach might erase too much. Closes #8164 --- src/screen.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screen.rs b/src/screen.rs index a532e528c..ff4f923c3 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -824,11 +824,11 @@ impl Screen { zelf.write_bytes(b"\x1b]133;A;special_key=1\x07"); let mut start = 0; for line_break in left_prompt_layout.line_breaks { - zelf.write_str(&left_prompt[start..line_break]); zelf.outp .borrow_mut() .tputs_if_some(&term.and_then(|term| term.clr_eol.as_ref())); - start = line_break; + zelf.write_str(&left_prompt[start..=line_break]); + start = line_break + 1; } zelf.write_str(&left_prompt[start..]); zelf.actual_left_prompt = left_prompt.to_owned();