2
0
Fork 0
mirror of https://github.com/fish-shell/fish-shell synced 2025-02-13 04:33:33 +00:00

Add and use event_queue_t::insert_front()

This allows directly inserting multiple characters/events in one go at
the front of the input queue, instead of needing to add them one-by-one
in reverse order.

In addition to improving performance in case of fragmented dequeue
allocation, this also is less error prone since a dev need not remember
to use reverse iterators when looping over a vector of peeked events.
This commit is contained in:
Mahmoud Al-Qudsi 2021-02-06 17:05:46 -06:00
parent b385772a84
commit c203c88c66
2 changed files with 13 additions and 12 deletions

View file

@ -383,10 +383,7 @@ void inputter_t::mapping_execute(const input_mapping_t &m,
if (has_commands && !command_handler) {
// We don't want to run commands yet. Put the characters back and return check_exit.
for (wcstring::const_reverse_iterator it = m.seq.rbegin(), end = m.seq.rend(); it != end;
++it) {
event_queue_.push_front(*it);
}
event_queue_.insert_front(m.seq.cbegin(), m.seq.cend());
event_queue_.push_front(char_event_type_t::check_exit);
return; // skip the input_set_bind_mode
} else if (has_functions && !has_commands) {
@ -424,7 +421,7 @@ bool inputter_t::mapping_is_match(const input_mapping_t &m) {
auto evt = timed ? event_queue_.readch_timed() : event_queue_.readch();
if (!evt.is_char() || evt.get_char() != str[i]) {
// We didn't match the bind sequence/input mapping, (it timed out or they entered
// something else) Undo consumption of the read characters since we didn't match the
// something else). Undo consumption of the read characters since we didn't match the
// bind sequence and abort.
event_queue_.push_front(evt);
while (i--) event_queue_.push_front(str[i]);
@ -496,10 +493,8 @@ char_event_t inputter_t::read_characters_no_readline() {
break;
}
}
// Restore any readline functions, in reverse to preserve their original order.
for (auto iter = saved_events.rbegin(); iter != saved_events.rend(); ++iter) {
event_queue_.push_front(*iter);
}
// Restore any readline functions
event_queue_.insert_front(saved_events.cbegin(), saved_events.cend());
return evt_to_return;
}
@ -516,9 +511,7 @@ char_event_t inputter_t::readch(const command_handler_t &command_handler) {
case readline_cmd_t::self_insert_notfirst: {
// Typically self-insert is generated by the generic (empty) binding.
// However if it is generated by a real sequence, then insert that sequence.
for (auto iter = evt.seq.crbegin(); iter != evt.seq.crend(); ++iter) {
event_queue_.push_front(*iter);
}
event_queue_.insert_front(evt.seq.cbegin(), evt.seq.cend());
// Issue #1595: ensure we only insert characters, not readline functions. The
// common case is that this will be empty.
char_event_t res = read_characters_no_readline();

View file

@ -221,6 +221,14 @@ class input_event_queue_t {
/// Add a character or a readline function to the front of the queue of unread characters. This
/// will be the next character returned by readch.
void push_front(const char_event_t& ch);
/// Add multiple characters or readline events to the front of the queue of unread characters.
/// The order of the provided events is not changed, i.e. they are not inserted in reverse
/// order.
template<typename Iterator>
void insert_front(const Iterator begin, const Iterator end) {
queue_.insert(queue_.begin(), begin, end);
}
};
#endif