use super::{Capabilities, Graphics, Protocol};
impl Graphics {
pub fn detect() -> Option<Graphics> {
Capabilities::detect().best()
}
pub fn detect_for(destination: &impl std::io::IsTerminal) -> Option<Graphics> {
Capabilities::detect_for(destination).best()
}
}
pub(crate) fn sniff(variable: &impl Fn(&str) -> Option<String>) -> Vec<Protocol> {
if variable("TMUX").is_some() {
return Vec::new();
}
let term = variable("TERM").unwrap_or_default();
if term == "dumb" || term.starts_with("screen") || term.starts_with("tmux") {
return Vec::new();
}
if variable("KITTY_WINDOW_ID").is_some() || term.contains("kitty") || term.contains("ghostty") {
return vec![Protocol::Kitty];
}
let program = variable("TERM_PROGRAM")
.unwrap_or_default()
.to_ascii_lowercase();
if program.contains("ghostty") {
return vec![Protocol::Kitty];
}
if program.contains("iterm") || program.contains("wezterm") {
return vec![Protocol::ITerm2, Protocol::Sixel];
}
if term.contains("foot") {
return vec![Protocol::Sixel];
}
if variable("KONSOLE_VERSION").is_some_and(|v| v.parse::<u32>().is_ok_and(|v| v >= 220400)) {
return vec![Protocol::Sixel];
}
if variable("WT_SESSION").is_some() {
return vec![Protocol::Sixel];
}
Vec::new()
}
#[cfg(unix)]
pub(crate) fn cell_size() -> Option<(u16, u16)> {
use std::os::fd::AsFd;
fn from(fd: impl AsFd) -> Option<(u16, u16)> {
let size = rustix::termios::tcgetwinsize(fd).ok()?;
if size.ws_col == 0 || size.ws_row == 0 {
return None;
}
let cell = (size.ws_xpixel / size.ws_col, size.ws_ypixel / size.ws_row);
(cell.0 >= 2 && cell.1 >= 4).then_some(cell)
}
std::fs::File::open("/dev/tty")
.ok()
.and_then(from)
.or_else(|| from(std::io::stdout()))
}
#[cfg(not(unix))]
pub(crate) fn cell_size() -> Option<(u16, u16)> {
None
}
#[cfg(test)]
#[path = "tests/detect_tests.rs"]
mod tests;