parse method
Implementation
List<KeyEvent> parse(String chunk) {
final input = _pending + chunk;
_pending = '';
final events = <KeyEvent>[];
final text = StringBuffer();
void add(KeyEvent event) {
if (text.isNotEmpty) {
events.add(KeyEvent(Key.text, text.toString()));
text.clear();
}
events.add(event);
}
var index = 0;
while (index < input.length) {
final paste = _paste;
if (paste != null) {
final end = input.indexOf(_pasteEnd, index);
if (end < 0) {
paste.write(input.substring(index));
break;
}
paste.write(input.substring(index, end));
add(KeyEvent(Key.paste, paste.toString()));
_paste = null;
index = end + _pasteEnd.length;
continue;
}
final char = input[index];
if (char == '\x1B') {
final escape = _parseEscape(input, index);
if (escape == null) {
_pending = input.substring(index);
break;
}
if (escape.event case final event?) {
add(event);
}
index += escape.length;
continue;
}
if (char == '\r' || char == '\n') {
final length = char == '\r' && index + 1 < input.length && input[index + 1] == '\n' ? 2 : 1;
// Without bracketed paste, pasted lines arrive in one read with text
// after the line break; only a trailing break is the Enter key.
final pastedBreak = input.substring(index + length).trim().isNotEmpty;
add(KeyEvent(pastedBreak ? Key.newline : Key.enter));
index += length;
continue;
}
final control = _controlKeys[char];
if (control != null) {
add(KeyEvent(control));
} else if (char.codeUnitAt(0) >= 0x20) {
text.write(char);
}
index++;
}
if (text.isNotEmpty) {
events.add(KeyEvent(Key.text, text.toString()));
}
return events;
}