Este é o código em OCaml para detectar chaves usando o módulo Unix e o modo raw no terminal Linux.
A única tecla que não consigo detectar é ESC. Pode haver outras, mas meu objetivo principal é detectar a tecla ESC.
Aqui está o código da função:
(* Function to read a character and recognize special keys *)
let read_character () =
let in_chan = in_channel_of_descr stdin in
let c = input_char in_chan in
if c = '\027' then
let next1 = input_char in_chan in
let next2 = input_char in_chan in
match (next1, next2) with
| ('[', 'A') -> "Up Arrow"
| ('[', 'B') -> "Down Arrow"
| ('[', 'C') -> "Right Arrow"
| ('[', 'D') -> "Left Arrow"
| ('[', 'H') -> "Home"
| ('[', 'F') -> "End"
| ('[', '3') when input_char in_chan = '~' -> "Delete"
| ('[', '2') when input_char in_chan = '~' -> "Insert"
| ('[', '5') when input_char in_chan = '~' -> "Page Up"
| ('[', '6') when input_char in_chan = '~' -> "Page Down"
| _ -> "Ignore"
else
match c with
| '\n' -> "Enter" (* Handle Enter key *)
| '\127' -> "Backspace" (* Handle Backspace (DEL) *)
| _ -> String.make 1 c (* Return single character *)
Por favor, leve em consideração que C/curses funciona, mas é muito lento para inicializar/finalizar e limpa a tela, então não é uma opção ideal.
É meio que um desafio. A AI me sugeriu usar Lwt/Async, mas nada disso funcionou, já que não tive sucesso instalando isso no Arch Linux.
Felizmente, há um modo não canônico com timeout que permite isso. O código fonte completo é este:
A tecla Esc gera um único byte ESC (octal 027), enquanto outras teclas especiais geram uma sequência de escape começando com este byte.
Portanto, não há uma maneira totalmente confiável de detectar o pressionamento da tecla Esc em terminais.
Uma possibilidade, feita provavelmente mais notavelmente pela
vi
família, é verificar o byte ESC sem nenhum outro byte imediatamente disponível. Isso funciona muito bem na prática, embora, estritamente falando, possa haver casos em que, dependendo do tempo, os eventos podem dar errado. Uma variação disso é permitir um pouco de atraso adicional enquanto se espera pelos bytes de acompanhamento.Outra possibilidade, também vista frequentemente em aplicativos baseados em terminal, é esperar que o usuário pressione a tecla Esc duas vezes. Isso é fácil de detectar sem heurística, mas resulta em uma experiência de usuário menos agradável.