Üetliberg | Sneeuw at Warande

Colors in GHCi

Posted on Saturday, 27 February 2010 at 12:10.

Whenever you load a Haskell file into GHCi, it will either tell you your modules loaded fine, or that there were some errors. Sebas came with the awesome idea of coloring these messages green and red, respectively. Here is how to do this:

Create a script that looks like this:

#!/usr/bin/env bash

GREEN=`echo -e '\033[92m'`
RED=`echo -e '\033[91m'`
RESET=`echo -e '\033[0m'`

/usr/bin/ghci "${@}" |\
  sed "s/^Failed, modules loaded:/${RED}&${RESET}/g;s/^Ok, modules loaded:/${GREEN}&${RESET}/g"

If your ghci is not located in /usr/bin, change the path in the script accordingly. If you want, you can name your script ghci so that it takes over the original one. Just make sure its location appears in your PATH variable before the location of the true ghci.

If all goes well, you should now see colors whenever you load your modules:

% ghci Sirenial.Merge
...
Failed, modules loaded: Sirenial.Query.

And then when the bug has been fixed:

% ghci Sirenial.Merge
...
Ok, modules loaded: Sirenial.Merge, Sirenial.Query.

This has only been tested on Terminal.app in Snow Leopard. If it doesn’t work for your system, please leave a comment, with—if possible—a fix.

There is a small issue: sometimes sed delays the colored parts a bit, causing your prompt to be printed before the success or error message. Again, if you know a fix, please comment.

Comments

By Tom Lokhorst on Saturday, 27 February 2010 at 17:26:

This is very useful!

I’ve updated the script to also highlight warnings (as I usually launch ghci from vim with -Wall):

#!/usr/bin/env bash

YELLOW=`echo -e ‘33[93m’`
GREEN=`echo -e ‘33[92m’`
RED=`echo -e ‘33[91m’`
RESET=`echo -e ‘33[0m’`

/usr/bin/ghci “${@}” 2>&1 |\
sed “s/ Warning:/${YELLOW}&${RESET}/g;s/^Failed, modules loaded:/${RED}&${RESET}/g;s/^Ok, modules loaded:/${GREEN}&${RESET}/g”

I’m not happy with the fact that this merges the stdout and stderr, but I don’t know of a better way to do this.

By Erlend on Saturday, 27 February 2010 at 19:12:

Cool. Thanks!
Works perfectly on openSuse 11.2. :-)

By Orphi on Monday, 01 March 2010 at 12:59:

I still think GHCi should have this built-in. We already have ansi-terminal on Hackage, which does this in a [ahem] *portable* way. (Your examples don’t work on Windows, because it fails to grok ANSI escape sequences.)

By Nikolas Mayr on Wednesday, 03 March 2010 at 14:39:

Why are you using

#!/usr/bin/env bash

intead of

#!/bin/bash

?

By Martijn on Thursday, 24 June 2010 at 10:24:

@Orphi Yes, I agree. It shouldn’t be too hard.

@Nikolas Good question. I have no good reason for it.

Leave a comment!

Martijn loves to receive comments! Add yours by filling out the fields below.