Input may contain tabs and other characters whose byte widths do not
correspond to their display widths. This causes error context
underlining to be off when lines contain those characters
Fixed by properly accounting for the display width of characters, as
well as replacing tabs with spaces when printing error messages.
This is a pretty gross commit, since it also includes a lot of
unrelated refactoring, especially of how error messages are printed.
Also adds a lint recipe that prints lines over 100 characters
To test, I added a `--color=[auto|always|never]` option that defaults to
auto in normal use, but can be forced to `always` for testing. In `auto`
mode it defers to `atty` to figure out if the current stream is a
terminal and uses color if so.
Color printing is controlled by the `alternate` formatting flag.
When printing an error message, using `{:#}` will print it with colors
and `{}` will print it normally.