diff --git a/CHANGELOG.md b/CHANGELOG.md index 485b510..2e37297 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ `colourista` uses [PVP Versioning][1]. The changelog is available [on GitHub][2]. +## 0.2.0.0 + +* [#26](https://github.com/kowainik/colourista/issues/26): + Support enabling and disable of colouring with implicit parameters. + + __Migration guide:__ You can continue using `colourista` without + changing anything and you still get colourful formatting. + + However, if you want to enable or disable colouring, you need to add + the `HasColourMode =>` constraint to all functions that format data + or call such formatting functions, and set the value of the + `?colourMode` variable in the beginning of your application. + ## 0.1.0.0 — May 2, 2020 🌈 * [#22](https://github.com/kowainik/colourista/issues/22): diff --git a/README.md b/README.md index aa633c6..35d40f0 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,16 @@ > > — Coco Chanel -`colourista` is the library that provides a convenient interface for printing -colourful messages to the terminal. It is based on -[`ansi-terminal`](https://hackage.haskell.org/package/ansi-terminal), however, -in contradistinction to this Haskell library, `colourista` is a high-level -wrapper focused on easily achieved output modification without low-level setup. +`colourista` is the library that provides a simple and convenient +interface for printing colourful messages to the +terminal. Additionally, `colourista` allows to easily control enabling +and disabling of colours. + +The library is based on +[`ansi-terminal`](https://hackage.haskell.org/package/ansi-terminal), +however, in contradistinction to this Haskell library, `colourista` is +a high-level wrapper focused on easily achieved output modification +without low-level setup. ## Interface @@ -32,10 +37,17 @@ The two main functions that `colourista` provides are: The library also provides a set of different pure and impure helpers for the colouring and emphasis. -## Example +## Examples + +Simple output example: ![output](https://user-images.githubusercontent.com/8126674/74609327-0a5dbb00-50e1-11ea-8c4b-2db4ab5b42a2.png) +Example of disabling colouring. The colour mode controlling is based on the +[Implicit Parameters](https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#implicit-parameters) GHC feature. + +![Colour mode](https://user-images.githubusercontent.com/4276606/90915207-0c2d7180-e3d7-11ea-934c-ec840118ed73.png) + ## How to use `colourista` is compatible with the latest GHC compiler versions starting from `8.2.2`. diff --git a/colourista.cabal b/colourista.cabal index 6ac93d5..3da0896 100644 --- a/colourista.cabal +++ b/colourista.cabal @@ -1,8 +1,17 @@ cabal-version: 2.4 name: colourista -version: 0.1.0.0 -synopsis: Convenient interface for printing colourful messages -description: Convenient interface for printing colourful messages based on the @ansi-terminal@ library. +version: 0.2.0.0 +synopsis: Simple and convenient interface for colourful outputting +description: + Convenient interface for printing colourful messages based on the @ansi-terminal@ library. + Supports enabling and disabling of colouring based on + the [Implicit Parameters](https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#implicit-parameters) + GHC feature. + . + Usage and output example: + . + * ![Example](https://user-images.githubusercontent.com/4276606/90915207-0c2d7180-e3d7-11ea-934c-ec840118ed73.png) + homepage: https://github.com/kowainik/colourista bug-reports: https://github.com/kowainik/colourista/issues license: MPL-2.0 @@ -28,12 +37,14 @@ library hs-source-dirs: src exposed-modules: Colourista Colourista.IO + Colourista.Mode Colourista.Pure Colourista.Short build-depends: base >= 4.10.1.0 && < 4.15 , ansi-terminal ^>= 0.10 , bytestring ^>= 0.10 + , ghc-prim >= 0.5 && < 0.7 , text ^>= 1.2.3.0 ghc-options: -Wall diff --git a/src/Colourista.hs b/src/Colourista.hs index dce8ea2..2b57041 100644 --- a/src/Colourista.hs +++ b/src/Colourista.hs @@ -14,9 +14,12 @@ module Colourista -- $pure , module Colourista.IO -- $io + , module Colourista.Mode + -- $mode ) where import Colourista.IO +import Colourista.Mode import Colourista.Pure @@ -29,3 +32,8 @@ customisation: colouring and emphasis. The set of functions that work in 'IO' to output formatted messages directly to terminal. -} + +{- $mode +'ColourMode' data type that allows disabling and enabling colouring +based on the implicit @?colourMode@ parameter in scope. +-} diff --git a/src/Colourista/IO.hs b/src/Colourista/IO.hs index 7160cf5..6acc2fe 100644 --- a/src/Colourista/IO.hs +++ b/src/Colourista/IO.hs @@ -37,6 +37,8 @@ import Data.Semigroup (Semigroup (..)) #endif import Data.Text (Text) +import Colourista.Mode (HasColourMode) + import qualified Data.Text.IO as TIO import qualified Colourista.Pure as Colourista @@ -46,42 +48,42 @@ import qualified Colourista.Pure as Colourista ---------------------------------------------------------------------------- -- | Print 'Text' coloured in 'Colourista.red'. -redMessage :: Text -> IO () +redMessage :: HasColourMode => Text -> IO () redMessage = formattedMessage [Colourista.red] {-# INLINE redMessage #-} -- | Print 'Text' coloured in 'Colourista.green'. -greenMessage :: Text -> IO () +greenMessage :: HasColourMode => Text -> IO () greenMessage = formattedMessage [Colourista.green] {-# INLINE greenMessage #-} -- | Print 'Text' coloured in 'Colourista.blue'. -blueMessage :: Text -> IO () +blueMessage :: HasColourMode => Text -> IO () blueMessage = formattedMessage [Colourista.blue] {-# INLINE blueMessage #-} -- | Print 'Text' coloured in 'Colourista.yellow'. -yellowMessage :: Text -> IO () +yellowMessage :: HasColourMode => Text -> IO () yellowMessage = formattedMessage [Colourista.yellow] {-# INLINE yellowMessage #-} -- | Print 'Text' coloured in 'Colourista.black'. -blackMessage :: Text -> IO () +blackMessage :: HasColourMode => Text -> IO () blackMessage = formattedMessage [Colourista.black] {-# INLINE blackMessage #-} -- | Print 'Text' coloured in 'Colourista.white'. -whiteMessage :: Text -> IO () +whiteMessage :: HasColourMode => Text -> IO () whiteMessage = formattedMessage [Colourista.white] {-# INLINE whiteMessage #-} -- | Print 'Text' coloured in 'Colourista.magenta'. -magentaMessage :: Text -> IO () +magentaMessage :: HasColourMode => Text -> IO () magentaMessage = formattedMessage [Colourista.magenta] {-# INLINE magentaMessage #-} -- | Print 'Text' coloured in 'Colourista.cyan'. -cyanMessage :: Text -> IO () +cyanMessage :: HasColourMode => Text -> IO () cyanMessage = formattedMessage [Colourista.cyan] {-# INLINE cyanMessage #-} @@ -93,7 +95,7 @@ cyanMessage = formattedMessage [Colourista.cyan] <> -} -successMessage :: Text -> IO () +successMessage :: HasColourMode => Text -> IO () successMessage t = greenMessage $ " ✔ " <> t {-# INLINE successMessage #-} @@ -101,7 +103,7 @@ successMessage t = greenMessage $ " ✔ " <> t <> -} -infoMessage :: Text -> IO () +infoMessage :: HasColourMode => Text -> IO () infoMessage t = blueMessage $ " ⓘ " <> t {-# INLINE infoMessage #-} @@ -109,7 +111,7 @@ infoMessage t = blueMessage $ " ⓘ " <> t <> -} -skipMessage :: Text -> IO () +skipMessage :: HasColourMode => Text -> IO () skipMessage t = cyanMessage $ " ▶ " <> t {-# INLINE skipMessage #-} @@ -117,7 +119,7 @@ skipMessage t = cyanMessage $ " ▶ " <> t <> -} -warningMessage :: Text -> IO () +warningMessage :: HasColourMode => Text -> IO () warningMessage t = yellowMessage $ " ⚠ " <> t {-# INLINE warningMessage #-} @@ -125,7 +127,7 @@ warningMessage t = yellowMessage $ " ⚠ " <> t <> -} -errorMessage :: Text -> IO () +errorMessage :: HasColourMode => Text -> IO () errorMessage t = redMessage $ " \128721 " <> t {-# INLINE errorMessage #-} @@ -134,12 +136,12 @@ errorMessage t = redMessage $ " \128721 " <> t ---------------------------------------------------------------------------- -- | Print 'Text' emphasized with 'Colourista.bold'. -boldMessage :: Text -> IO () +boldMessage :: HasColourMode => Text -> IO () boldMessage = formattedMessage [Colourista.bold] {-# INLINE boldMessage #-} -- | Print 'Text' emphasized with 'Colourista.italic'. -italicMessage :: Text -> IO () +italicMessage :: HasColourMode => Text -> IO () italicMessage = formattedMessage [Colourista.italic] {-# INLINE italicMessage #-} @@ -153,6 +155,6 @@ list, no formatting is applied. ![formattedMessage-example](https://user-images.githubusercontent.com/4276606/74608898-e6987600-50dc-11ea-9a93-bda701fd3c43.png) -} -formattedMessage :: [Text] -> Text -> IO () +formattedMessage :: HasColourMode => [Text] -> Text -> IO () formattedMessage formatting = TIO.putStrLn . Colourista.formatWith formatting {-# INLINE formattedMessage #-} diff --git a/src/Colourista/Mode.hs b/src/Colourista/Mode.hs new file mode 100644 index 0000000..224ab90 --- /dev/null +++ b/src/Colourista/Mode.hs @@ -0,0 +1,108 @@ +{-# OPTIONS_GHC -fno-warn-orphans #-} + +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE ImplicitParams #-} +{-# LANGUAGE MultiParamTypeClasses #-} + +{- | +Copyright: (c) 2020 Kowainik +SPDX-License-Identifier: MPL-2.0 +Maintainer: Kowainik + +The 'ColourMode' data type that allows disabling and enabling of +colouring. Implemented using the [Implicit Parameters](https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#implicit-parameters) +GHC feature. + +By default, all formatting and printing functions in @colourista@ +print with colour. However, you control this behaviour by adding the +@HasColourMode@ constraint to your functions and setting the value of +the implicit @?colourMode@ variable. + +@since 0.2.0.0 +-} + +module Colourista.Mode + ( ColourMode (..) + , HasColourMode + , withColourMode + , handleColourMode + ) where + +import System.IO (Handle) +import System.Console.ANSI (hSupportsANSIWithoutEmulation) +import Data.String (IsString) + +import GHC.Classes (IP (..)) + + +{- | Data type that tells whether the colouring is enabled or +disabled. It's used with the @-XImplicitParams@ GHC extension. + +@since 0.2.0.0 +-} +data ColourMode + = DisableColour + | EnableColour + deriving stock (Show, Eq, Enum, Bounded) + +{- | Magic instance to set the value of the implicit variable +@?colourMode@ to 'EnableColour' by default. Equivalent to the +following code: + +@ +?colourMode = 'EnableColour' +@ + +However, you still can override @?colourMode@ with any possible value. + +@since 0.2.0.0 +-} +instance IP "colourMode" ColourMode where + ip = EnableColour + +{- | Constraint that stores 'ColourMode' as an implicit parameter. + +@since 0.2.0.0 +-} +type HasColourMode = (?colourMode :: ColourMode) + +{- | Helper function for writing custom formatter. The function takes +'ColourMode' from the implicit parameter context and either returns a +given string or an empty string. + +@since 0.2.0.0 +-} +withColourMode :: (HasColourMode, IsString str) => str -> str +withColourMode str = case ?colourMode of + EnableColour -> str + DisableColour -> "" +{-# INLINE withColourMode #-} + +{- | Returns 'ColourMode' of a 'Handle'. You can use this function on +output 'Handle's to find out whether they support colouring or +now. Use this function like this to check whether you can print with +colour to terminal: + +@ +'handleColourMode' 'System.IO.stdout' +@ + +Typical usage can look like this: + +@ +main :: IO () +main = do + colourMode <- 'handleColourMode' 'System.IO.stdout' + let ?colourMode = fromMaybe 'DisableColour' + 'Colourista.IO.successMessage' "Success!" +@ + +@since 0.2.0.0 +-} +handleColourMode :: Handle -> IO (Maybe ColourMode) +handleColourMode handle = do + supportsANSI <- hSupportsANSIWithoutEmulation handle + pure $ fmap + (\supportsColour -> if supportsColour then EnableColour else DisableColour) + supportsANSI diff --git a/src/Colourista/Pure.hs b/src/Colourista/Pure.hs index fb21fca..00e3385 100644 --- a/src/Colourista/Pure.hs +++ b/src/Colourista/Pure.hs @@ -8,6 +8,7 @@ This module introduces helpful pure codes to customise the terminal output view. module Colourista.Pure ( formatWith + -- * Colour , red , green @@ -49,6 +50,8 @@ import System.Console.ANSI (Color (..), ColorIntensity (Vivid), ConsoleIntensity ConsoleLayer (Background, Foreground), SGR (..), Underlining (..), setSGRCode) +import Colourista.Mode (HasColourMode, withColourMode) + {- | General purpose function to format strings with multiple options. If this function takes empty list as an argument, no @@ -68,179 +71,179 @@ It is also not natively supported on Windows 10. -} formatWith - :: (IsString str, Semigroup str) + :: (HasColourMode, IsString str, Semigroup str) => [str] -> str -> str formatWith formatting str = case formatting of [] -> str x:xs -> sconcat (x :| xs) <> str <> reset -{-# SPECIALIZE formatWith :: [String] -> String -> String #-} -{-# SPECIALIZE formatWith :: [Text] -> Text -> Text #-} -{-# SPECIALIZE formatWith :: [ByteString] -> ByteString -> ByteString #-} +{-# SPECIALIZE formatWith :: HasColourMode => [String] -> String -> String #-} +{-# SPECIALIZE formatWith :: HasColourMode => [Text] -> Text -> Text #-} +{-# SPECIALIZE formatWith :: HasColourMode => [ByteString] -> ByteString -> ByteString #-} ---------------------------------------------------------------------------- -- Colours ---------------------------------------------------------------------------- -- | Code to apply 'Red' colouring for the terminal output. -red :: IsString str => str -red = fromString $ setSGRCode [SetColor Foreground Vivid Red] -{-# SPECIALIZE red :: String #-} -{-# SPECIALIZE red :: Text #-} -{-# SPECIALIZE red :: ByteString #-} +red :: (HasColourMode, IsString str) => str +red = withColourMode $ fromString $ setSGRCode [SetColor Foreground Vivid Red] +{-# SPECIALIZE red :: HasColourMode => String #-} +{-# SPECIALIZE red :: HasColourMode => Text #-} +{-# SPECIALIZE red :: HasColourMode => ByteString #-} -- | Code to apply 'Green' colouring for the terminal output. -green :: IsString str => str -green = fromString $ setSGRCode [SetColor Foreground Vivid Green] -{-# SPECIALIZE green :: String #-} -{-# SPECIALIZE green :: Text #-} -{-# SPECIALIZE green :: ByteString #-} +green :: (HasColourMode, IsString str) => str +green = withColourMode $ fromString $ setSGRCode [SetColor Foreground Vivid Green] +{-# SPECIALIZE green :: HasColourMode => String #-} +{-# SPECIALIZE green :: HasColourMode => Text #-} +{-# SPECIALIZE green :: HasColourMode => ByteString #-} -- | Code to apply 'Blue' colouring for the terminal output. -blue :: IsString str => str -blue = fromString $ setSGRCode [SetColor Foreground Vivid Blue] -{-# SPECIALIZE blue :: String #-} -{-# SPECIALIZE blue :: Text #-} -{-# SPECIALIZE blue :: ByteString #-} +blue :: (HasColourMode, IsString str) => str +blue = withColourMode $ fromString $ setSGRCode [SetColor Foreground Vivid Blue] +{-# SPECIALIZE blue :: HasColourMode => String #-} +{-# SPECIALIZE blue :: HasColourMode => Text #-} +{-# SPECIALIZE blue :: HasColourMode => ByteString #-} -- | Code to apply 'Yellow' colouring for the terminal output. -yellow :: IsString str => str -yellow = fromString $ setSGRCode [SetColor Foreground Vivid Yellow] -{-# SPECIALIZE yellow :: String #-} -{-# SPECIALIZE yellow :: Text #-} -{-# SPECIALIZE yellow :: ByteString #-} +yellow :: (HasColourMode, IsString str) => str +yellow = withColourMode $ fromString $ setSGRCode [SetColor Foreground Vivid Yellow] +{-# SPECIALIZE yellow :: HasColourMode => String #-} +{-# SPECIALIZE yellow :: HasColourMode => Text #-} +{-# SPECIALIZE yellow :: HasColourMode => ByteString #-} -- | Code to apply 'Black' colouring for the terminal output. -black :: IsString str => str -black = fromString $ setSGRCode [SetColor Foreground Vivid Black] -{-# SPECIALIZE black :: String #-} -{-# SPECIALIZE black :: Text #-} -{-# SPECIALIZE black :: ByteString #-} +black :: (HasColourMode, IsString str) => str +black = withColourMode $ fromString $ setSGRCode [SetColor Foreground Vivid Black] +{-# SPECIALIZE black :: HasColourMode => String #-} +{-# SPECIALIZE black :: HasColourMode => Text #-} +{-# SPECIALIZE black :: HasColourMode => ByteString #-} -- | Code to apply 'White' colouring for the terminal output. -white :: IsString str => str -white = fromString $ setSGRCode [SetColor Foreground Vivid White] -{-# SPECIALIZE white :: String #-} -{-# SPECIALIZE white :: Text #-} -{-# SPECIALIZE white :: ByteString #-} +white :: (HasColourMode, IsString str) => str +white = withColourMode $ fromString $ setSGRCode [SetColor Foreground Vivid White] +{-# SPECIALIZE white :: HasColourMode => String #-} +{-# SPECIALIZE white :: HasColourMode => Text #-} +{-# SPECIALIZE white :: HasColourMode => ByteString #-} -- | Code to apply 'Magenta' colouring for the terminal output. -magenta :: IsString str => str -magenta = fromString $ setSGRCode [SetColor Foreground Vivid Magenta] -{-# SPECIALIZE magenta :: String #-} -{-# SPECIALIZE magenta :: Text #-} -{-# SPECIALIZE magenta :: ByteString #-} +magenta :: (HasColourMode, IsString str) => str +magenta = withColourMode $ fromString $ setSGRCode [SetColor Foreground Vivid Magenta] +{-# SPECIALIZE magenta :: HasColourMode => String #-} +{-# SPECIALIZE magenta :: HasColourMode => Text #-} +{-# SPECIALIZE magenta :: HasColourMode => ByteString #-} -- | Code to apply 'Cyan' colouring for the terminal output. -cyan :: IsString str => str -cyan = fromString $ setSGRCode [SetColor Foreground Vivid Cyan] -{-# SPECIALIZE cyan :: String #-} -{-# SPECIALIZE cyan :: Text #-} -{-# SPECIALIZE cyan :: ByteString #-} +cyan :: (HasColourMode, IsString str) => str +cyan = withColourMode $ fromString $ setSGRCode [SetColor Foreground Vivid Cyan] +{-# SPECIALIZE cyan :: HasColourMode => String #-} +{-# SPECIALIZE cyan :: HasColourMode => Text #-} +{-# SPECIALIZE cyan :: HasColourMode => ByteString #-} ---------------------------------------------------------------------------- -- Background ---------------------------------------------------------------------------- -- | Code to apply 'Red' background colouring for the terminal output. -redBg :: IsString str => str -redBg = fromString $ setSGRCode [SetColor Background Vivid Red] -{-# SPECIALIZE redBg :: String #-} -{-# SPECIALIZE redBg :: Text #-} -{-# SPECIALIZE redBg :: ByteString #-} +redBg :: (HasColourMode, IsString str) => str +redBg = withColourMode $ fromString $ setSGRCode [SetColor Background Vivid Red] +{-# SPECIALIZE redBg :: HasColourMode => String #-} +{-# SPECIALIZE redBg :: HasColourMode => Text #-} +{-# SPECIALIZE redBg :: HasColourMode => ByteString #-} -- | Code to apply 'Green' background colouring for the terminal output. -greenBg :: IsString str => str -greenBg = fromString $ setSGRCode [SetColor Background Vivid Green] -{-# SPECIALIZE greenBg :: String #-} -{-# SPECIALIZE greenBg :: Text #-} -{-# SPECIALIZE greenBg :: ByteString #-} +greenBg :: (HasColourMode, IsString str) => str +greenBg = withColourMode $ fromString $ setSGRCode [SetColor Background Vivid Green] +{-# SPECIALIZE greenBg :: HasColourMode => String #-} +{-# SPECIALIZE greenBg :: HasColourMode => Text #-} +{-# SPECIALIZE greenBg :: HasColourMode => ByteString #-} -- | Code to apply 'Blue' background colouring for the terminal output. -blueBg :: IsString str => str -blueBg = fromString $ setSGRCode [SetColor Background Vivid Blue] -{-# SPECIALIZE blueBg :: String #-} -{-# SPECIALIZE blueBg :: Text #-} -{-# SPECIALIZE blueBg :: ByteString #-} +blueBg :: (HasColourMode, IsString str) => str +blueBg = withColourMode $ fromString $ setSGRCode [SetColor Background Vivid Blue] +{-# SPECIALIZE blueBg :: HasColourMode => String #-} +{-# SPECIALIZE blueBg :: HasColourMode => Text #-} +{-# SPECIALIZE blueBg :: HasColourMode => ByteString #-} -- | Code to apply 'Yellow' background colouring for the terminal output. -yellowBg :: IsString str => str -yellowBg = fromString $ setSGRCode [SetColor Background Vivid Yellow] -{-# SPECIALIZE yellowBg :: String #-} -{-# SPECIALIZE yellowBg :: Text #-} -{-# SPECIALIZE yellowBg :: ByteString #-} +yellowBg :: (HasColourMode, IsString str) => str +yellowBg = withColourMode $ fromString $ setSGRCode [SetColor Background Vivid Yellow] +{-# SPECIALIZE yellowBg :: HasColourMode => String #-} +{-# SPECIALIZE yellowBg :: HasColourMode => Text #-} +{-# SPECIALIZE yellowBg :: HasColourMode => ByteString #-} -- | Code to apply 'Black' background colouring for the terminal output. -blackBg :: IsString str => str -blackBg = fromString $ setSGRCode [SetColor Background Vivid Black] -{-# SPECIALIZE blackBg :: String #-} -{-# SPECIALIZE blackBg :: Text #-} -{-# SPECIALIZE blackBg :: ByteString #-} +blackBg :: (HasColourMode, IsString str) => str +blackBg = withColourMode $ fromString $ setSGRCode [SetColor Background Vivid Black] +{-# SPECIALIZE blackBg :: HasColourMode => String #-} +{-# SPECIALIZE blackBg :: HasColourMode => Text #-} +{-# SPECIALIZE blackBg :: HasColourMode => ByteString #-} -- | Code to apply 'White' background colouring for the terminal output. -whiteBg :: IsString str => str -whiteBg = fromString $ setSGRCode [SetColor Background Vivid White] -{-# SPECIALIZE whiteBg :: String #-} -{-# SPECIALIZE whiteBg :: Text #-} -{-# SPECIALIZE whiteBg :: ByteString #-} +whiteBg :: (HasColourMode, IsString str) => str +whiteBg = withColourMode $ fromString $ setSGRCode [SetColor Background Vivid White] +{-# SPECIALIZE whiteBg :: HasColourMode => String #-} +{-# SPECIALIZE whiteBg :: HasColourMode => Text #-} +{-# SPECIALIZE whiteBg :: HasColourMode => ByteString #-} -- | Code to apply 'Magenta' background colouring for the terminal output. -magentaBg :: IsString str => str -magentaBg = fromString $ setSGRCode [SetColor Background Vivid Magenta] -{-# SPECIALIZE magentaBg :: String #-} -{-# SPECIALIZE magentaBg :: Text #-} -{-# SPECIALIZE magentaBg :: ByteString #-} +magentaBg :: (HasColourMode, IsString str) => str +magentaBg = withColourMode $ fromString $ setSGRCode [SetColor Background Vivid Magenta] +{-# SPECIALIZE magentaBg :: HasColourMode => String #-} +{-# SPECIALIZE magentaBg :: HasColourMode => Text #-} +{-# SPECIALIZE magentaBg :: HasColourMode => ByteString #-} -- | Code to apply 'Cyan' background colouring for the terminal output. -cyanBg :: IsString str => str -cyanBg = fromString $ setSGRCode [SetColor Background Vivid Cyan] -{-# SPECIALIZE cyanBg :: String #-} -{-# SPECIALIZE cyanBg :: Text #-} -{-# SPECIALIZE cyanBg :: ByteString #-} +cyanBg :: (HasColourMode, IsString str) => str +cyanBg = withColourMode $ fromString $ setSGRCode [SetColor Background Vivid Cyan] +{-# SPECIALIZE cyanBg :: HasColourMode => String #-} +{-# SPECIALIZE cyanBg :: HasColourMode => Text #-} +{-# SPECIALIZE cyanBg :: HasColourMode => ByteString #-} ---------------------------------------------------------------------------- -- Emphasis ---------------------------------------------------------------------------- -- | Code to apply __bold__ emphasis for the terminal output. -bold :: IsString str => str -bold = fromString $ setSGRCode [SetConsoleIntensity BoldIntensity] -{-# SPECIALIZE bold :: String #-} -{-# SPECIALIZE bold :: Text #-} -{-# SPECIALIZE bold :: ByteString #-} +bold :: (HasColourMode, IsString str) => str +bold = withColourMode $ fromString $ setSGRCode [SetConsoleIntensity BoldIntensity] +{-# SPECIALIZE bold :: HasColourMode => String #-} +{-# SPECIALIZE bold :: HasColourMode => Text #-} +{-# SPECIALIZE bold :: HasColourMode => ByteString #-} -- | Code to apply /italic/ emphasis for the terminal output. -italic :: IsString str => str -italic = fromString $ setSGRCode [SetItalicized True] -{-# SPECIALIZE italic :: String #-} -{-# SPECIALIZE italic :: Text #-} -{-# SPECIALIZE italic :: ByteString #-} +italic :: (HasColourMode, IsString str) => str +italic = withColourMode $ fromString $ setSGRCode [SetItalicized True] +{-# SPECIALIZE italic :: HasColourMode => String #-} +{-# SPECIALIZE italic :: HasColourMode => Text #-} +{-# SPECIALIZE italic :: HasColourMode => ByteString #-} -- | Code to apply __underline__ emphasis for the terminal output. -underline :: IsString str => str -underline = fromString $ setSGRCode [SetUnderlining SingleUnderline] -{-# SPECIALIZE underline :: String #-} -{-# SPECIALIZE underline :: Text #-} -{-# SPECIALIZE underline :: ByteString #-} +underline :: (HasColourMode, IsString str) => str +underline = withColourMode $ fromString $ setSGRCode [SetUnderlining SingleUnderline] +{-# SPECIALIZE underline :: HasColourMode => String #-} +{-# SPECIALIZE underline :: HasColourMode => Text #-} +{-# SPECIALIZE underline :: HasColourMode => ByteString #-} {- | Code to apply __double underline__ emphasis for the terminal output. __⚠ Caution:__ This is not widely supported. It is not natively supported on Windows 10 -} -doubleUnderline :: IsString str => str -doubleUnderline = fromString $ setSGRCode [SetUnderlining DoubleUnderline] -{-# SPECIALIZE doubleUnderline :: String #-} -{-# SPECIALIZE doubleUnderline :: Text #-} -{-# SPECIALIZE doubleUnderline :: ByteString #-} +doubleUnderline :: (HasColourMode, IsString str) => str +doubleUnderline = withColourMode $ fromString $ setSGRCode [SetUnderlining DoubleUnderline] +{-# SPECIALIZE doubleUnderline :: HasColourMode => String #-} +{-# SPECIALIZE doubleUnderline :: HasColourMode => Text #-} +{-# SPECIALIZE doubleUnderline :: HasColourMode => ByteString #-} -- | Code to apply __no underline__ emphasis for the terminal output. -noUnderline :: IsString str => str -noUnderline = fromString $ setSGRCode [SetUnderlining NoUnderline] -{-# SPECIALIZE noUnderline :: String #-} -{-# SPECIALIZE noUnderline :: Text #-} -{-# SPECIALIZE noUnderline :: ByteString #-} +noUnderline :: (HasColourMode, IsString str) => str +noUnderline = withColourMode $ fromString $ setSGRCode [SetUnderlining NoUnderline] +{-# SPECIALIZE noUnderline :: HasColourMode => String #-} +{-# SPECIALIZE noUnderline :: HasColourMode => Text #-} +{-# SPECIALIZE noUnderline :: HasColourMode => ByteString #-} -- | Code to indent the terminal output by the given amount of spaces. indent :: (IsString str, Semigroup str) => Int -> str @@ -252,8 +255,8 @@ indent n {-# SPECIALIZE indent :: Int -> ByteString #-} -- | Code to reset all previous code applied for the terminal output. -reset :: IsString str => str -reset = fromString $ setSGRCode [Reset] -{-# SPECIALIZE reset :: String #-} -{-# SPECIALIZE reset :: Text #-} -{-# SPECIALIZE reset :: ByteString #-} +reset :: (HasColourMode, IsString str) => str +reset = withColourMode $ fromString $ setSGRCode [Reset] +{-# SPECIALIZE reset :: HasColourMode => String #-} +{-# SPECIALIZE reset :: HasColourMode => Text #-} +{-# SPECIALIZE reset :: HasColourMode => ByteString #-} diff --git a/src/Colourista/Short.hs b/src/Colourista/Short.hs index bc35a59..873d3bc 100644 --- a/src/Colourista/Short.hs +++ b/src/Colourista/Short.hs @@ -21,26 +21,27 @@ import Data.Semigroup (Semigroup) import Data.String (IsString) import Data.Text (Text) +import Colourista.Mode (HasColourMode) import Colourista.Pure (bold, formatWith, italic, underline) -- | Short alias for 'bold'. -b :: (IsString str, Semigroup str) => str -> str +b :: (HasColourMode, IsString str, Semigroup str) => str -> str b = formatWith [bold] -{-# SPECIALIZE b :: String -> String #-} -{-# SPECIALIZE b :: Text -> Text #-} -{-# SPECIALIZE b :: ByteString -> ByteString #-} +{-# SPECIALIZE b :: HasColourMode => String -> String #-} +{-# SPECIALIZE b :: HasColourMode => Text -> Text #-} +{-# SPECIALIZE b :: HasColourMode => ByteString -> ByteString #-} -- | Short alias for 'italic'. -i :: (IsString str, Semigroup str) => str -> str +i :: (HasColourMode, IsString str, Semigroup str) => str -> str i = formatWith [italic] -{-# SPECIALIZE i :: String -> String #-} -{-# SPECIALIZE i :: Text -> Text #-} -{-# SPECIALIZE i :: ByteString -> ByteString #-} +{-# SPECIALIZE i :: HasColourMode => String -> String #-} +{-# SPECIALIZE i :: HasColourMode => Text -> Text #-} +{-# SPECIALIZE i :: HasColourMode => ByteString -> ByteString #-} -- | Short alias for 'underline'. -u :: (IsString str, Semigroup str) => str -> str +u :: (HasColourMode, IsString str, Semigroup str) => str -> str u = formatWith [underline] -{-# SPECIALIZE u :: String -> String #-} -{-# SPECIALIZE u :: Text -> Text #-} -{-# SPECIALIZE u :: ByteString -> ByteString #-} +{-# SPECIALIZE u :: HasColourMode => String -> String #-} +{-# SPECIALIZE u :: HasColourMode => Text -> Text #-} +{-# SPECIALIZE u :: HasColourMode => ByteString -> ByteString #-} diff --git a/stack.yaml b/stack.yaml index 4fb1f2b..11d9ae6 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1 +1 @@ -resolver: lts-15.8 \ No newline at end of file +resolver: lts-16.10 \ No newline at end of file