From ac64331217d5ee39bacb56ef0b07bfecc64a8aa7 Mon Sep 17 00:00:00 2001 From: Fabian Boehm Date: Fri, 6 Oct 2023 16:38:26 +0200 Subject: [PATCH] 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 ff433b0cb235689a93734e08a9dbed0204ce7ebe) --- src/reader.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/reader.cpp b/src/reader.cpp index d3bfa17fb..351c12e4d 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -3489,8 +3489,10 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat parser().libdata().is_repaint = true; exec_mode_prompt(); if (!mode_prompt_buff.empty()) { - screen.reset_line(true /* redraw prompt */); - if (this->is_repaint_needed()) this->layout_and_repaint(L"mode"); + if (this->is_repaint_needed()) { + screen.reset_line(true /* redraw prompt */); + this->layout_and_repaint(L"mode"); + } parser().libdata().is_repaint = false; break; }