const OS_NAME: &[u8] = if cfg!(target_os = "macos") {
b"macos"
} else if cfg!(target_os = "linux") {
b"linux"
} else if cfg!(target_os = "windows") {
b"windows"
} else if cfg!(target_os = "freebsd") {
b"freebsd"
} else {
b"unknown"
};
#[derive(Clone, Copy, Debug)]
#[non_exhaustive]
pub enum CapValue {
None,
Bool,
Text(&'static [u8]),
Cols,
Rows,
OsName,
}
impl CapValue {
pub const TEXT_TN: Self = Self::Text(b"jetfish");
pub const TEXT_CO: Self = Self::Text(b"256");
pub const TEXT_PA: Self = Self::Text(b"32767");
pub const TEXT_RGB: Self = Self::Text(b"8/8/8");
pub const TEXT_IT: Self = Self::Text(b"8");
pub const TEXT_KITTY: Self = Self::Text(b"yes");
pub const TEXT_SETRGBF: Self = Self::Text(b"\x1b[38:2:%p1%d:%p2%d:%p3%dm");
pub const TEXT_SETRGBB: Self = Self::Text(b"\x1b[48:2:%p1%d:%p2%d:%p3%dm");
pub const TEXT_SETAF: Self = Self::Text(b"\x1b[38;5;%p1%dm");
pub const TEXT_SETAB: Self = Self::Text(b"\x1b[48;5;%p1%dm");
pub const TEXT_OP: Self = Self::Text(b"\x1b[39;49m");
pub const TEXT_OC: Self = Self::Text(b"\x1b]104\x07");
pub const TEXT_SMULX: Self = Self::Text(b"\x1b[4:%p1%dm");
pub const TEXT_SETULC: Self =
Self::Text(b"\x1b[58:2:%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%dm");
pub const TEXT_SS: Self = Self::Text(b"\x1b[%p1%d q");
pub const TEXT_SE: Self = Self::Text(b"\x1b[0 q");
pub const TEXT_CS: Self = Self::Text(b"\x1b]12;%p1%s\x07");
pub const TEXT_CR: Self = Self::Text(b"\x1b]112\x07");
pub const TEXT_SYNC: Self = Self::Text(b"\x1b[?2026%?%p1%{1}%-%tl%eh");
pub const TEXT_E3: Self = Self::Text(b"\x1b[3J");
pub const TEXT_CLEAR: Self = Self::Text(b"\x1b[H\x1b[2J");
pub const TEXT_CUP: Self = Self::Text(b"\x1b[%i%p1%d;%p2%dH");
pub const TEXT_SMKX: Self = Self::Text(b"\x1b[?1h\x1b=");
pub const TEXT_RMKX: Self = Self::Text(b"\x1b[?1l\x1b>");
pub const TEXT_SMCUP: Self = Self::Text(b"\x1b[?1049h");
pub const TEXT_RMCUP: Self = Self::Text(b"\x1b[?1049l");
pub const TEXT_SMACS: Self = Self::Text(b"\x1b(0");
pub const TEXT_RMACS: Self = Self::Text(b"\x1b(B");
pub const TEXT_ACSC: Self = Self::Text(b"``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~");
pub const TEXT_CIVIS: Self = Self::Text(b"\x1b[?25l");
pub const TEXT_CNORM: Self = Self::Text(b"\x1b[?25h");
pub const TEXT_KBS: Self = Self::Text(b"\x7f");
pub const TEXT_KDCH1: Self = Self::Text(b"\x1b[3~");
pub const TEXT_KICH1: Self = Self::Text(b"\x1b[2~");
pub const TEXT_KHOME: Self = Self::Text(b"\x1b[H");
pub const TEXT_KEND: Self = Self::Text(b"\x1b[F");
pub const TEXT_KCUU1: Self = Self::Text(b"\x1b[A");
pub const TEXT_KCUD1: Self = Self::Text(b"\x1b[B");
pub const TEXT_KCUB1: Self = Self::Text(b"\x1b[D");
pub const TEXT_KCUF1: Self = Self::Text(b"\x1b[C");
pub const TEXT_INDN: Self = Self::Text(b"\x1b[%p1%dS");
}
#[derive(Clone, Copy, Debug)]
pub struct Cap;
impl Cap {
pub const TN: &'static [u8] = b"TN";
pub const CO: &'static [u8] = b"Co";
pub const PA: &'static [u8] = b"pa";
pub const RGB: &'static [u8] = b"RGB";
pub const TC: &'static [u8] = b"Tc";
pub const COLS: &'static [u8] = b"co";
pub const ROWS: &'static [u8] = b"li";
pub const IT: &'static [u8] = b"it";
pub const AM: &'static [u8] = b"am";
pub const BCE: &'static [u8] = b"bce";
pub const CCC: &'static [u8] = b"ccc";
pub const XENL: &'static [u8] = b"xenl";
pub const XN: &'static [u8] = b"xn";
pub const XT: &'static [u8] = b"XT";
pub const XF: &'static [u8] = b"XF";
pub const SIXEL: &'static [u8] = b"sixel";
pub const ITERM2: &'static [u8] = b"iterm2";
pub const KITTY: &'static [u8] = b"kitty";
pub const SETAF: &'static [u8] = b"setaf";
pub const SETAB: &'static [u8] = b"setab";
pub const OP: &'static [u8] = b"op";
pub const OC: &'static [u8] = b"oc";
pub const SMULX: &'static [u8] = b"Smulx";
pub const SETULC: &'static [u8] = b"Setulc";
pub const SS: &'static [u8] = b"Ss";
pub const SE: &'static [u8] = b"Se";
pub const CS: &'static [u8] = b"Cs";
pub const CR: &'static [u8] = b"Cr";
pub const E3: &'static [u8] = b"E3";
pub const CLEAR: &'static [u8] = b"clear";
pub const CUP: &'static [u8] = b"cup";
pub const SMKX: &'static [u8] = b"smkx";
pub const RMKX: &'static [u8] = b"rmkx";
pub const SMCUP: &'static [u8] = b"smcup";
pub const RMCUP: &'static [u8] = b"rmcup";
pub const SMACS: &'static [u8] = b"smacs";
pub const RMACS: &'static [u8] = b"rmacs";
pub const CIVIS: &'static [u8] = b"civis";
pub const CNORM: &'static [u8] = b"cnorm";
pub const KBS: &'static [u8] = b"kbs";
pub const KDCH1: &'static [u8] = b"kdch1";
pub const KICH1: &'static [u8] = b"kich1";
pub const KHOME: &'static [u8] = b"khome";
pub const KEND: &'static [u8] = b"kend";
pub const KCUU1: &'static [u8] = b"kcuu1";
pub const KCUD1: &'static [u8] = b"kcud1";
pub const KCUB1: &'static [u8] = b"kcub1";
pub const KCUF1: &'static [u8] = b"kcuf1";
pub const INDN: &'static [u8] = b"indn";
pub const QUERY_OS_NAME: &'static [u8] = b"query-os-name";
pub const NONE: &'static [u8] = b"";
pub const UNSUPPORTED: &'static [u8] = b"unsupported";
pub const SETRGBF: &'static [u8] = b"setrgbf";
pub const SETRGBB: &'static [u8] = b"setrgbb";
pub const SYNC: &'static [u8] = b"sync";
pub const ACSC: &'static [u8] = b"acsc";
pub const NAME: &'static [u8] = b"name";
pub const COLORS: &'static [u8] = b"colors";
pub const PAIRS: &'static [u8] = b"pairs";
pub const COLUMNS: &'static [u8] = b"cols";
pub const LINES: &'static [u8] = b"lines";
pub const TK: &'static [u8] = b"TK";
pub const CL: &'static [u8] = b"cl";
pub const CM: &'static [u8] = b"cm";
pub const KS: &'static [u8] = b"ks";
pub const KE: &'static [u8] = b"ke";
pub const TI: &'static [u8] = b"ti";
pub const TE: &'static [u8] = b"te";
pub const AS: &'static [u8] = b"as";
pub const AE: &'static [u8] = b"ae";
pub const VI: &'static [u8] = b"vi";
pub const VE: &'static [u8] = b"ve";
pub fn parse(query: &[u8]) -> (&'static [u8], CapValue) {
match query {
Self::TN | Self::NAME => (Self::TN, CapValue::TEXT_TN),
Self::CO | Self::COLORS => (Self::CO, CapValue::TEXT_CO),
Self::PA | Self::PAIRS => (Self::PA, CapValue::TEXT_PA),
Self::RGB => (Self::RGB, CapValue::TEXT_RGB),
Self::TC => (Self::TC, CapValue::Bool),
Self::COLS | Self::COLUMNS => (Self::COLS, CapValue::Cols),
Self::ROWS | Self::LINES => (Self::ROWS, CapValue::Rows),
Self::IT => (Self::IT, CapValue::TEXT_IT),
Self::AM => (Self::AM, CapValue::Bool),
Self::BCE => (Self::BCE, CapValue::Bool),
Self::CCC => (Self::CCC, CapValue::Bool),
Self::XENL | Self::XN => (Self::XN, CapValue::Bool),
Self::XT => (Self::XT, CapValue::Bool),
Self::XF => (Self::XF, CapValue::Bool),
Self::SIXEL => (Self::SIXEL, CapValue::Bool),
Self::ITERM2 => (Self::ITERM2, CapValue::Bool),
Self::KITTY | Self::TK => (Self::KITTY, CapValue::TEXT_KITTY),
Self::SETRGBF => (Self::SETRGBF, CapValue::TEXT_SETRGBF),
Self::SETRGBB => (Self::SETRGBB, CapValue::TEXT_SETRGBB),
Self::SETAF => (Self::SETAF, CapValue::TEXT_SETAF),
Self::SETAB => (Self::SETAB, CapValue::TEXT_SETAB),
Self::OP => (Self::OP, CapValue::TEXT_OP),
Self::OC => (Self::OC, CapValue::TEXT_OC),
Self::SMULX => (Self::SMULX, CapValue::TEXT_SMULX),
Self::SETULC => (Self::SETULC, CapValue::TEXT_SETULC),
Self::SS => (Self::SS, CapValue::TEXT_SS),
Self::SE => (Self::SE, CapValue::TEXT_SE),
Self::CS => (Self::CS, CapValue::TEXT_CS),
Self::CR => (Self::CR, CapValue::TEXT_CR),
Self::SYNC => (Self::SYNC, CapValue::TEXT_SYNC),
Self::E3 => (Self::E3, CapValue::TEXT_E3),
Self::CLEAR | Self::CL => (Self::CLEAR, CapValue::TEXT_CLEAR),
Self::CUP | Self::CM => (Self::CUP, CapValue::TEXT_CUP),
Self::SMKX | Self::KS => (Self::SMKX, CapValue::TEXT_SMKX),
Self::RMKX | Self::KE => (Self::RMKX, CapValue::TEXT_RMKX),
Self::SMCUP | Self::TI => (Self::SMCUP, CapValue::TEXT_SMCUP),
Self::RMCUP | Self::TE => (Self::RMCUP, CapValue::TEXT_RMCUP),
Self::SMACS | Self::AS => (Self::SMACS, CapValue::TEXT_SMACS),
Self::RMACS | Self::AE => (Self::RMACS, CapValue::TEXT_RMACS),
Self::ACSC => (Self::ACSC, CapValue::TEXT_ACSC),
Self::CIVIS | Self::VI => (Self::CIVIS, CapValue::TEXT_CIVIS),
Self::CNORM | Self::VE => (Self::CNORM, CapValue::TEXT_CNORM),
Self::KBS => (Self::KBS, CapValue::TEXT_KBS),
Self::KDCH1 => (Self::KDCH1, CapValue::TEXT_KDCH1),
Self::KICH1 => (Self::KICH1, CapValue::TEXT_KICH1),
Self::KHOME => (Self::KHOME, CapValue::TEXT_KHOME),
Self::KEND => (Self::KEND, CapValue::TEXT_KEND),
Self::KCUU1 => (Self::KCUU1, CapValue::TEXT_KCUU1),
Self::KCUD1 => (Self::KCUD1, CapValue::TEXT_KCUD1),
Self::KCUB1 => (Self::KCUB1, CapValue::TEXT_KCUB1),
Self::KCUF1 => (Self::KCUF1, CapValue::TEXT_KCUF1),
Self::INDN => (Self::INDN, CapValue::TEXT_INDN),
Self::QUERY_OS_NAME => (Self::QUERY_OS_NAME, CapValue::OsName),
_ => (Self::NONE, CapValue::None),
}
}
}
impl crate::Reply {
pub fn termcap(self, cap: &[u8], cols: usize, rows: usize) -> Self {
let mut reply = self;
for part in cap.split(|&b| b == b';') {
if part.is_empty() {
continue;
}
let (key, value) = Cap::parse(part);
reply = match value {
CapValue::None => reply.xtgettcap_error(Cap::UNSUPPORTED),
CapValue::Bool => reply.xtgettcap_reply_bool(key),
CapValue::Text(v) => reply.xtgettcap_reply(key, v),
CapValue::Cols => reply.xtgettcap_num(key, cols),
CapValue::Rows => reply.xtgettcap_num(key, rows),
CapValue::OsName => reply.xtgettcap_reply(key, OS_NAME),
};
}
reply
}
}