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:
parent
b385772a84
commit
c203c88c66
2 changed files with 13 additions and 12 deletions
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue