The coloring-stream library

The coloring-stream module provides a means for writing text to the console or terminal with colors and varying intensity.

On Unix, this is typically done via ANSI codes. Windows support is yet to be implemented.

Usage

It is implemented as a <wrapper-stream>, so it can wrap any given stream. While it can be created via make, it is easiest to just call colorize-stream on a stream to get back a <coloring-stream> wrapper that can be used to output color.

If the underlying stream doesn’t support color, then the returned <coloring-stream> will silently drop all text attributes.

Once you have a <coloring-stream>, you can set text attributes by writing instances of <text-attributes>. Text attributes are created with text-attributes. Text can have a foreground color, a background color and an intensity:

let error-attributes = text-attributes(foreground: $color-red);
let blinding-attributes = text-attributes(foreground: $color-green,
                                          background: $color-red,
                                          intensity: $bright-intensity);

To reset text back to the defaults, use the predefined $reset-attributes constant.

Text attributes can be stored and used repeatedly. This lets you set up some stylized text attributes and re-use them.

The text attributes can be written to the stream in two different ways:

Once you have a <coloring-stream>, then you can write colorized text to it with format:

let error-attributes = text-attributes(foreground: $color-red);
let cs = colorize-stream(*standard-output*);
format(cs, "%=Error:%= %s", error-attributes, $reset-attributes, error-message);

This is implemented by providing an implementation of print specialized on <text-attributes> and <coloring-stream>.

This can be used directly as well:

let error-attributes = text-attributes(foreground: $color-red);
let cs = colorize-stream(*standard-output*);
print(error-attributes, cs);
print("Error:", cs);
print($reset-attributes, cs);
print(' ', cs);
print(error-message, cs);

The COLORING-STREAM module

<coloring-stream> Abstract Class
Superclasses:<wrapper-stream>
Discussion:<coloring-stream> is the abstract wrapper stream that is used to determine whether or not a stream supports color output to avoid having to check at every write.
colorize-stream Generic function
Signature:

colorize-stream (stream #key force-ansi?) => (coloring-stream)

Parameters:
  • stream – An instance of <stream>.
  • force-ansi? (#key) – An instance of <boolean>.
Values:
Discussion:

Wrap a stream with an appropriate instance of <coloring-stream>. It uses stream-supports-color? to determine whether or not the underlying stream supports color output.

When force-ansi? is #t, then the usual checks are skipped and a coloring stream that generates ANSI output is created. This is useful when outputting to a string prior to writing the text to *standard-output* or when writing a network server where the user may have an ANSI-capable client.

When called on a <coloring-stream>, if force-ansi? is set and the stream is not an ANSI coloring stream, then the stream will be unwrapped and a new ANSI coloring stream wrapper will be created. Otherwise, calling colorize-stream on a <coloring-stream> will return the same stream.

Example:
let stream = colorize-stream(*standard-output*);

Or, using force-ansi?:

let text
  = with-output-to-string (s :: <byte-string-stream>)
      let force-ansi? = stream-supports-color?(*standard-output*);
      let s = colorize-stream(s, force-ansi?: force-ansi?);
      ...
    end with-output-to-string;
write(*standard-output*, text);
stream-supports-color? Open Generic function
Signature:

stream-supports-color? (stream) => (well?)

Parameters:
Values:
Discussion:

Return whether or not the underlying stream supports color output.

This checks that:

  • The stream is a <file-stream>.
  • stream-console? is true. (On Unix, this means that isatty is true for the stream.)
  • The TERM environment variable is not "dumb".
  • The EMACS environment variable is not "t".

stream-supports-ansi-color? Open Generic function
Signature:

stream-supports-ansi-color? (stream) => (well?)

Parameters:
Values:
Discussion:

Return whether or not the underlying stream might support ANSI color output, assuming that the underlying stream supports color output at all.

On Unix, this will always return #t.

On Windows, this attempts to detect situations where ANSI output would be permissible, such as running within an alternate console window like ConEMU.

Note

This does NOT check to see if the stream actually supports coloring. It is meant to be used in conjunction with stream-supports-color?.

Text Attributes

<text-attributes> Class
Superclasses:

<object>

Init-Keywords:
  • background – An instance of false-or(<text-color>).
  • foreground – An instance of false-or(<text-color>).
  • intensity – An instance of false-or(<text-intensity>).
Discussion:

Instances of <text-attributes> are used for representing the desired text appearance. They can be passed to format when writing to a <coloring-stream>.

background and foreground, if given, should be one of the color constants like $color-red, $color-green, etc.

intensity, if given, should be one of $bright-intensity, $dim-intensity or $normal-intensity.

Values that are omitted are set to the default values for the terminal.

text-attributes Function
Signature:

text-attributes (#key foreground background intensity) => (attributes)

Parameters:
  • foreground (#key) – An instance of false-or(<text-color>).
  • background (#key) – An instance of false-or(<text-color>).
  • intensity (#key) – An instance of false-or(<text-intensity>).
Values:
Discussion:

text-attributes provides an easy wrapper for creating instances of <text-attributes>.

background and foreground, if given, should be one of the color constants like $color-red, $color-green, etc.

intensity, if given, should be one of $bright-intensity, $dim-intensity or $normal-intensity.

Values that are omitted are set to the default values for the terminal.

Example:
let error-attributes = text-attributes(foreground: $color-red);
$reset-attributes Constant
Type:<text-attributes>
Discussion:A predefined constant to reset the text back to the default attributes.

This is equivalent to text-attributes(intensity: $normal-intensity).

Text Intensity

$bright-intensity Constant
$dim-intensity Constant
Discussion:

Note

Not all terminals support dimmed text.

$normal-intensity Constant

Text Colors

$color-black Constant
$color-blue Constant
$color-cyan Constant
$color-default Constant
$color-green Constant
$color-magenta Constant
$color-red Constant
$color-white Constant
$color-yellow Constant