mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-15 14:34:05 +00:00
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:
parent
e8a61ef4aa
commit
c570a14c04
2 changed files with 58 additions and 41 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
tests/pexpects/disable_mouse.py
Normal file
32
tests/pexpects/disable_mouse.py
Normal 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")
|
Loading…
Reference in a new issue