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]) }