tastty-core 0.1.0

Sans-IO core of the tastty terminal session library: VT parser, screen buffer, and byte encoders.
//! Crate-internal scratch state stored on [`Screen`](super::Screen).

#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
pub(crate) enum Charset {
    #[default]
    Ascii,
    LineDrawing,
}

impl Charset {
    pub(crate) fn map(self, c: char) -> char {
        match self {
            Charset::Ascii => c,
            Charset::LineDrawing => match c {
                '_' => ' ',
                '`' => '',
                'a' => '',
                'b' => '\u{2409}',
                'c' => '\u{240c}',
                'd' => '\u{240d}',
                'e' => '\u{240a}',
                'f' => '°',
                'g' => '±',
                'h' => '\u{2424}',
                'i' => '\u{240b}',
                'j' => '',
                'k' => '',
                'l' => '',
                'm' => '',
                'n' => '',
                'o' => '',
                'p' => '',
                'q' => '',
                'r' => '',
                's' => '',
                't' => '',
                'u' => '',
                'v' => '',
                'w' => '',
                'x' => '',
                'y' => '',
                'z' => '',
                '{' => 'π',
                '|' => '',
                '}' => '£',
                '~' => '·',
                _ => c,
            },
        }
    }
}

#[derive(Clone, Debug)]
pub(crate) struct TitleStackEntry {
    pub(crate) title: String,
    pub(crate) icon: String,
}

#[derive(Copy, Clone, Debug)]
pub(crate) enum TitleStackTarget {
    Both,
    Window,
    Icon,
}

const KITTY_STACK_CAP: usize = 8;

#[derive(Clone, Debug)]
pub(crate) struct KittyFlagStack {
    entries: [u8; KITTY_STACK_CAP],
    len: u8,
}

impl Default for KittyFlagStack {
    fn default() -> Self {
        Self {
            entries: [0; KITTY_STACK_CAP],
            len: 0,
        }
    }
}

impl KittyFlagStack {
    pub(crate) fn push(&mut self, flags: u8) {
        if (self.len as usize) < KITTY_STACK_CAP {
            self.entries[self.len as usize] = flags;
            self.len += 1;
        }
    }

    pub(crate) fn pop(&mut self, count: u16) {
        let count = count.min(u16::from(self.len));
        self.len -= count as u8;
    }

    pub(crate) fn set(&mut self, flags: u8, mode: u16) {
        if self.len == 0 {
            self.push(flags);
            return;
        }
        let top = &mut self.entries[self.len as usize - 1];
        match mode {
            2 => *top |= flags,
            3 => *top &= !flags,
            _ => *top = flags, // mode 1 (assign) is the default
        }
    }

    pub(crate) fn current(&self) -> u8 {
        if self.len == 0 {
            0
        } else {
            self.entries[self.len as usize - 1]
        }
    }
}

/// The most recently emitted graphic character, retained so that CSI REP
/// (`\x1b[Pb b`) can repeat it. Cleared by any non-print VT operation.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(crate) struct LastPrinted {
    pub(crate) ch: char,
    pub(crate) width: u16,
}

#[derive(Clone, Debug, Default)]
pub(crate) enum DcsHandler {
    #[default]
    None,
    Decrqss(Vec<u8>),
    XtGetTcap(Vec<u8>),
}