use {
crate::kitty::KittyGraphicsDisplay,
cli_log::*,
std::env,
};
#[allow(unreachable_code)]
pub fn detect_kitty_graphics_protocol_display() -> KittyGraphicsDisplay {
debug!("is_kitty_graphics_protocol_supported ?");
#[cfg(not(unix))]
{
debug!("no kitty support yet on Windows");
return KittyGraphicsDisplay::None;
}
for env_var in ["TERM", "TERMINAL"] {
if let Ok(env_val) = env::var(env_var) {
debug!("${env_var} = {env_val:?}");
let env_val = env_val.to_ascii_lowercase();
if env_val.contains("kitty") {
debug!(" -> this terminal seems to be Kitty");
return KittyGraphicsDisplay::Direct;
}
}
}
if let Ok(env_val) = env::var("TERM") {
debug!("$TERM = {env_val:?}");
if env_val == "xterm-ghostty" {
debug!(" -> this terminal seems to be Ghostty");
return KittyGraphicsDisplay::Direct;
}
}
if let Ok(term_program) = env::var("TERM_PROGRAM") {
debug!("$TERM_PROGRAM = {term_program:?}");
if term_program == "WezTerm" {
if let Ok(version) = env::var("TERM_PROGRAM_VERSION") {
debug!("$TERM_PROGRAM_VERSION = {version:?}");
if &*version < "20220105-201556-91a423da" {
debug!("WezTerm's version predates Kitty Graphics protocol support");
} else {
debug!("this looks like a compatible version");
return KittyGraphicsDisplay::Direct;
}
} else {
warn!("$TERM_PROGRAM_VERSION unexpectedly missing");
}
} else if term_program == "ghostty" {
debug!("Ghostty implements Kitty Graphics protocol");
return KittyGraphicsDisplay::Direct;
} else if term_program == "iTerm.app" {
if let Ok(version) = env::var("TERM_PROGRAM_VERSION") {
debug!("$TERM_PROGRAM_VERSION = {version:?}");
if &*version < "3.6.6" {
debug!("iTerm2's version predates Kitty Graphics protocol support");
} else {
debug!("this looks like a compatible version");
return KittyGraphicsDisplay::Direct;
}
} else {
warn!("$TERM_PROGRAM_VERSION unexpectedly missing");
}
}
}
#[cfg(feature = "kitty-csi-check")]
{
let start = std::time::Instant::now();
const TIMEOUT_MS: u64 = 200;
let response = xterm_query::query_osc(
"\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\\x1b[c",
TIMEOUT_MS,
);
let s = match response {
Err(e) => {
debug!("xterm querying failed: {}", e);
KittyGraphicsDisplay::None
}
Ok(response) if response == "_Gi=31;OK" => KittyGraphicsDisplay::Direct,
Ok(_) => KittyGraphicsDisplay::None,
};
debug!("Xterm querying took {:?}", start.elapsed());
debug!("kitty protocol support: {:?}", s);
return s;
}
KittyGraphicsDisplay::None
}
#[allow(unreachable_code)]
pub fn is_tmux() -> bool {
debug!("is_tmux ?");
for env_var in ["TERM", "TERMINAL"] {
if let Ok(env_val) = env::var(env_var) {
debug!("${env_var} = {env_val:?}");
let env_val = env_val.to_ascii_lowercase();
if env_val.contains("tmux") {
debug!(" -> this terminal seems to be Tmux");
return true;
}
}
}
false
}
pub fn get_tmux_nest_count() -> u32 {
std::env::var("TMUX_NEST_COUNT")
.map(|s| str::parse(&s).unwrap_or(1))
.unwrap_or(1)
}
#[allow(unreachable_code)]
pub fn is_ssh() -> bool {
debug!("is_ssh ?");
for env_var in ["SSH_CLIENT", "SSH_CONNECTION"] {
if env::var(env_var).is_ok() {
debug!(" -> this seems to be under SSH");
return true;
}
}
false
}