23 {std::string({8}), std::string({127})},
27 : out_(std::move(out)) {}
31 const int timeout_threshold = 50;
32 if (timeout_ < timeout_threshold) {
36 if (!pending_.empty()) {
48unsigned char TerminalInputParser::Current() {
49 return pending_[position_];
52bool TerminalInputParser::Eat() {
54 return position_ < (int)pending_.size();
57void TerminalInputParser::Send(TerminalInputParser::Output output) {
58 switch (output.type) {
67 out_->Send(Event::Character(std::move(pending_)));
74 pending_ = it->second;
82 out_->Send(Event::Mouse(std::move(pending_), output.mouse));
86 case CURSOR_REPORTING:
87 out_->Send(Event::CursorReporting(std::move(pending_),
96TerminalInputParser::Output TerminalInputParser::Parse() {
112 if (Current() < 32) {
116 if (Current() == 127) {
139TerminalInputParser::Output TerminalInputParser::ParseUTF8() {
140 auto head =
static_cast<unsigned char>(Current());
141 unsigned char selector = 0b1000'0000;
144 unsigned char mask = selector;
147 unsigned int first_zero = 8;
148 for (
unsigned int i = 0; i < 8; ++i) {
150 if (!(head & selector)) {
158 auto value = uint32_t(head & ~mask);
161 const unsigned int max_utf8_bytes = 5;
162 if (first_zero == 1 || first_zero >= max_utf8_bytes) {
167 for (
unsigned int i = 2; i <= first_zero; ++i) {
173 head =
static_cast<unsigned char>(Current());
174 if ((head & 0b1100'0000) != 0b1000'0000) {
178 value += head & 0b0011'1111;
183 if (value <= 0b000'0000'0111'1111) {
185 }
else if (value <= 0b000'0111'1111'1111) {
187 }
else if (value <= 0b1111'1111'1111'1111) {
189 }
else if (value <= 0b1'0000'1111'1111'1111'1111) {
195 if (extra_byte != position_) {
202TerminalInputParser::Output TerminalInputParser::ParseESC() {
222TerminalInputParser::Output TerminalInputParser::ParseDCS() {
229 if (Current() !=
'\x1B') {
237 if (Current() !=
'\\') {
245TerminalInputParser::Output TerminalInputParser::ParseCSI() {
246 bool altered =
false;
248 std::vector<int> arguments;
254 if (Current() ==
'<') {
259 if (Current() >=
'0' && Current() <=
'9') {
261 argument += int(Current() -
'0');
265 if (Current() ==
';') {
266 arguments.push_back(argument);
271 if (Current() >=
' ' && Current() <=
'~' && Current() !=
'<') {
272 arguments.push_back(argument);
276 return ParseMouse(altered,
true, std::move(arguments));
278 return ParseMouse(altered,
false, std::move(arguments));
280 return ParseCursorReporting(std::move(arguments));
287 if (Current() ==
'\x1B') {
293TerminalInputParser::Output TerminalInputParser::ParseOSC() {
299 if (Current() !=
'\x1B') {
305 if (Current() !=
'\\') {
312TerminalInputParser::Output TerminalInputParser::ParseMouse(
315 std::vector<int> arguments) {
316 if (arguments.size() != 3) {
322 Output output(MOUSE);
324 ((arguments[0] & 64) >> 4));
326 output.mouse.shift = bool(arguments[0] & 4);
327 output.mouse.meta = bool(arguments[0] & 8);
328 output.mouse.x = arguments[1];
329 output.mouse.y = arguments[2];
334TerminalInputParser::Output TerminalInputParser::ParseCursorReporting(
335 std::vector<int> arguments) {
336 if (arguments.size() != 2) {
339 Output output(CURSOR_REPORTING);
340 output.cursor.y = arguments[0];
341 output.cursor.x = arguments[1];
const std::map< std::string, std::string > g_uniformize
std::unique_ptr< SenderImpl< T > > Sender
static Event Special(std::string)