package term
import "core:os"
Key_Kind :: enum {
None,
Char,
Enter,
Escape,
Backspace,
Tab,
CtrlC,
Up,
Down,
Left,
Right,
}
Key :: struct {
kind: Key_Kind,
char: u8,
}
@(private)
key_from_byte :: proc(b: u8) -> Key {
switch b {
case 0x03:
return {kind = .CtrlC}
case 0x1b:
return {kind = .Escape}
case 0x7f,0x08:
return {kind = .Backspace}
case '\r','\n':
return {kind = .Enter}
case '\t':
return {kind = .Tab}
case:
if b >= 0x20 && b < 0x7f {
return {kind = .Char, char = b}
}
}
return {kind = .None}
}
read_key :: proc() -> Key {
buf: [1]u8
if n, _ := os.read(os.stdin, buf[:]); n == 0 {
// VTIME timeout, no input yet
return {kind = .None}
}
// ESC — might be a lone Escape, might be a sequence
if buf[0] == 0x1b {
seq: [2]u8
// try to read 2 more bytes with a short timeout
// if nothing comes, it was just Escape
if n, _ := os.read(os.stdin, seq[:1]); n == 0 {
return {kind = .Escape}
}
if n, _ := os.read(os.stdin, seq[1:2]); n == 0 {
return {kind = .Escape}
}
if seq[0] == '[' {
switch seq[1] {
case 'A':
return {kind = .Up}
case 'B':
return {kind = .Down}
case 'C':
return {kind = .Right}
case 'D':
return {kind = .Left}
}
}
return {kind = .Escape}
}
return key_from_byte(buf[0])
}