27 {std::string({8}), std::string({127})},
56 {
"\x1B[[A",
"\x1BOP"},
57 {
"\x1B[[B",
"\x1BOQ"},
58 {
"\x1B[[C",
"\x1BOR"},
59 {
"\x1B[[D",
"\x1BOS"},
60 {
"\x1B[[E",
"\x1B[15~"},
63 {
"\x1B[11~",
"\x1BOP"},
64 {
"\x1B[12~",
"\x1BOQ"},
65 {
"\x1B[13~",
"\x1BOR"},
66 {
"\x1B[14~",
"\x1BOS"},
69 {
"\x1BOt",
"\x1B[15~"},
70 {
"\x1BOu",
"\x1B[17~"},
71 {
"\x1BOv",
"\x1B[18~"},
72 {
"\x1BOl",
"\x1B[19~"},
73 {
"\x1BOw",
"\x1B[20~"},
74 {
"\x1BOx",
"\x1B[21~"},
81 {
"\x1B[Q",
"\x1B[15~"},
82 {
"\x1B[R",
"\x1B[17~"},
83 {
"\x1B[S",
"\x1B[18~"},
84 {
"\x1B[T",
"\x1B[19~"},
85 {
"\x1B[U",
"\x1B[20~"},
86 {
"\x1B[V",
"\x1B[21~"},
87 {
"\x1B[W",
"\x1B[23~"},
88 {
"\x1B[X",
"\x1B[24~"},
92 : out_(std::move(out)) {}
96 const int timeout_threshold = 50;
97 if (timeout_ < timeout_threshold) {
101 if (!pending_.empty()) {
113unsigned char TerminalInputParser::Current() {
114 return pending_[position_];
117bool TerminalInputParser::Eat() {
119 return position_ < static_cast<int>(pending_.size());
122void TerminalInputParser::Send(TerminalInputParser::Output output) {
123 switch (output.type) {
132 out_(Event::Character(std::move(pending_)));
139 pending_ = it->second;
147 out_(Event::Mouse(std::move(pending_), output.mouse));
151 case CURSOR_POSITION:
152 out_(Event::CursorPosition(std::move(pending_),
159 out_(Event::CursorShape(std::move(pending_), output.cursor_shape));
166TerminalInputParser::Output TerminalInputParser::Parse() {
171 if (Current() ==
'\x1B') {
175 if (Current() < 32) {
179 if (Current() == 127) {
201TerminalInputParser::Output TerminalInputParser::ParseUTF8() {
202 auto head = Current();
203 unsigned char selector = 0b1000'0000;
206 unsigned char mask = selector;
209 unsigned int first_zero = 8;
210 for (
unsigned int i = 0; i < 8; ++i) {
212 if (!(head & selector)) {
220 auto value = uint32_t(head & ~mask);
223 const unsigned int max_utf8_bytes = 5;
224 if (first_zero == 1 || first_zero >= max_utf8_bytes) {
229 for (
unsigned int i = 2; i <= first_zero; ++i) {
236 if ((head & 0b1100'0000) != 0b1000'0000) {
240 value += head & 0b0011'1111;
245 if (value <= 0b000'0000'0111'1111) {
247 }
else if (value <= 0b000'0111'1111'1111) {
249 }
else if (value <= 0b1111'1111'1111'1111) {
251 }
else if (value <= 0b1'0000'1111'1111'1111'1111) {
257 if (extra_byte != position_) {
264TerminalInputParser::Output TerminalInputParser::ParseESC() {
298TerminalInputParser::Output TerminalInputParser::ParseDCS() {
305 if (Current() !=
'\x1B') {
313 if (Current() !=
'\\') {
317 if (pending_.size() == 10 &&
318 pending_[2] ==
'1' &&
319 pending_[3] ==
'$' &&
320 pending_[4] ==
'r' &&
322 Output output(CURSOR_SHAPE);
323 output.cursor_shape = pending_[5] -
'0';
331TerminalInputParser::Output TerminalInputParser::ParseCSI() {
332 bool altered =
false;
334 std::vector<int> arguments;
340 if (Current() ==
'<') {
345 if (Current() >=
'0' && Current() <=
'9') {
347 argument += Current() -
'0';
351 if (Current() ==
';') {
352 arguments.push_back(argument);
359 if (Current() >=
'@' && Current() <=
'~' &&
364 arguments.push_back(argument);
369 return ParseMouse(altered,
true, std::move(arguments));
371 return ParseMouse(altered,
false, std::move(arguments));
373 return ParseCursorPosition(std::move(arguments));
380 if (Current() ==
'\x1B') {
386TerminalInputParser::Output TerminalInputParser::ParseOSC() {
392 if (Current() !=
'\x1B') {
398 if (Current() !=
'\\') {
405TerminalInputParser::Output TerminalInputParser::ParseMouse(
408 std::vector<int> arguments) {
409 if (arguments.size() != 3) {
415 Output output(MOUSE);
428 const int button = arguments[0] & (1 + 2);
429 const bool is_shift = arguments[0] & 4;
430 const bool is_meta = arguments[0] & 8;
431 const bool is_control = arguments[0] & 16;
432 const bool is_move = arguments[0] & 32;
433 const bool is_wheel = arguments[0] & 64;
438 : Mouse::Button(button);
439 output.mouse.shift = is_shift;
440 output.mouse.meta = is_meta;
441 output.mouse.control = is_control;
442 output.mouse.x = arguments[1];
443 output.mouse.y = arguments[2];
450TerminalInputParser::Output TerminalInputParser::ParseCursorPosition(
451 std::vector<int> arguments) {
452 if (arguments.size() != 2) {
455 Output output(CURSOR_POSITION);
456 output.cursor.y = arguments[0];
457 output.cursor.x = arguments[1];
static Event Special(std::string)
ライブラリのユーザーによって意味が定義されるカスタムイベント。
イベントを表します。キープレスイベント、ターミナルのリサイズなど、さまざまなイベントがあります。
const std::map< std::string, std::string > g_uniformize