From 47480b2dbd43dec4a7eca4e369ea4b7a0ee73e24 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 24 Aug 2020 13:19:57 -0700 Subject: [PATCH] Remove redraw coalescing logic Prior to this change, if we saw more than one repaint readline command in a row, we would try to ignore the second one. However this was never the right thing to do since sometimes we really do need to repaint twice in a row (e.g. the user hits Ctrl+L twice). Previously we were saved by the buginess of this mechanism but with the repainting refactoring we see missing redraws. Remove the coalescing logic and add a test. Fixes #7280. --- build_tools/pexpect_helper.py | 7 ++++--- src/reader.cpp | 13 ++++--------- tests/pexpects/bind.py | 8 +++++++- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/build_tools/pexpect_helper.py b/build_tools/pexpect_helper.py index d7350fc43..2b8ac9253 100644 --- a/build_tools/pexpect_helper.py +++ b/build_tools/pexpect_helper.py @@ -197,10 +197,10 @@ class SpawnedProc(object): """ Cover over expect_re() which accepts a literal string. """ return self.expect_re(re.escape(s), **kwargs) - def expect_prompt(self, *args, **kwargs): + def expect_prompt(self, increment=True, *args, **kwargs): """ Convenience function which matches some text and then a prompt. Match the given positional arguments as expect_re, and then look - for a prompt, bumping the prompt counter. + for a prompt, bumping the prompt counter if increment is true. Returns None on success, and exits on failure. Example: sp.sendline("echo hello world") @@ -212,7 +212,8 @@ class SpawnedProc(object): get_prompt_re(self.prompt_counter), pat_desc="prompt %d" % self.prompt_counter, ) - self.prompt_counter += 1 + if increment: + self.prompt_counter += 1 def report_exception_and_exit(self, pat, unmatched, err): """ Things have gone badly. diff --git a/src/reader.cpp b/src/reader.cpp index d7fb4012e..8a3c9ac2c 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2645,9 +2645,6 @@ struct readline_loop_state_t { /// Maximum number of characters to read. size_t nchars{std::numeric_limits::max()}; - - /// \return whether the last readline command was a repaint. - bool last_was_repaint() const { return last_cmd && *last_cmd == readline_cmd_t::repaint; } }; /// Read normal characters, inserting them into the command line. @@ -2767,12 +2764,10 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat } case rl::force_repaint: case rl::repaint: { - if (force_exec_prompt_and_repaint || !rls.last_was_repaint()) { - exec_prompt(); - s_reset_line(&screen, true /* redraw prompt */); - this->layout_and_repaint(L"readline"); - force_exec_prompt_and_repaint = false; - } + exec_prompt(); + s_reset_line(&screen, true /* redraw prompt */); + this->layout_and_repaint(L"readline"); + force_exec_prompt_and_repaint = false; break; } case rl::complete: diff --git a/tests/pexpects/bind.py b/tests/pexpects/bind.py index 59bc6acdd..1f331c6eb 100644 --- a/tests/pexpects/bind.py +++ b/tests/pexpects/bind.py @@ -3,7 +3,13 @@ from pexpect_helper import SpawnedProc sp = SpawnedProc() send, sendline, sleep, expect_prompt = sp.send, sp.sendline, sp.sleep, sp.expect_prompt -expect_prompt() +expect_prompt(increment=False) + +# Clear twice (regression test for #7280). +send("\f") +expect_prompt(increment=False) +send("\f") +expect_prompt(increment=False) # Fish should start in default-mode (i.e., emacs) bindings. The default escape # timeout is 30ms.