forked from timsneath/dart_console
-
Notifications
You must be signed in to change notification settings - Fork 9
Open
Labels
enhancementNew feature or requestNew feature or requesthelp wantedExtra attention is neededExtra attention is needed
Description
The synchronous method readKey is limiting since it blocks any update to the console that might be wanted before the next key is pressed.
For example you might want to refresh a loader character and wait for an input key at the same time.
To solve this, the stdin stream should be listen instead to manage the received bytes. Something like the following should work :
extension ConsoleExtensions on Console {
Stream<Key> readKeys() async* {
rawMode = true;
List<int> escapeSequence = <int>[];
void resetEscape() => escapeSequence = <int>[];
await for (var codeUnit in stdin.expand((x) => x)) {
if (escapeSequence.isNotEmpty) {
escapeSequence.add(codeUnit);
switch (escapeSequence) {
case [0x1b, -1]:
yield Key.control(ControlCharacter.escape);
resetEscape();
case [0x1b, 127]:
yield Key.control(ControlCharacter.wordBackspace);
resetEscape();
case [0x1b, 91, 65]: // [ A
yield Key.control(ControlCharacter.arrowUp);
resetEscape();
case [0x1b, 91, 66]: // [ B
yield Key.control(ControlCharacter.arrowDown);
resetEscape();
case [0x1b, 91, 67]: // [ C
yield Key.control(ControlCharacter.arrowRight);
resetEscape();
case [0x1b, 91, 68]: // [ D
yield Key.control(ControlCharacter.arrowLeft);
resetEscape();
case [0x1b, 91, 72]: // [ H
yield Key.control(ControlCharacter.home);
resetEscape();
case [0x1b, 91, 70]: // [ F
yield Key.control(ControlCharacter.end);
resetEscape();
// TODO more scaped sequences
}
} else if (codeUnit == 0x1b) {
escapeSequence = <int>[codeUnit];
} else if (codeUnit >= 0x01 && codeUnit <= 0x1a) {
// Ctrl+A thru Ctrl+Z are mapped to the 1st-26th entries in the
// enum, so it's easy to convert them across
yield Key.control(ControlCharacter.values[codeUnit]);
} else if (codeUnit == 0x7f) {
yield Key.control(ControlCharacter.backspace);
} else if (codeUnit == 0x00 || (codeUnit >= 0x1c && codeUnit <= 0x1f)) {
yield Key.control(ControlCharacter.unknown);
} else {
// assume other characters are printable
yield Key.printable(String.fromCharCode(codeUnit));
}
}
}
}
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requesthelp wantedExtra attention is neededExtra attention is needed