crossterm-rs / crossterm

Cross platform terminal library rust
MIT License
3.19k stars 276 forks source link

Why are ansi 3/4 bit colors not supported? #844

Open markus-bauer opened 10 months ago

markus-bauer commented 10 months ago

It looks like it's currently not possible to output the standard 3/4 bit colors with crossterm.

I just assumed that crossterm's named colors map to those colors, but they actually use the 8-bit color format. For example Color::Red, doesn't produces the code 31 or 91, but 5;9:

println!("{:?}", SetForegroundColor(Color::Red).to_string())
"\u{1b}[38;5;9m"

Reference: https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit https://github.com/crossterm-rs/crossterm/blob/08762b3ef4519e7f834453bf91e3fe36f4c63fe7/src/style/types/colored.rs#L134

This is extra confusing since there is a separate Color::Ansi() variant, especially for that.

How can one output these default colors with crossterm? Why are 8-bit colors used for the 16 default colors?

thecaralice commented 5 months ago

AFAICS the 8-bit 0x00..0x0F and 3/4-bit colors are equivalent; the linked article mentions that:

As 256-color lookup tables became common on graphic cards, escape sequences were added to select from a pre-defined set of 256 colors:[citation needed]

ESC[38;5;⟨n⟩m Select foreground color      where n is a number from the table below
ESC[48;5;⟨n⟩m Select background color
  0-  7:  standard colors (as in ESC [ 30–37 m)
  8- 15:  high intensity colors (as in ESC [ 90–97 m)
 16-231:  6 × 6 × 6 cube (216 colors): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
232-255:  grayscale from dark to light in 24 steps
markus-bauer commented 4 months ago

Sorry, for responding so late.

Yes, the colors are equivalent.

If I remember correctly, my issue was more with the fact that crossterm doesn't let you choose which codes to emit, even though it has separate types for named colors and ansi colors.