use std::sync::OnceLock;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum TerminalProtocol {
Sixel,
Kitty,
TextFallback,
}
static PROTOCOL: OnceLock<TerminalProtocol> = OnceLock::new();
pub fn init(p: TerminalProtocol) {
_ = PROTOCOL.set(p);
}
pub fn protocol() -> TerminalProtocol {
*PROTOCOL.get().unwrap_or(&TerminalProtocol::TextFallback)
}
pub fn protocol_name(p: TerminalProtocol) -> &'static str {
match p {
TerminalProtocol::Sixel => "sixel",
TerminalProtocol::Kitty => "kitty",
TerminalProtocol::TextFallback => "text-fallback",
}
}
pub fn detect() -> TerminalProtocol {
if let Ok(force) = std::env::var("MCRAW_FORCE_PROTOCOL") {
match force.to_lowercase().as_str() {
"kitty" => return TerminalProtocol::Kitty,
"sixel" => return TerminalProtocol::Sixel,
"text" => return TerminalProtocol::TextFallback,
_ => {} }
}
let term = std::env::var("TERM").unwrap_or_default();
let term_program = std::env::var("TERM_PROGRAM").unwrap_or_default();
if std::env::var("KITTY_WINDOW_ID").is_ok()
|| std::env::var("KITTY_PID").is_ok()
|| term == "xterm-kitty"
{
return TerminalProtocol::Kitty;
}
if term_program == "Ghostty" {
return TerminalProtocol::Kitty;
}
if term_program == "vscode" {
return TerminalProtocol::Kitty;
}
if std::env::var("WEZTERM_EXECUTABLE").is_ok() {
return TerminalProtocol::Kitty;
}
if term_program == "iTerm.app" {
return TerminalProtocol::Kitty;
}
if std::env::var("KONSOLE_VERSION").is_ok() {
return TerminalProtocol::Kitty;
}
if term_program == "WarpTerminal" || std::env::var("WARP_IS_LOCAL_SHELL_SESSION").is_ok() {
return TerminalProtocol::Kitty;
}
if term_program == "Rio" {
return TerminalProtocol::Kitty;
}
if term_program == "Apple_Terminal" {
return TerminalProtocol::Kitty;
}
if term_program == "Tabby" {
return TerminalProtocol::Kitty;
}
if term.contains("sixel") {
return TerminalProtocol::Sixel;
}
if term == "foot" || term.starts_with("foot-") {
return TerminalProtocol::Sixel;
}
if term == "contour" {
return TerminalProtocol::Sixel;
}
if term == "mlterm" {
return TerminalProtocol::Sixel;
}
if (std::env::var("MSYSTEM").is_ok() || std::env::var("MINGW_PREFIX").is_ok())
&& (term.starts_with("xterm") || term == "cygwin")
{
return TerminalProtocol::Sixel;
}
if std::env::var("WT_SESSION").is_ok() {
return TerminalProtocol::Sixel;
}
if std::env::var("ConEmuPID").is_ok() || std::env::var("ConEmuHWND").is_ok() {
return TerminalProtocol::Sixel;
}
TerminalProtocol::TextFallback
}