It would be nice if colourista could support automatic disabling and enabling of colouring, so we can easily disable/enable colours in our code. We want to have a solution that satisfies the following requirements:
- Allows specifying the colour only in a single place in the application.
- Colours the text by default, if no option is specified.
- Doesn't involve code duplication.
- Doesn't require code recompilation to change colouring settings.
I'll describe one possible solution below.
-XImplicitParams
One way to do this is to use the ImplicitParams Haskell language extension. It contains the following parts:
- Implement simple enum to control colouring mode.
data ColourMode = EnableColour | DisableColour
- Introduce a constraint with implicit params:
type HasColourMode = (?colourMode :: ColourMode)
- Patch each function to pattern-math on a colour:
withColourMode :: (HasColourMode, IsString str) => str -> str
withColourMode = case ?colourMode of
EnableColour -> str
DisableColour -> ""
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 #-}
- Implement magic instance described in this blog post to make
EnableColour default:
-- ?color = EnableColor
instance IP "colourMode" ColourMode where
ip = EnableColour
Cons and pros
Implementation cost: patch each function.
Pros:
- All existing code should work without any changes.
- We can easily disable/enable colouring by defining a single variable in a single module after we parse
--no-colour option or something like this.
Cons
- Each function that performs colouring or calls colouring function should add
HasColourMode constraint.
- You don't have compile-time guarantees if you forget to add such constraint somewhere.
- This involves using non-common GHC feature.
Additionally we need to add tests for this:
It would be nice if
colouristacould support automatic disabling and enabling of colouring, so we can easily disable/enable colours in our code. We want to have a solution that satisfies the following requirements:I'll describe one possible solution below.
-XImplicitParams
One way to do this is to use the
ImplicitParamsHaskell language extension. It contains the following parts:EnableColourdefault:Cons and pros
Implementation cost: patch each function.
Pros:
--no-colouroption or something like this.Cons
HasColourModeconstraint.Additionally we need to add tests for this: