haskell - 退出时恢复终端设置

标签 haskell terminal resource-cleanup

使用 the terminal package ,我的代码基本上是这样的:

main :: IO ()
main = withTerminal $ runTerminalT $ do
    eraseInDisplay EraseAll
    hideCursor
    setAutoWrap False

    forever $ do
        calculate
        updateScreen
如果用户使用 Ctrl-C 退出该程序,终端设置(在本例中为隐藏光标)将保留。我正在寻找一种轻量级的方式 将终端设置恢复为运行程序之前的状态 .我所说的轻量级是指我可以将整个 runTerminalT 包裹起来的东西。 shebang,而不必手动调用 checkInterrupt在我的代码的各个部分等。

最佳答案

没有必要弄乱 POSIX 信号来做类似 Daniel Wagner 的回答。 Control.Exception拥有您需要的一切。

import Control.Exception (handleJust, AsyncException (UserInterrupt))
import Control.Monad (guard)
import System.Exit (exitWith, ExitCode (ExitFailure))

main = withTerminal $ \term ->
  handleJust
         (guard . (== UserInterrupt))
         (\ ~() -> do
           resetTerminalOrWhatever term
           exitWith (ExitFailure 1)) $
         ...
您实际上可能想要更广泛的东西,因为您可能希望在任何异常终止时重置终端:
main = withTerminal $ \term -> ... `onException` resetTerminalOrWhatever term
请注意,第二个版本将通过调用 exitWith 来激活。也是。如果不希望这样做,那么您可以手动捕获/重新抛出并避免在 ExitSuccess 上重置终端。 .

请注意 withTerminal实际上可以在比 IO 更一般的上下文中运行,但它总是需要 MonadMask约束,这对于这种一般方法应该是足够的。

关于haskell - 退出时恢复终端设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66396215/

相关文章:

json - 在命令行终端解析json

c - 如何使 printf 在 C 中正确打印用户输入 argv 的 strtok

linux - 如何一次返回一行 grep 结果以便在另一个脚本中使用解析后的数据?

java - java Play! 返回结果后如何执行代码框架?

python - Try-finally 装饰器清理 python 对象

windows - ansi 终端和 native io 管理器不起作用

algorithm - 字符串中的第一个非重复字符?在 haskell 或 F# 中

haskell - 为什么这个类型类只能用 "-XNoMonomorphismRestriction"编译?

haskell - 连接到 GHC 运行时系统

.net - 处理 StreamWriter 而不在一行中声明变量