diff --git a/app/Main.hs b/app/Main.hs index 6fe389f..be22207 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -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 diff --git a/src/Unused/CLI/Util.hs b/src/Unused/CLI/Util.hs index f509a25..178a41e 100644 --- a/src/Unused/CLI/Util.hs +++ b/src/Unused/CLI/Util.hs @@ -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 diff --git a/unused.cabal b/unused.cabal index 5953e2d..fdea707 100644 --- a/unused.cabal +++ b/unused.cabal @@ -40,6 +40,7 @@ library , regex-tdfa , terminal-progress-bar , ansi-terminal + , unix default-language: Haskell2010 executable unused