package main import ( "bufio" "fmt" "golang.org/x/term" "os" ) func isAscii(char rune) bool { ord := int(char) return ord < 0x80 } func isCtrl(char rune) bool { if ! isAscii(char) { return false } ord:= int(char) return ord == 0x7f || ord < 0x20 } func goRaw() (*term.State, error) { state, err := term.MakeRaw(int(os.Stdin.Fd())) return state, err } func main() { // Go to proper raw mode oldState, err := goRaw() if err != nil { panic(err) } // Restore canonical mode at exit defer term.Restore(int(os.Stdin.Fd()), oldState) reader := bufio.NewReader(os.Stdin) for { char, _, err := reader.ReadRune() if err != nil { panic(err) } switch { case char == 'q': fmt.Println("bye!\r") return case isCtrl(char): fmt.Printf("%d\n", char) default: fmt.Printf("%d ('%c')\n", char, char) } _ = os.Stdout.Sync() } }