这是 OCaml 中的代码,用于在 Linux 终端中使用 Unix 模块和原始模式检测按键。
我唯一检测不到的键是 ESC。可能还有其他的,但我的主要目标是检测 ESC 键。
这是该函数的代码:
(* 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 *)
请考虑到 C/curses 可以工作,但初始化/完成速度非常慢并且会清除屏幕,因此它不是最佳选择。
这是一种挑战。 AI 建议我使用 Lwt/Async,但这些都不起作用,因为我没有在 Arch Linux 中成功安装它。
Esc 键生成单个 ESC 字节(八进制 027),而其他特殊键生成以此字节开头的转义序列。
因此,没有完全可靠的方法来检测终端中的 Esc 按键。
一种可能,最显着的是由
vi
系列完成的,是在没有任何其他立即可用的字节的情况下检查 ESC 字节。这在实践中效果很好,尽管严格来说,在某些情况下,依赖事件的时间可能会出错。对此的一种变体是在等待后续字节时允许一些额外的延迟。
另一种可能性(也经常出现在基于终端的应用程序中)是期望用户按 Esc 键两次。无需启发式即可直接检测到这一点,但会导致不太愉快的用户体验。