haskell - 如何在Haskell中使用readline在任何按键上删除终端中的一行?

标签 haskell readline

我正在使用Haskell bindingsreadline 库来读取用户的输入。

我想要实现的是提供一个预填充值,只需按回车键即可提交该值,但如果用户开始键入,我想自动删除预填充文本。 (这样用户就不必关心删除预填充值。)

我认为可以通过使用rl_getc_function钩子(Hook)来完成。但是,Haskell 绑定(bind)不公开此函数。

有什么方法可以实现所需的行为吗?

最佳答案

最后我找到了一种方法,但它不太好,感觉有点像黑客。

它的工作原理是将所有键重新绑定(bind)到一个自定义函数,该函数首先删除该行,然后重置所有这些处理程序以实际再次插入该字符。为了不丢失触发按键,它被推回输入。

main :: IO ()
main = do
    -- create a copy of current keymap
    keymap <- getKeymap >>= copyKeymap
    -- bind (hopefully all) regular keys to a helper function
    forM_ (map toEnum [32..256]) $ \key ->
        bindKey key $ \ _ _ -> do
            -- delete all text on line
            getEnd >>= deleteText 0
            -- set cursor to start of line
            setPoint 0
            redisplay
            -- reset keymap to the original one
            setKeymap keymap
            -- push pressed key back to input
            setPendingInput key
            return 0
    setStartupHook (Just $ insertText "prefilled text")
    readline "prompt> "

这里的主要难点是确定要重新绑定(bind)哪些键。我使用了一种科学的反复试验方法:下限是空间(任何小于该值的东西都是不可打印的,可能有一些特殊的功能,我不想弄乱它)。上限设置为 256 – 任何更多都会导致段错误,使用较小的数字会使函数无法处理某些 unicode 输入。

即使在这个范围内,如果用户开始在CJK中输入内容,它也可能不起作用。 。如果用户使用dead key输入内容,它肯定无法正常工作。 .

关于haskell - 如何在Haskell中使用readline在任何按键上删除终端中的一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28645656/

相关文章:

perl - 使用 Term::Readline:Zoid 时出现 "ViCommand: no such keymap"错误

haskell - 为什么单子(monad)在组合下不关闭?

performance - Haskell中合理有效的纯功能矩阵产品?

haskell - 一个不平凡的共同类群是什么样子的?

node.js - 我应该使用哪些 Linux 系统调用从 stdin 读取原始字符?

r - 如何让 R 中的原生 Vi 模式保持持久?

haskell - SPECIALIZE 编译用语的误解

python - Haskell 与 Python 线程模型

bash - 如何从命令行进行递归查找和替换?

C# ReadLine 转义回车/换行符?