27 {std::string({8}), std::string({127})},
58 {
"\x1B[[A",
"\x1BOP"},
59 {
"\x1B[[B",
"\x1BOQ"},
60 {
"\x1B[[C",
"\x1BOR"},
61 {
"\x1B[[D",
"\x1BOS"},
62 {
"\x1B[[E",
"\x1B[15~"},
65 {
"\x1B[11~",
"\x1BOP"},
66 {
"\x1B[12~",
"\x1BOQ"},
67 {
"\x1B[13~",
"\x1BOR"},
68 {
"\x1B[14~",
"\x1BOS"},
71 {
"\x1BOt",
"\x1B[15~"},
72 {
"\x1BOu",
"\x1B[17~"},
73 {
"\x1BOv",
"\x1B[18~"},
74 {
"\x1BOl",
"\x1B[19~"},
75 {
"\x1BOw",
"\x1B[20~"},
76 {
"\x1BOx",
"\x1B[21~"},
83 {
"\x1B[Q",
"\x1B[15~"},
84 {
"\x1B[R",
"\x1B[17~"},
85 {
"\x1B[S",
"\x1B[18~"},
86 {
"\x1B[T",
"\x1B[19~"},
87 {
"\x1B[U",
"\x1B[20~"},
88 {
"\x1B[V",
"\x1B[21~"},
89 {
"\x1B[W",
"\x1B[23~"},
90 {
"\x1B[X",
"\x1B[24~"},
94 : out_(std::move(out)) {}
98 const int timeout_threshold = 50;
99 if (timeout_ < timeout_threshold) {
103 if (!pending_.empty()) {
115unsigned char TerminalInputParser::Current() {
116 return pending_[position_];
119bool TerminalInputParser::Eat() {
121 return position_ < static_cast<int>(pending_.size());
124void TerminalInputParser::Send(TerminalInputParser::Output output) {
125 switch (output.type) {
141 pending_ = it->second;
149 out_->Send(
Event::Mouse(std::move(pending_), output.mouse));
153 case CURSOR_POSITION:
168TerminalInputParser::Output TerminalInputParser::Parse() {
184 if (Current() < 32) {
188 if (Current() == 127) {
211TerminalInputParser::Output TerminalInputParser::ParseUTF8() {
212 auto head = Current();
213 unsigned char selector = 0b1000'0000;
216 unsigned char mask = selector;
219 unsigned int first_zero = 8;
220 for (
unsigned int i = 0; i < 8; ++i) {
222 if (!(head & selector)) {
230 auto value = uint32_t(head & ~mask);
233 const unsigned int max_utf8_bytes = 5;
234 if (first_zero == 1 || first_zero >= max_utf8_bytes) {
239 for (
unsigned int i = 2; i <= first_zero; ++i) {
246 if ((head & 0b1100'0000) != 0b1000'0000) {
250 value += head & 0b0011'1111;
255 if (value <= 0b000'0000'0111'1111) {
257 }
else if (value <= 0b000'0111'1111'1111) {
259 }
else if (value <= 0b1111'1111'1111'1111) {
261 }
else if (value <= 0b1'0000'1111'1111'1111'1111) {
267 if (extra_byte != position_) {
274TerminalInputParser::Output TerminalInputParser::ParseESC() {
295TerminalInputParser::Output TerminalInputParser::ParseDCS() {
302 if (Current() !=
'\x1B') {
310 if (Current() !=
'\\') {
314 if (pending_.size() == 10 &&
315 pending_[2] ==
'1' &&
316 pending_[3] ==
'$' &&
317 pending_[4] ==
'r' &&
319 Output output(CURSOR_SHAPE);
320 output.cursor_shape = pending_[5] -
'0';
328TerminalInputParser::Output TerminalInputParser::ParseCSI() {
329 bool altered =
false;
331 std::vector<int> arguments;
337 if (Current() ==
'<') {
342 if (Current() >=
'0' && Current() <=
'9') {
344 argument += Current() -
'0';
348 if (Current() ==
';') {
349 arguments.push_back(argument);
356 if (Current() >=
'@' && Current() <=
'~' &&
361 arguments.push_back(argument);
366 return ParseMouse(altered,
true, std::move(arguments));
368 return ParseMouse(altered,
false, std::move(arguments));
370 return ParseCursorPosition(std::move(arguments));
377 if (Current() ==
'\x1B') {
383TerminalInputParser::Output TerminalInputParser::ParseOSC() {
389 if (Current() !=
'\x1B') {
395 if (Current() !=
'\\') {
402TerminalInputParser::Output TerminalInputParser::ParseMouse(
405 std::vector<int> arguments) {
406 if (arguments.size() != 3) {
412 Output output(MOUSE);
414 ((arguments[0] & 64) >> 4));
416 output.mouse.shift = bool(arguments[0] & 4);
417 output.mouse.meta = bool(arguments[0] & 8);
418 output.mouse.x = arguments[1];
419 output.mouse.y = arguments[2];
424TerminalInputParser::Output TerminalInputParser::ParseCursorPosition(
425 std::vector<int> arguments) {
426 if (arguments.size() != 2) {
429 Output output(CURSOR_POSITION);
430 output.cursor.y = arguments[0];
431 output.cursor.x = arguments[1];
std::unique_ptr< SenderImpl< T > > Sender
const std::map< std::string, std::string > g_uniformize
static Event CursorShape(std::string, int shape)
An event corresponding to a terminal DCS (Device Control String).
static Event Mouse(std::string, Mouse mouse)
An event corresponding to a given typed character.
static Event Character(std::string)
An event corresponding to a given typed character.
static Event CursorPosition(std::string, int x, int y)
static Event Special(std::string)
An custom event whose meaning is defined by the user of the library.