use std::sync::OnceLock;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum TerminalType {
Kitty,
Iterm2,
#[default]
Unknown,
}
static TERMINAL_TYPE: OnceLock<TerminalType> = OnceLock::new();
pub fn terminal_type() -> TerminalType {
*TERMINAL_TYPE.get_or_init(|| {
if is_kitty_terminal() {
return TerminalType::Kitty;
}
if is_iterm2_terminal() {
return TerminalType::Iterm2;
}
TerminalType::Unknown
})
}
fn is_kitty_terminal() -> bool {
std::env::var("KITTY_WINDOW_ID").is_ok()
|| std::env::var("KITTY_PID").is_ok()
|| std::env::var("TERM_PROGRAM")
.map(|v| v.to_lowercase() == "kitty")
.unwrap_or(false)
}
fn is_iterm2_terminal() -> bool {
std::env::var("TERM_PROGRAM")
.map(|v| v.to_lowercase() == "iterm.app")
.unwrap_or(false)
|| std::env::var("LC_TERMINAL")
.map(|v| v.to_lowercase() == "iterm2")
.unwrap_or(false)
}
pub fn is_sixel_capable() -> bool {
is_sixel_capable_auto()
}
fn is_sixel_capable_auto() -> bool {
if let Ok(term) = std::env::var("TERM") {
let term_lower = term.to_lowercase();
term_lower.contains("mlterm")
|| term_lower.contains("yaft")
|| term_lower.contains("foot")
|| term_lower.contains("contour")
|| term_lower.contains("sixel")
|| term_lower.contains("vt340")
|| term_lower.contains("vt384")
} else {
false
}
}