anstyle_progress/query.rs
1/// Determines whether the terminal supports ANSI OSC 9;4.
2pub fn supports_term_progress(is_terminal: bool) -> bool {
3 let windows_terminal = std::env::var("WT_SESSION").is_ok();
4 let conemu = std::env::var("ConEmuANSI").ok() == Some("ON".into());
5 let wezterm = std::env::var("TERM_PROGRAM").ok() == Some("WezTerm".into());
6 let ghostty = std::env::var("TERM_PROGRAM").ok() == Some("ghostty".into());
7 // iTerm added OSC 9;4 support in v3.6.6, which we can check for.
8 // For context: https://github.com/rust-lang/cargo/pull/16506#discussion_r2706584034
9 let iterm = std::env::var("TERM_PROGRAM").ok() == Some("iTerm.app".into())
10 && std::env::var("TERM_FEATURES")
11 .ok()
12 .map(|v| term_features_has_progress(&v))
13 .unwrap_or(false);
14 // Ptyxis added OSC 9;4 support in 48.0.
15 // See https://gitlab.gnome.org/chergert/ptyxis/-/issues/305
16 let ptyxis = std::env::var("PTYXIS_VERSION")
17 .ok()
18 .and_then(|version| version.split(".").next()?.parse::<i32>().ok())
19 .map(|major_version| major_version >= 48)
20 .unwrap_or(false);
21
22 (windows_terminal || conemu || wezterm || ghostty || iterm || ptyxis) && is_terminal
23}
24
25// For iTerm, the TERM_FEATURES value "P" indicates OSC 9;4 support.
26// Context: https://iterm2.com/feature-reporting/
27fn term_features_has_progress(value: &str) -> bool {
28 let mut current = String::new();
29
30 for ch in value.chars() {
31 if !ch.is_ascii_alphanumeric() {
32 break;
33 }
34 if ch.is_ascii_uppercase() {
35 if current == "P" {
36 return true;
37 }
38 current.clear();
39 current.push(ch);
40 } else {
41 current.push(ch);
42 }
43 }
44 current == "P"
45}
46
47#[cfg(test)]
48mod tests {
49 use super::term_features_has_progress;
50
51 #[test]
52 fn term_features_progress_detection() {
53 // With PROGRESS feature ("P")
54 assert!(term_features_has_progress("MBT2ScP"));
55
56 // Without PROGRESS feature
57 assert!(!term_features_has_progress("MBT2Sc"));
58 }
59}