Hook into interrupt to trigger other behavior

Why?
====

Unused hides the cursor and potentially does other things to the window that
may leave it in an odd state. This introduces a hook to run any state
cleanup, including re-enabling the cursor, when a user sends a SIGINT to
the program.
This commit is contained in:
Joshua Clayton 2016-05-09 17:45:42 -04:00
parent 5952306873
commit 11d35a6263
3 changed files with 25 additions and 3 deletions

View File

@ -5,7 +5,7 @@ import System.IO (hSetBuffering, BufferMode(NoBuffering), stdout)
import Unused.Parser (parseLines)
import Unused.Types (ParseResponse, RemovalLikelihood(..))
import Unused.ResponseFilter (withOneOccurrence, withOneFile, withLikelihoods, ignoringPaths)
import Unused.CLI (SearchRunner(..), executeSearch, printParseError, printSearchResults, resetScreen)
import Unused.CLI (SearchRunner(..), executeSearch, printParseError, printSearchResults, resetScreen, withInterruptHandler)
data Options = Options
{ oSearchRunner :: SearchRunner
@ -15,8 +15,9 @@ data Options = Options
}
main :: IO ()
main = run =<< execParser
(parseOptions `withInfo` "Analyze potentially unused code")
main = withInterruptHandler $
run =<< execParser
(parseOptions `withInfo` "Analyze potentially unused code")
run :: Options -> IO ()
run options = do

View File

@ -1,11 +1,31 @@
module Unused.CLI.Util
( resetScreen
, withInterruptHandler
, module System.Console.ANSI
) where
import System.Console.ANSI
import Control.Exception (throwTo)
import System.Posix.Signals (Handler(Catch), installHandler, keyboardSignal)
import Control.Concurrent (ThreadId, myThreadId)
import System.Exit (ExitCode(ExitFailure))
resetScreen :: IO ()
resetScreen = do
clearScreen
setCursorPosition 0 0
withInterruptHandler :: IO () -> IO ()
withInterruptHandler body = do
tid <- myThreadId
_ <- installHandler keyboardSignal (Catch (handleInterrupt tid)) Nothing
body
handleInterrupt :: ThreadId -> IO ()
handleInterrupt tid = do
resetScreen
showCursor
throwTo tid $ ExitFailure code
where
code = signalToInt $ 128 + keyboardSignal
signalToInt s = read $ show s :: Int

View File

@ -40,6 +40,7 @@ library
, regex-tdfa
, terminal-progress-bar
, ansi-terminal
, unix
default-language: Haskell2010
executable unused