diff --git a/benchmark.tsv b/benchmark.tsv index 644a5e3..0103b7d 100644 --- a/benchmark.tsv +++ b/benchmark.tsv @@ -9,3 +9,12 @@ Terminal.app 10000 196143 25064408 241916 iTerm2 10000 4065856 49872777 28259948 IntelliJ IDEA 10000 71267 2453094 154491 Hyper 10000 16287473 57534790 20040066 +QTerminal 10000 26220 4127641 37446 +linux 10000 15470 75190 16107 +WezTerm 10000 1174129 6400318 3461548 +kitty 10000 1412243 6343324 3137705 +Rio 10000 36940 1626094 56959 +rxvt-unicode 10000 27900 11974885 37092 +QMLKonsole 10000 25010 969482 27317 +cool-retro-term 10000 28070 3457008 35218 +Terminology 10000 30570 620351 36248 diff --git a/doc/latency.md b/doc/latency.md index f24c950..1a3eaf1 100644 --- a/doc/latency.md +++ b/doc/latency.md @@ -1,18 +1,27 @@ # Latency Measurements generated using [examples/benchmark](../examples/benchmark/src/main.rs): -| Terminal | Iterations | min | max | mean | -|---------------------|------------|--------------|---------------|--------------| -| foot | 10000 | 26.130 µs | 248.260 µs | 31.825 µs | -| XTerm | 10000 | 33.550 µs | 295.990 µs | 39.926 µs | -| Konsole | 10000 | 34.110 µs | 3.652145 ms | 38.094 µs | -| Alacritty | 10000 | 40.340 µs | 414.961 µs | 57.569 µs | -| IntelliJ IDEA | 10000 | 71.267 µs | 2.453094 ms | 154.491 µs | -| Terminal.app | 10000 | 196.143 µs | 25.064408 ms | 241.916 µs | -| Hyper | 10000 | 16.287473 ms | 57.534790 ms | 20.040066 ms | -| GNOME Console (vte) | 10000 | 8.157828 ms | 56.823240 ms | 20.656316 ms | -| VSCode | 10000 | 24.164008 ms | 140.036258 ms | 26.061349 ms | -| iTerm2 | 10000 | 4.065856 ms | 49.872777 ms | 28.259948 ms | +| Terminal | Iterations | min | max | mean | supported | +|---------------------|------------|--------------|---------------|--------------|-----------| +| foot | 10000 | 26.130 µs | 248.260 µs | 31.825 µs | yes | +| XTerm | 10000 | 33.550 µs | 295.990 µs | 39.926 µs | yes | +| Konsole | 10000 | 34.110 µs | 3.652145 ms | 38.094 µs | yes | +| Alacritty | 10000 | 40.340 µs | 414.961 µs | 57.569 µs | yes | +| IntelliJ IDEA | 10000 | 71.267 µs | 2.453094 ms | 154.491 µs | yes | +| Terminal.app | 10000 | 196.143 µs | 25.064408 ms | 241.916 µs | yes | +| Hyper | 10000 | 16.287473 ms | 57.534790 ms | 20.040066 ms | yes | +| GNOME Console (vte) | 10000 | 8.157828 ms | 56.823240 ms | 20.656316 ms | yes | +| VSCode | 10000 | 24.164008 ms | 140.036258 ms | 26.061349 ms | yes | +| iTerm2 | 10000 | 4.065856 ms | 49.872777 ms | 28.259948 ms | yes | +| QTerminal | 10000 | 26.22 µs | 4.127641 ms | 37.446 µs | no | +| linux | 10000 | 15.47 µs | 75.19 µs | 16.107 µs | no | +| WezTerm | 10000 | 1.174129 ms | 6.400318 ms | 3.461548 ms | yes | +| kitty | 10000 | 1.412243 ms | 6.343324 ms | 3.137705 ms | yes | +| Rio | 10000 | 36.94 µs | 1.626094 ms | 56.959 µs | yes | +| rxvt-unicode | 10000 | 27.9 µs | 11.97489 ms | 37.092 µs | yes | +| QMLKonsole | 10000 | 25.01 µs | 0.969482 ms | 27.317 µs | no | +| cool-retro-term | 10000 | 28.07 µs | 3.457008 ms | 35.218 µs | no | +| Terminology | 10000 | 30.57 µs | 0.620351 ms | 36.248 µs | yes | **ℹ️ Note:** The macOS terminals were not tested on the same machine as the Linux terminals. diff --git a/doc/terminal-survey.md b/doc/terminal-survey.md index eccf1b8..9898bd0 100644 --- a/doc/terminal-survey.md +++ b/doc/terminal-survey.md @@ -1,36 +1,56 @@ A list of terminals that were tested for support of DA1 (`CSI c`) and `OSC 10` / `OSC 11`. -| Terminal | DA1 | Foreground | Background | Version Tested | -|-----------------------|-----|------------|------------|----------------------------| -| Jetbrains Fleet | yes | no | no | build 1.29.213 (macOS) | -| macOS Terminal | yes | yes | yes | Version 2.13 (447) | -| iTerm2 | yes | yes | yes | Build 3.5.0beta18 | -| Alacritty | yes | yes | yes | Version 0.13.1 (1) (macOS) | -| VSCode (xterm.js) | yes | yes | yes | 1.85.1 (macOS) | -| iSH (hterm) | yes | no | no | 1.3.2 (Build 494) (iOS) | -| IntelliJ IDEA | yes | yes | yes | PyCharm 2023.3.2 (macOS) | -| [Contour] | yes | yes | yes | 0.4.1.6292 (macOS) | -| GNOME Terminal (vte) | yes | yes | yes | 3.50.1 | -| (GNOME) Console (vte) | yes | yes | yes | 45.0 | -| Konsole | yes | yes | yes | 23.08.4 | -| [QTerminal] | yes | no | no | 1.3.0 | -| [foot] | yes | yes | yes | 1.16.1 | -| xterm | yes | yes | yes | 385 | -| Linux console | yes | no | no | - | -| Windows Terminal | yes | no | no | 1.18.3181.0 | -| Windows Console Host | yes | no | no | Windows 10.0.22631.2428 | -| PuTTY | yes | no | no | 0.80 | -| Hyper | yes | yes | yes | 3.4.1 (macOS) | -| ConEmu / Cmder | yes | no | no | 230724 stable | -| Mintty | yes | yes | yes | 3.6.1 | +| Terminal | DA1 | Foreground | Background | Version Tested | +|-----------------------|------|------------|------------|------------------------------------| +| Jetbrains Fleet | yes | no | no | build 1.29.213 (macOS) | +| macOS Terminal | yes | yes | yes | Version 2.13 (447) | +| iTerm2 | yes | yes | yes | Build 3.5.0beta18 | +| Alacritty | yes | yes | yes | Version 0.13.1 (1) (macOS) | +| VSCode (xterm.js) | yes | yes | yes | 1.85.1 (macOS) | +| iSH (hterm) | yes | no | no | 1.3.2 (Build 494) (iOS) | +| IntelliJ IDEA | yes | yes | yes | PyCharm 2023.3.2 (macOS) | +| [Contour] | yes | yes | yes | 0.4.1.6292 (macOS) | +| GNOME Terminal (vte) | yes | yes | yes | 3.50.1 | +| (GNOME) Console (vte) | yes | yes | yes | 45.0 | +| Konsole | yes | yes | yes | 23.08.4 | +| [QTerminal] | yes | no | no | 1.3.0 | +| [foot] | yes | yes | yes | 1.16.1 | +| xterm | yes | yes | yes | 385 | +| Linux console | yes | no | no | - | +| Windows Terminal | yes | no | no | 1.18.3181.0 | +| Windows Console Host | yes | no | no | Windows 10.0.22631.2428 | +| PuTTY | yes | no | no | 0.80 | +| Hyper | yes | yes | yes | 3.4.1 (macOS) | +| ConEmu / Cmder | yes | no | no | 230724 stable | +| Mintty | yes | yes | yes | 3.6.1 | +| [WezTerm] | yes | yes | yes | 20240203-110809-5046fc22 (flatpak) | +| [kitty] | yes | yes | yes | 0.31.0 | +| [Rio Terminal] | yes | yes | yes | 0.0.36 (wayland) | +| [rxvt-unicode] | yes | yes | yes | 9.31 | +| QMLKonsole | yes | no | no | 23.08.5 | +| mrxvt | yes | no | no | 0.5.3 | +| Eterm | no ⚠️ | no | no | 0.9.6 | +| [cool-retro-term] | yes | no | no | 1.2.0 | +| [anyterm] | no ⚠️ | no | no | 1.2.3 | +| [shellinabox] | no ⚠️ | no | no | 2.20 | +| [Terminology] | yes | yes [^1] | yes | 1.13.0 |
**ℹ️ Note:** Some Linux terminals are omitted since they all use the `vte` library behind the scenes. \ -Here's a non-exhaustive list: GNOME Terminal, (GNOME) Console, MATE Terminal, XFCE Terminal, (GNOME) Builder, (elementary) Terminal, LXTerminal. +Here's a non-exhaustive list: GNOME Terminal, (GNOME) Console, MATE Terminal, XFCE Terminal, (GNOME) Builder, (elementary) Terminal, LXTerminal, Guake. +[^1]: The response does not use the `XParseColor` format but rather a CSS-like hex code (e.g. `#AAAAAA`). [Contour]: https://contour-terminal.org/ [QTerminal]: https://github.com/lxqt/qterminal [foot]: https://codeberg.org/dnkl/foot +[WezTerm]: https://wezfurlong.org/wezterm/ +[kitty]: https://sw.kovidgoyal.net/kitty/ +[Rio Terminal]: https://raphamorim.io/rio/ +[rxvt-unicode]: http://software.schmorp.de/pkg/rxvt-unicode.html +[cool-retro-term]: https://github.com/Swordfish90/cool-retro-term +[anyterm]: https://anyterm.org/ +[shellinabox]: https://github.com/shellinabox/shellinabox +[Terminology]: http://www.enlightenment.org/ diff --git a/examples/benchmark/src/main.rs b/examples/benchmark/src/main.rs index f77f29d..6e74f36 100644 --- a/examples/benchmark/src/main.rs +++ b/examples/benchmark/src/main.rs @@ -5,7 +5,7 @@ use std::fs::OpenOptions; use std::hint::black_box; use std::io::{self, Write as _}; use std::time::{Duration, Instant}; -use terminal_colorsaurus::{color_scheme, QueryOptions, Result}; +use terminal_colorsaurus::{color_scheme, Error, QueryOptions, Result}; #[derive(Parser, Debug)] struct Args { @@ -46,8 +46,10 @@ fn main() -> Result<()> { fn bench() -> Result { let start = Instant::now(); - let _ = black_box(color_scheme(QueryOptions::default()))?; - Ok(start.elapsed()) + match black_box(color_scheme(QueryOptions::default())) { + Ok(_) | Err(Error::UnsupportedTerminal) => Ok(start.elapsed()), + Err(err) => Err(err), + } } fn save_results(results: &[Duration], term: String) -> io::Result<()> { diff --git a/src/color.rs b/src/color.rs index 3baf4ea..dc2d5c5 100644 --- a/src/color.rs +++ b/src/color.rs @@ -57,6 +57,22 @@ impl Color { let b = parse_channel(parts.next()?)?; Some(Color { r, g, b }) } + + // Some terminals (only Terminology found so far) respond with a + // CSS-like hex color code. + #[cfg(unix)] + pub(crate) fn parse_css_like(input: &str) -> Option { + let raw_parts = input.strip_prefix('#')?; + let len = raw_parts.len(); + if len == 6 { + let r = parse_channel(&raw_parts[..2])?; + let g = parse_channel(&raw_parts[2..4])?; + let b = parse_channel(&raw_parts[4..])?; + Some(Color { r, g, b }) + } else { + None + } + } } #[cfg(unix)] @@ -100,6 +116,7 @@ fn luminance_to_perceived_lightness(luminance: f64) -> u8 { } #[cfg(test)] +#[allow(clippy::unwrap_used)] mod tests { use super::*; @@ -118,4 +135,17 @@ mod tests { }; assert_eq!(100, black.perceived_lightness()) } + + #[test] + #[cfg(unix)] + fn parses_css_like_color() { + assert_eq!( + Color { + r: 171 << 8, + g: 205 << 8, + b: 239 << 8 + }, + Color::parse_css_like("#ABCDEF").unwrap() + ) + } } diff --git a/src/xterm.rs b/src/xterm.rs index 2e75d86..e23f33c 100644 --- a/src/xterm.rs +++ b/src/xterm.rs @@ -74,7 +74,7 @@ fn parse_response(response: String, prefix: &str) -> Result { .strip_suffix('\x07') .or(response.strip_suffix("\x1b\\")) }) - .and_then(Color::parse_x11) + .and_then(|c| Color::parse_x11(c).or_else(|| Color::parse_css_like(c))) .ok_or_else(|| Error::Parse(response)) }