代码之家  ›  专栏  ›  技术社区  ›  Cactus

退出时恢复终端设置

  •  0
  • Cactus  · 技术社区  · 4 年前

    the terminal package ,我的代码基本上如下所示:

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

    Ctrl-C键 ,终端设置(在这个具体的例子中,隐藏的光标)保持不变。我正在寻找一种轻量级的方法 . 我所说的轻量级,是指我可以把整个 runTerminalT 舍邦,不用手动打电话 checkInterrupt 在我的代码的各个部分等等。

    0 回复  |  直到 4 年前
        1
  •  3
  •   dfeuer    4 年前

    没有必要乱搞POSIX信号来做一些类似于danielwagner的回答。 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 约束,对于这种通用方法来说应该足够了。

        2
  •  1
  •   Daniel Wagner    4 年前

    import System.Exit
    import System.Posix.Signals
    
    main = do
        installHandler sigINT Nothing . Catch $ do
            resetTerminalOrWhatever
            exitWith (ExitFailure 1)
        withTerminal $ {- ... -}
    

    信号模块可从 unix 包裹。

    如果你是偏执狂,你可以检查一下旧的处理程序是什么,并尝试将其纳入你的:

    main = do
        mfix $ \oldHandler ->
            installHandler sigINT Nothing . CatchInfo $ \si -> case oldHandler of
                Default -> reset >> exit
                Ignore -> reset >> exit
                Catch act -> reset >> act
                CatchOnce act -> reset >> act >> exit
                CatchInfo f -> reset >> f si
                CatchInfoOnce f -> reset >> f si >> exit
        withTerminal $ {- ... -}
    

    ……或者类似的。