Haskell: Colour highlighting when writing to the shell
I spent a few hours writing a simple front end on top of the Rabin Karp algorithm so that I could show the line of the first occurrence of a pattern in a piece of text on the shell.
I thought it would be quite cool if I could highlight the appropriate text on the line like how grep does when the ‘–color=auto’ flag is supplied.
We can make use of ANSI escape codes to do this.
We need to construct an escape sequence which starts with the ‘ESC’ character, represented by decimal value 27 or hexidecimal value 1b, followed by a left bracket (”[“):
"\x1b[" or "\27["
In the second part of the sequence we can choose a variety of different options. In this case we use the following:
CSI n [;k] m SGR – Select Graphic Rendition Sets SGR parameters, including text color. After CSI can be zero or more parameters separated with ;. With no parameters, CSI m is treated as CSI 0 m (reset / normal), which is typical of most of the ANSI escape sequences.
To change the colour of the text we need to set ‘k’ to one of the following values:
- 30 - Black
- 31 - Red
- 32 - Green
- 33 - Yellow
- 34 - Blue
- 35 - Magenta
- 36 - Cyan
- 37 - White
For example, if we want to print all future text in green then we can use the following escape sequence:
> putStrLn $ "\x1b[32m"
Ideally we should then reset the terminal which means passing a ‘k’ value of 0.
So if we just want to highlight one word we’d end up with this:
> putStrLn $ "\x1b[32m" ++ "highlight me" ++ "\x1b[0m" ++ " but not me"