Simplify event_queue_peeker_t

Make it an ordinary struct wrapping a vector, instead of a template.
This is in preparation for using it more widely, for matching bindings
as well as mouse CSI sequences.
Also add some mouse-disabling tests.
This commit is contained in:
ridiculousfish 2021-04-07 15:26:24 -07:00
parent e8a61ef4aa
commit c570a14c04
2 changed files with 58 additions and 41 deletions

View file

@ -485,56 +485,41 @@ maybe_t<input_mapping_t> inputter_t::find_mapping() {
return generic ? maybe_t<input_mapping_t>(*generic) : none(); return generic ? maybe_t<input_mapping_t>(*generic) : none();
} }
template <size_t N = 16> /// A class which allows accumulating input events, or return them to the queue.
class event_queue_peeker_t { class event_queue_peeker_t {
private: public:
input_event_queue_t &event_queue_; explicit event_queue_peeker_t(input_event_queue_t &event_queue) : event_queue_(event_queue) {}
std::array<char_event_t, N> peeked_;
size_t count = 0;
bool consumed_ = false;
public: /// \return the next event, optionally waiting for it.
event_queue_peeker_t(input_event_queue_t &event_queue) char_event_t next(bool timed = false) {
: event_queue_(event_queue) { auto event = timed ? event_queue_.readch_timed() : event_queue_.readch();
} peeked_.push_back(event);
return event;
}
char_event_t next(bool timed = false) { /// \return how many events are currently stored.
assert(count < N && "Insufficient backing array size!"); size_t len() const { return peeked_.size(); }
auto event = timed ? event_queue_.readch_timed() : event_queue_.readch();
peeked_[count++] = event;
return event;
}
size_t len() { /// Consume all events that have been peeked, leaving this empty.
return count; void consume() { peeked_.clear(); }
}
constexpr size_t max_len() const { /// Return all peeked events to the queue.
return N; void restart() {
} event_queue_.insert_front(peeked_.cbegin(), peeked_.cend());
peeked_.clear();
}
void consume() { ~event_queue_peeker_t() { restart(); }
consumed_ = true;
}
void restart() { private:
if (count > 0) { std::vector<char_event_t> peeked_;
event_queue_.insert_front(peeked_.cbegin(), peeked_.cbegin() + count); input_event_queue_t &event_queue_;
count = 0;
}
}
~event_queue_peeker_t() {
if (!consumed_) {
restart();
}
}
}; };
bool inputter_t::have_mouse_tracking_csi() { bool inputter_t::have_mouse_tracking_csi() {
// Maximum length of any CSI is NPAR (which is nominally 16), although this does not account for // Maximum length of any CSI is NPAR (which is nominally 16), although this does not account for
// user input intermixed with pseudo input generated by the tty emulator. // user input intermixed with pseudo input generated by the tty emulator.
event_queue_peeker_t<16> peeker(event_queue_); event_queue_peeker_t peeker(event_queue_);
// Check for the CSI first // Check for the CSI first
if (peeker.next().maybe_char() != L'\x1B' if (peeker.next().maybe_char() != L'\x1B'
@ -576,11 +561,11 @@ bool inputter_t::have_mouse_tracking_csi() {
// Consume however many characters it takes to prevent the mouse tracking sequence from reaching // Consume however many characters it takes to prevent the mouse tracking sequence from reaching
// the prompt, dependent on the class of mouse reporting as detected above. // the prompt, dependent on the class of mouse reporting as detected above.
peeker.consume(); while (peeker.len() < length) {
while (peeker.len() != length) { (void)peeker.next();
auto _ = peeker.next();
} }
peeker.consume();
return true; return true;
} }

View file

@ -0,0 +1,32 @@
#!/usr/bin/env python3
from pexpect_helper import SpawnedProc
import subprocess
import sys
import time
sp = SpawnedProc(args=["-d", "reader"])
sp.expect_prompt()
# Verify we correctly diable mouse tracking.
# Five char sequence.
sp.send("\x1b[tDE")
sp.expect_str("reader: Disabling mouse tracking")
# Six char sequence.
sp.send("\x1b[MABC")
sp.expect_str("reader: Disabling mouse tracking")
# Nine char sequences.
sp.send("\x1b[TABCDEF")
sp.expect_str("reader: Disabling mouse tracking")
# Extended SGR sequences.
sp.send("\x1b[<fooM")
sp.expect_str("reader: Disabling mouse tracking")
sp.send("\x1b[<foobarm")
sp.expect_str("reader: Disabling mouse tracking")
sp.sendline("echo done")
sp.expect_prompt("done")