Skip to content

[RFC] Ability to disable and enable colouring #26

@chshersh

Description

@chshersh

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:

  1. Allows specifying the colour only in a single place in the application.
  2. Colours the text by default, if no option is specified.
  3. Doesn't involve code duplication.
  4. 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:

  1. Implement simple enum to control colouring mode.
    data ColourMode = EnableColour | DisableColour
  2. Introduce a constraint with implicit params:
    type HasColourMode = (?colourMode :: ColourMode)
  3. 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 #-}
  4. 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:

  1. All existing code should work without any changes.
  2. 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

  1. Each function that performs colouring or calls colouring function should add HasColourMode constraint.
  2. You don't have compile-time guarantees if you forget to add such constraint somewhere.
  3. This involves using non-common GHC feature.

Additionally we need to add tests for this:

  • Check that disabling colour mode actually disables colour codes

Metadata

Metadata

Assignees

Labels

questionFurther information is requested

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions