reader: Only move cursor if needed for repaint-mode

This uses "screen.reset_line" to move the cursor without informing the
reader's machinery (because that deals with positions *in the
commandline*), but then only repainted "if needed" - meaning if the
reader thought anything changed.

That could lead to a situation where the cursor stays at column 0
until you do something, e.g. in

```fish
bind -m insert u undo
```

when you press alt+u - because the *escape* calls repaint-mode, which
puts the cursor in column 0, and then the undo doesn't, which keeps it
there.

Of course this binding should also `repaint-mode`, because it changes
the mode.

Some changes might be ergonomic:

1. Make repaint-mode the default if the mode changed (we would need to
skip it for bracketed-paste)
2. Make triggering the repaint easier - do we need to set
force_exec_prompt_and_repaint to false here as well?

Anyway, this

Fixes #7910

(cherry picked from commit ff433b0cb2)
This commit is contained in:
Fabian Boehm 2023-10-06 16:38:26 +02:00
parent 04492a1a23
commit ac64331217

View File

@ -3489,8 +3489,10 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
parser().libdata().is_repaint = true; parser().libdata().is_repaint = true;
exec_mode_prompt(); exec_mode_prompt();
if (!mode_prompt_buff.empty()) { if (!mode_prompt_buff.empty()) {
if (this->is_repaint_needed()) {
screen.reset_line(true /* redraw prompt */); screen.reset_line(true /* redraw prompt */);
if (this->is_repaint_needed()) this->layout_and_repaint(L"mode"); this->layout_and_repaint(L"mode");
}
parser().libdata().is_repaint = false; parser().libdata().is_repaint = false;
break; break;
} }