fix(tui): use erase_chars for short clears #38973

Problem:
Due to optimizations c936ae0f36, nvim prints literal spaces instead of using
`erase_chars` in widths <= 5 even if the terminal advertises `erase_chars`
support (perhaps a small-output size heuristic). However, this is not
semantically neutral: in some terminals, erased cells and printed spaces are
copied differently.

I ended up with two useful groups of results.

First, I tested raw terminal behavior without nvim involved:

    | Terminal | Raw plain text | Raw `erase_chars` | Raw literal spaces |
    | --- | --- | --- | --- |
    | xterm | clean | trailing spaces copied | trailing spaces copied |
    | xfce4-terminal | clean | clean | trailing spaces copied |

Second, I tested nvim itself:

    | Terminal | no patch | with this patch |
    | --- | --- | --- |
    | xfce4-terminal | trailing spaces reproduced | clean |
    | xterm | trailing spaces reproduced | trailing spaces reproduced |
    | Alacritty | clean | clean |
    | Ghostty | clean | clean |
    | WezTerm | clean | clean |

Nvim often prints spaces instead of sending `erase_chars`, which this patch
changes for short clears when the terminal advertises it. This fixes
xfce4-terminal because raw `erase_chars` are already cleaned up by the terminal,
while spaces aren't. ***Notably, xterm is different***: even when `erase_chars`
is sent directly (NO NVIM INVOLVED) xterm *still* copies those cleared blank
trailing cells (and this is documented). So for xterm, which is the only
remaining problematic fix, I'm quite sure there's nothing we ought to do on the
Nvim side.

Solution:
Drop the `width >= 5` condition.
This commit is contained in:
Barrett Ruth authored and GitHub committed 2026-04-12 10:30:06 -04:00
1 parent 52d466c500
commit b7cbad7489
1 file changed
+1 -1
+1 -1
View File
@@ -1191,7 +1191,7 @@ static void clear_region(TUIData *tui, int top, int bot, int left, int right, in
cursor_goto(tui, row, left);
if (tui->can_clear_attr && right == tui->width) {
terminfo_out(tui, kTerm_clr_eol);
} else if (tui->can_erase_chars && tui->can_clear_attr && width >= 5) {
} else if (tui->can_erase_chars && tui->can_clear_attr) {
terminfo_print_num1(tui, kTerm_erase_chars, width);
} else {
print_spaces(tui, width);