hit-on-0.1.0.0: src/Hit/ColorTerminal.hs
-- | This module contains functions for colorful printing into terminal.
module Hit.ColorTerminal
( Color (..)
, putStrFlush
, beautyPrint
, bold
, boldText
, boldDefault
, italic
, reset
, setColor
, successMessage
, warningMessage
, errorMessage
, infoMessage
, skipMessage
-- * Colors
, redCode
, blueCode
, greenCode
, yellowCode
, cyanCode
, magentaCode
-- * Other formatters
, boldCode
, resetCode
, blueBg
-- * Input with prompt
, Answer (..)
, prompt
, arrow
) where
import System.Console.ANSI (Color (..), ColorIntensity (Dull, Vivid),
ConsoleIntensity (BoldIntensity), ConsoleLayer (Background, Foreground),
SGR (..), setSGR, setSGRCode)
import System.IO (hFlush)
import qualified Data.Text as T
-- | Explicit flush ensures prompt messages are in the correct order on all systems.
putStrFlush :: Text -> IO ()
putStrFlush msg = do
putText msg
hFlush stdout
setColor :: Color -> IO ()
setColor color = setSGR [SetColor Foreground Vivid color]
-- | Starts bold printing.
bold :: IO ()
bold = setSGR [SetConsoleIntensity BoldIntensity]
italic :: IO ()
italic = setSGR [SetItalicized True]
-- | Resets all previous settings.
reset :: IO ()
reset = do
setSGR [Reset]
hFlush stdout
-- | Takes list of formatting options, prints text using this format options.
beautyPrint :: [IO ()] -> Text -> IO ()
beautyPrint formats msg = do
sequence_ formats
putText msg
reset
boldText :: Text -> IO ()
boldText message = bold >> putStrFlush message >> reset
boldDefault :: Text -> IO ()
boldDefault message = boldText (" [" <> message <> "]")
colorMessage :: Color -> Text -> IO ()
colorMessage color message = do
setColor color
putTextLn $ " " <> message
reset
errorMessage, warningMessage, successMessage, infoMessage, skipMessage :: Text -> IO ()
errorMessage = colorMessage Red
warningMessage = colorMessage Yellow
successMessage = colorMessage Green
infoMessage = colorMessage Blue
skipMessage = colorMessage Cyan
redCode, blueCode, greenCode, yellowCode, cyanCode, magentaCode :: Text
redCode = mkColor Red
blueCode = mkColor Blue
greenCode = mkColor Green
yellowCode = mkColor Yellow
cyanCode = mkColor Cyan
magentaCode = mkColor Magenta
boldCode, resetCode, blueBg :: Text
boldCode = toText $ setSGRCode [SetConsoleIntensity BoldIntensity]
resetCode = toText $ setSGRCode [Reset]
blueBg = toText $ setSGRCode [SetColor Foreground Dull White, SetColor Background Dull Blue]
mkColor :: Color -> Text
mkColor color = toText $ setSGRCode [SetColor Foreground Vivid color]
-- | Arrow symbol
arrow :: Text
arrow = " ➤ "
-- | Represents a user's answer
data Answer = Y | N
-- | Parse an answer to 'Answer'
yesOrNo :: Text -> Maybe Answer
yesOrNo (T.toLower -> answer )
| T.null answer = Just Y
| answer `elem` ["yes", "y", "ys"] = Just Y
| answer `elem` ["no", "n"] = Just N
| otherwise = Nothing
prompt :: IO Answer
prompt = do
answer <- yesOrNo . T.strip <$> getLine
case answer of
Just ans -> pure ans
Nothing -> do
errorMessage "This wasn't a valid choice."
prompt