如何使用Unix模块和原始模式检测Esc键?

问题描述 投票:0回答:1

这是 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 中成功安装它。

linux terminal key ocaml detection
1个回答
0
投票

Esc 键生成单个 ESC 字节(八进制 027),而其他特殊键生成以此字节开头的转义序列。

因此,没有完全可靠的方法来检测终端中的 Esc 按键。

一种可能,最显着的是由

vi
系列完成的,是在没有任何其他立即可用的字节的情况下检查 ESC 字节。这在实践中效果很好,尽管严格来说,在某些情况下,依赖事件的时间可能会出错。对此的一种变体是在等待后续字节时允许一些额外的延迟。

另一种可能性(也经常出现在基于终端的应用程序中)是期望用户按 Esc 键两次。无需启发式即可直接检测到这一点,但会导致不太愉快的用户体验。

© www.soinside.com 2019 - 2024. All rights reserved.