使用 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/