Prevent signals from tearing multi-char bindings

Say the user has a multi-char binding (typically an escape sequence), and a
signal arrives partway through the binding. The signal has an event handler
which enques some readline event, for example, `repaint`. Prior to this
change, the readline event would cause the multi-char binding to fail. This
would cause bits of the escape sequence to be printed to the screen.

Fix this by noticing when a sequence was "interrupted" by a non-char event,
and then rotating a sequence of such interruptions to the front of the
queue.

Fixes #8628
This commit is contained in:
ridiculousfish
2022-01-30 13:15:50 -08:00
parent 43e5004b6e
commit 1bdd629326
5 changed files with 120 additions and 1 deletions

View File

@@ -255,6 +255,15 @@ void input_event_queue_t::push_back(const char_event_t& ch) { queue_.push_back(c
void input_event_queue_t::push_front(const char_event_t& ch) { queue_.push_front(ch); }
void input_event_queue_t::promote_interruptions_to_front() {
// Find the first sequence of non-char events.
// EOF is considered a char: we don't want to pull EOF in front of real chars.
auto is_char = [](const char_event_t& ch) { return ch.is_char() || ch.is_eof(); };
auto first = std::find_if_not(queue_.begin(), queue_.end(), is_char);
auto last = std::find_if(first, queue_.end(), is_char);
std::rotate(queue_.begin(), first, last);
}
void input_event_queue_t::prepare_to_select() {}
void input_event_queue_t::select_interrupted() {}
input_event_queue_t::~input_event_queue_t() = default;