pub fn supports_term_progress(is_terminal: bool) -> bool {
if !is_terminal {
return false;
}
let term_features = std::env::var("TERM_FEATURES")
.ok()
.map(|v| term_features_has_progress(&v))
.unwrap_or(false);
if term_features {
return true;
}
let term_program = std::env::var("TERM_PROGRAM").ok();
if matches!(term_program.as_deref(), Some("WezTerm") | Some("ghostty")) {
return true;
}
if std::env::var("WT_SESSION").is_ok() {
return true;
}
if std::env::var("ConEmuANSI").ok() == Some("ON".into()) {
return true;
}
let ptyxis = std::env::var("PTYXIS_VERSION")
.ok()
.and_then(|version| version.split(".").next()?.parse::<i32>().ok())
.map(|major_version| major_version >= 48)
.unwrap_or(false);
if ptyxis {
return true;
}
false
}
fn term_features_has_progress(value: &str) -> bool {
let mut current = String::new();
for ch in value.chars() {
if !ch.is_ascii_alphanumeric() {
break;
}
if ch.is_ascii_uppercase() {
if current == "P" {
return true;
}
current.clear();
current.push(ch);
} else {
current.push(ch);
}
}
current == "P"
}
#[cfg(test)]
mod tests {
use super::term_features_has_progress;
#[test]
fn term_features_progress_detection() {
assert!(term_features_has_progress("MBT2ScP"));
assert!(!term_features_has_progress("MBT2Sc"));
}
}