packages feed

console-style 0.0.1.1 → 0.0.2.0

raw patch · 2 files changed

+109/−78 lines, 2 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- System.Console.Style: styleCode :: (MonadState s m, HasStyle s, Foldable f) => f SetStyle -> m String
- System.Console.Style: styleCode' :: Foldable f => Style -> f SetStyle -> (Style, String)
+ System.Console.Style: applyStyle :: (MonadIO m, MonadState s m, HasStyle s) => m ()
+ System.Console.Style: applyStyleCode :: (MonadState s m, HasStyle s) => m String
+ System.Console.Style: changeStyle :: (MonadState s m, HasStyle s, Foldable f) => f SetStyle -> m ()
+ System.Console.Style: runStyleT :: Monad m => Term -> StateT Style m a -> m a
+ System.Console.Style: setStyleCode :: (MonadState s m, HasStyle s, Foldable f) => f SetStyle -> m String

Files

console-style.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           console-style-version:        0.0.1.1+version:        0.0.2.0 synopsis:       Styled console text output using ANSI escape sequences. description:    Styled console text output using ANSI escape sequences. category:       Text, User Interfaces, Monad
src/System/Console/Style.hs view
@@ -14,8 +14,8 @@ -- This makes it easy to use this library for a pretty printer with -- nested annotations, e.g., wl-pprint-console. ----- Warning: Windows supports is currently not implemented, but--- is planned (by using ansi-terminal or by directly using the ffi).+-- Warning: Windows support is currently not implemented, but+-- is planned (by using ansi-terminal or the ffi). -- -- Example: --@@ -49,11 +49,14 @@   hRunStyle,   hRunWithStyle,   runStyle,+  runStyleT,   runWithStyle,   setStyle,-  styleCode',-  styleCode,+  setStyleCode,   withStyle,+  changeStyle,+  applyStyle,+  applyStyleCode, ) where  import Data.Foldable (toList)@@ -64,9 +67,11 @@ import System.IO (Handle, stdout, hPutStr, hIsTerminalDevice) import System.Environment (getEnv) import Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty +-- | Console color data Color-  = DefaultColor+  = DefaultColor                  -- ^ Default terminal color (terminal specific)   | Black   | Red   | Green@@ -83,31 +88,39 @@   | DullMagenta   | DullCyan   | DullWhite-  | Color256 !Word8-  | RGB      !Word8 !Word8 !Word8+  | Color256 !Word8               -- ^ Color from 256 color scheme. Color is automatically degraded to 8 colors for older terminals.+  | RGB      !Word8 !Word8 !Word8 -- ^ True color. Color is automatically degraded to 256 or 8 colors for older terminals.   deriving (Eq, Ord, Show) -data Term = TermDumb | Term8 | Term256 | TermRGB | TermWin+-- | Terminal type. For older terminals the style is automatically degraded.+data Term+  = TermDumb -- ^ Dumb terminal - no color output+  | Term8    -- ^ 8 colors supported+  | Term256  -- ^ 256 colors supported+  | TermRGB  -- ^ True colors supported+  | TermWin  -- ^ Windows terminal. Will use emulation (Not yet implemented).   deriving (Eq, Show) +-- | Style commands data SetStyle-  = Bold-  | NotBold-  | Italic-  | NotItalic-  | Under-  | NotUnder-  | Invert-  | NotInvert-  | Save-  | Restore-  | Reset-  | Blink-  | NotBlink+  = Bold           -- ^ Bold font+  | NotBold        -- ^ Normal-weight font+  | Italic         -- ^ Italic font+  | NotItalic      -- ^ Non-italic font+  | Under          -- ^ Underlined text+  | NotUnder       -- ^ Text without underline+  | Invert         -- ^ Invert foreground and background color+  | NotInvert      -- ^ Deactivate color inversion+  | Save           -- ^ Save style to stack+  | Restore        -- ^ Restore style from stack+  | Reset          -- ^ Reset to default style+  | Blink          -- ^ Activate blinking+  | NotBlink       -- ^ Deactivate blinking   | FgColor !Color   | BgColor !Color   deriving (Eq, Ord, Show) +-- | State accessor for the 'Style' class HasStyle s where   getStyle :: s -> Style   putStyle :: Style -> s -> s@@ -116,8 +129,11 @@   getStyle = id   putStyle = const +-- | Abstract state datatype which keeps+-- a stack of the applied styles. data Style = Style   { styleStack  :: !(NonEmpty StyleState)+  , styleActive :: !StyleState   , styleHandle :: !Handle   , styleTerm   :: !Term   }@@ -132,10 +148,10 @@   , styleBg     :: !Color   } deriving (Eq, Ord, Show) --- | The action @(hGetTerm handle)@ determines the terminal type of the file handle @handle@.+-- | The action @(hGetTerm handle)@ determines the terminal type of the file @handle@. -- -- The terminal type is determined by checking if the file handle points to a device--- and by looking at the $TERM environment variable.+-- and by looking at the @$TERM@ environment variable. hGetTerm :: MonadIO m => Handle -> m Term hGetTerm h = liftIO $ do   term <- hIsTerminalDevice h@@ -143,7 +159,7 @@     then envToTerm  <$> getEnv "TERM"     else pure TermDumb --- | Determine the terminal type from the value of the $TERM environment variable.+-- | Determine the terminal type from the value of the @$TERM@ environment variable. -- TODO improve this envToTerm :: String -> Term envToTerm "dumb" = TermDumb@@ -152,18 +168,19 @@                | otherwise = Term8   where rgbTerminals = ["xterm", "konsole", "gnome", "st", "linux"] --- | @(hDefaultStyle handle term) return the default (initial) style configured+-- | @(hDefaultStyle handle term) return the default (initial) 'Style' configured -- with the file handle @handle@ and terminal type @term@. ----- Every style has a single associated handle.+-- Every 'Style' has a single associated handle. hDefaultStyle :: Handle -> Term -> Style hDefaultStyle h t = Style   { styleStack  = pure defaultStyleState   , styleHandle = h   , styleTerm   = t+  , styleActive = defaultStyleState   } --- | @(defaultStyle term)@ returns the default style configured with terminal type @term@.+-- | The function @(defaultStyle term)@ returns the default 'Style' configured with terminal type @term@. defaultStyle :: Term -> Style defaultStyle = hDefaultStyle stdout @@ -179,68 +196,46 @@   }  -- | The action @(hRunStyle handle action)@ runs the 'StateT' monad transformer providing--- the active style for the given @action@.+-- the active 'Style' for the given @action@. hRunStyle :: MonadIO m => Handle -> StateT Style m a -> m a hRunStyle h x = hDefaultStyle h <$> hGetTerm h >>= evalStateT x  -- | The action @(runStyle term action)@ runs the 'State' monad providing--- the active style for the given @action@.+-- the active 'Style' for the given @action@. runStyle :: Term -> State Style a -> a runStyle = flip evalState . defaultStyle +-- | The action @(runStyleT term action)@ runs the 'StateT' monad transformer providing+-- the active 'Style' for the given @action@.+runStyleT :: Monad m => Term -> StateT Style m a -> m a+runStyleT = flip evalStateT . defaultStyle+ -- | The action @(runWithStyle cmd action)@ runs the 'StateT' monad transformer providing--- the active style for the given @action@.+-- the active 'Style' for the given @action@. ----- The output on 'stdout' within the @action@ is modified by the given style commands @cmd@.--- The style is restored to the defaults afterwards.+-- The output on 'stdout' within the @action@ is modified by the given 'StyleSet' commands @cmd@.+-- The 'Style' is restored to the defaults afterwards. runWithStyle :: (MonadIO m, Foldable f) => f SetStyle -> StateT Style m a -> m a runWithStyle = hRunWithStyle stdout  -- | The action @(hRunWithStyle handle cmd action)@ runs the 'StateT' monad transformer providing--- the active style for the given @action@.+-- the active 'Style' for the given @action@. ----- The output on @handle@ within the @action@ is modified by the given style commands @cmd@.--- The style is restored to the defaults afterwards.+-- The output on @handle@ within the @action@ is modified by the given 'StyleSet' commands @cmd@.+-- The 'Style' is restored to the defaults afterwards. hRunWithStyle :: (MonadIO m, Foldable f) => Handle -> f SetStyle -> StateT Style m a -> m a-hRunWithStyle h style action = hRunStyle h $ withStyle style action---- | The function @(styleCode' style cmd)@ returns the modified style status and ANSI code--- corresponding to the style commands @cmd@.-styleCode' :: Foldable f => Style -> f SetStyle -> (Style, String)-styleCode' style cmd = (style', sgrCode style style')-  where style' = updateStyle cmd style---- | The action @(styleCode cmd)@ returns the ANSI code corresponding to the style commands @cmd@.--- This action must be executed within a monadic context providing the current style status.-styleCode :: (MonadState s m, HasStyle s, Foldable f) => f SetStyle -> m String-styleCode cmd = do-  style <- gets getStyle-  let (style', str) = styleCode' style cmd-  modify $ putStyle style'-  pure str---- | The action @(setStyle cmd)@ modifies the current style by executing the style commands @cmd@.-setStyle :: (MonadIO m, MonadState s m, HasStyle s, Foldable f) => f SetStyle -> m ()-setStyle cmd = do-  style <- gets getStyle-  let style' = updateStyle cmd style-  liftIO $ hPutStr (styleHandle style) $ sgrCode style style'-  modify $ putStyle style'+hRunWithStyle h cmd action = hRunStyle h $ withStyle cmd action --- | The action @(withStyle cmd action)@ executes the @action@ with the current style modified--- by the style commands @cmd@.+-- | The action @(changeStyle cmd)@ modifies the active 'Style' by executing the 'StyleSet' commands @cmd@+-- without applying the changes. ----- The style is restored to the previously active style afterwards.-withStyle :: (MonadIO m, MonadState s m, HasStyle s, Foldable f) => f SetStyle -> m a -> m a-withStyle cmd action = do-  setStyle (Save : toList cmd)-  ret <- action-  setStyle [Restore]-  pure ret--updateStyle :: Foldable f => f SetStyle -> Style -> Style-updateStyle cmd (Style stack h t) = Style (foldl go stack cmd) h t-  where go (_:|(x:xs)) Restore     = x :| xs+-- You have to call applyStyle or applyStyleCode afterwards!+changeStyle :: (MonadState s m, HasStyle s, Foldable f) => f SetStyle -> m ()+changeStyle cmd = do+  style <- gets getStyle+  modify $ putStyle $ new style+  where new style = style { styleStack = foldl go (styleStack style) cmd }+        go (_:|(x:xs)) Restore     = x :| xs         go (_:|[])     Restore     = pure defaultStyleState         go (x:|xs)     Save        = x :| (x:xs)         go (_:|xs)     Reset       = defaultStyleState :| xs@@ -257,6 +252,41 @@         go (x:|xs)     (BgColor c) = x { styleBg     = c     } :| xs         go (x:|xs)     (FgColor c) = x { styleFg     = c     } :| xs +-- | The action @applyStyle@ applies the latest style changes.+applyStyle :: (MonadIO m, MonadState s m, HasStyle s) => m ()+applyStyle = do+  h <- gets (styleHandle . getStyle)+  applyStyleCode >>= liftIO . hPutStr h++-- | The action @applyStyleCode@ returns the ANSI code for the latest style changes.+applyStyleCode :: (MonadState s m, HasStyle s) => m String+applyStyleCode = do+  style <- gets getStyle+  let style' = style { styleActive = NonEmpty.head $ styleStack style }+  modify $ putStyle style'+  pure $ sgrCode (styleTerm style) (styleActive style) (styleActive style')++-- | The action @(styleCode cmd)@ returns the ANSI code corresponding to the 'StyleSet' commands @cmd@.+setStyleCode :: (MonadState s m, HasStyle s, Foldable f) => f SetStyle -> m String+setStyleCode cmd = changeStyle cmd >> applyStyleCode++-- | The action @(setStyle cmd)@ modifies the active 'Style' by executing the 'StyleSet' commands @cmd@.+--+-- The style changes are applied immediately.+setStyle :: (MonadIO m, MonadState s m, HasStyle s, Foldable f) => f SetStyle -> m ()+setStyle cmd = changeStyle cmd >> applyStyle++-- | The action @(withStyle cmd action)@ executes the @action@ with the active 'Style' modified+-- by the 'StyleSet' commands @cmd@.+--+-- The style is restored to the previous 'Style' afterwards.+withStyle :: (MonadIO m, MonadState s m, HasStyle s, Foldable f) => f SetStyle -> m a -> m a+withStyle cmd action = do+  setStyle (Save : toList cmd)+  ret <- action+  setStyle [Restore]+  pure ret+ reduceColor :: Term -> Color -> Color reduceColor Term8    = reduceColor8 reduceColor Term256  = reduceColor256@@ -321,11 +351,12 @@ csi :: Char -> [Word8] -> String csi cmd args = "\ESC[" ++ intercalate ";" (map show args) ++ pure cmd -sgrCode :: Style -> Style -> String-sgrCode (Style _ _ TermDumb) _ = ""-sgrCode (Style _ _ TermWin)  _ = ""-sgrCode (Style (old:|_) _ t) (Style (new:|_) _ _)-  | old /= new && new == defaultStyleState = csi 'm' [0]+sgrCode :: Term -> StyleState -> StyleState -> String+sgrCode TermDumb _ _ = ""+sgrCode TermWin  _ _ = ""+sgrCode t old new+  | old == new = ""+  | new == defaultStyleState = csi 'm' []   | otherwise = csi 'm' $     flag   styleBlink  5  ++     flag   styleBold   1  ++