在 haskell 标准输入上处理箭头键 ANSI 转义序列

问题描述

我正在尝试处理箭头键 ANSI 转义序列,即

up - "\033[A"
down - "\033[B"
left - "\033[D"
right - "\033[C"

在我的程序中,所以当我按下向上/向下/向左/向右箭头键时,它不必看起来像这样:

% stack runghc test.hs
Input a name?
^[[A^[[B^[[C^[[D^

在我的标准输入上,但我希望这些键被抑制甚至更好, 让他们真正工作(即向左/向右移动光标)。我的代码如下:

main = do putStrLn "Input a name?"  
          name <- getLine  
          putStrLn $ ("His name is " ++ name)

任何帮助将不胜感激。提前致谢。

解决方法

获得类似 readline 功能的最简单方法是使用 readline。对于大多数简单的用例,rlwrap 就足够了,如 One REPL to bind them all? 中所述。如果您需要进行更高级的集成,您可以使用 readline 包。

,

由于某些 errors,我在安装 readline 库时遇到了问题,因此决定使用 haskeline 库,这是一个更便携的纯 Haskell 替代品。

使用它的语法并修改之前的代码,我得到:

main :: IO ()
main = do putStrLn "Input a name?"
          runInputT defaultSettings insertion
  where
      insertion :: InputT IO ()
      insertion = do
          minput <- getInputLine ""
          case minput of
              Nothing -> return ()
              Just input -> do outputStrLn $ "His name is " ++ input

这解决了问题,因为我现在可以使用箭头键自由移动光标,而无需看到任何尾随的 ANSI 转义序列,如下所示:

result