Hello!
I'm trying to make a simple console menu, interactively responsive to pressing a menu item selection key. For example, the menu:
1) пункт 1; 2) пункт 2; 0) выход. To select an item, press the key once, for example, "1" and the menu should work. Also in some cases it is necessary to work out control keys, such as Enter, Esc, Up, etc. If in Windows it turned out to be done without any problems, using the construction:
//#include <conio.h> import "C" func GetCh() int { c := C.getch() // C.int return int(c) } ... here the control keys are easily caught by checking the first byte 0x00 or 0xE0.
In Linux, I ran into problems. Used code:
/* #include <stdio.h> #include <unistd.h> #include <termios.h> char getch(){ char ch = 0; struct termios old = {0}; fflush(stdout); if( tcgetattr(0, &old) < 0 ) perror("tcsetattr()"); old.c_lflag &= ~ICANON; old.c_lflag &= ~ECHO; old.c_cc[VMIN] = 1; old.c_cc[VTIME] = 0; if( tcsetattr(0, TCSANOW, &old) < 0 ) perror("tcsetattr ICANON"); if( read(0, &ch,1) < 0 ) perror("read()"); old.c_lflag |= ICANON; old.c_lflag |= ECHO; if(tcsetattr(0, TCSADRAIN, &old) < 0) perror("tcsetattr ~ICANON"); return ch; } */ import "C" func GetCh() int { c := C.getch() // C.int return int(c) } Problems arise when pressing the control keys. First, they are hard to track, because the first byte is ESC, which corresponds to the code of the pressed ESC key. Secondly, keystrokes can consist of an arbitrary number of sequences. Here you need to create sheets of correspondence sheets from them, which is not my task. Attempting to use third-party modules did not help:
github.com/nsf/termbox-go - after a mandatory Init, it clears the console, which I absolutely do not need; github.com/rthornton128/goncurses - it didn’t work to install to Windows, but it also doesn’t work with UTF, which is important to me for other tasks; github.com/eiannone/keyboard - almost came up, but incorrectly handles the Up and Down keys if working through keyboard.GetKey (). Via keyboard.GetSingleKey () - starts duplicating key codes after several keystrokes until it crashes by mistake "panic: runtime error: slice bounds out of range":
for { ch, key, err := keyboard.GetSingleKey() if err != nil { log.Fatal(err) } fmt.Printf("%v %v\n", ch, key) } In principle, if Linux were able to get the entire set of bytes at once when you press the keys, that would be enough (or checking the keyboard buffer emptiness), but you could not find how to do this in Go.
In general, the question can be narrowed down to the last paragraph - how to get the whole set of bytes of a pressed key in Linux, or what third-party tool can I use for this (I understand that there are tools, but I cannot find them ... or I don’t understand how to do this)? Thank you in advance!