fn encode_kitty()

in crates/figterm/src/input/mod.rs [393:536]


    fn encode_kitty(&self, mods: Modifiers, is_down: bool, flags: KittyKeyboardFlags) -> Result<String> {
        use KeyCode::{
            Backspace,
            Char,
            Delete,
            DownArrow,
            End,
            Enter,
            Function,
            Home,
            Insert,
            LeftArrow,
            PageDown,
            PageUp,
            RightArrow,
            Tab,
            UpArrow,
        };

        if !flags.contains(KittyKeyboardFlags::REPORT_EVENT_TYPES) && !is_down {
            return Ok(String::new());
        }

        // Normalize
        let key = match self {
            Char('\r') => Enter,
            Char('\t') => Tab,
            Char('\x7f') => Delete,
            Char('\x08') => Backspace,
            c => *c,
        };

        if mods.is_empty() && !flags.contains(KittyKeyboardFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES) {
            // Check for simple text generating keys
            match key {
                Enter => return Ok("\r".to_string()),
                Tab => return Ok("\t".to_string()),
                Backspace => return Ok("\x7f".to_string()),
                Char(c) => return Ok(c.to_string()),
                _ => {},
            }
        }

        let mut modifiers = 0;
        if mods.contains(Modifiers::SHIFT) {
            modifiers |= 1;
        }
        if mods.contains(Modifiers::ALT) {
            modifiers |= 2;
        }
        if mods.contains(Modifiers::CTRL) {
            modifiers |= 4;
        }
        if mods.contains(Modifiers::META) {
            modifiers |= 8;
        }
        modifiers += 1;

        let event_type = if flags.contains(KittyKeyboardFlags::REPORT_EVENT_TYPES) && !is_down {
            ":3"
        } else {
            ""
        };

        match key {
            Char(shifted_key) => {
                let c = shifted_key.to_ascii_lowercase();

                let key_code = if flags.contains(KittyKeyboardFlags::REPORT_ALTERNATE_KEYS) && c != shifted_key {
                    // Note: we don't have enough information here to know what the base-layout key
                    // should really be.
                    let base_layout = c;
                    format!("{c}:{shifted_key}:{base_layout}")
                } else {
                    (c as u32).to_string()
                };

                Ok(format!("\x1b[{key_code};{modifiers}{event_type}u"))
            },
            LeftArrow | RightArrow | UpArrow | DownArrow | Home | End => {
                let c = match key {
                    UpArrow => 'A',
                    DownArrow => 'B',
                    RightArrow => 'C',
                    LeftArrow => 'D',
                    Home => 'H',
                    End => 'F',
                    _ => unreachable!(),
                };
                Ok(format!("\x1b[1;{modifiers}{event_type}{c}"))
            },
            PageUp | PageDown | Insert | Delete => {
                let c = match key {
                    Insert => 2,
                    Delete => 3,
                    PageUp => 5,
                    PageDown => 6,
                    _ => unreachable!(),
                };

                Ok(format!("\x1b[{c};{modifiers}{event_type}~"))
            },
            Function(n) if n < 13 => {
                if mods.is_empty() && n < 5 {
                    // F1-F4 are encoded using SS3 if there are no modifiers
                    Ok((match n {
                        1 => "\x1bOP",
                        2 => "\x1bOQ",
                        3 => "\x1bOR",
                        4 => "\x1bOS",
                        _ => unreachable!("wat?"),
                    })
                    .to_string())
                } else {
                    // Higher numbered F-keys plus modified F-keys are encoded
                    // using CSI instead of SS3.
                    let intro = match n {
                        1 => "\x1b[11",
                        2 => "\x1b[12",
                        3 => "\x1b[13",
                        4 => "\x1b[14",
                        5 => "\x1b[15",
                        6 => "\x1b[17",
                        7 => "\x1b[18",
                        8 => "\x1b[19",
                        9 => "\x1b[20",
                        10 => "\x1b[21",
                        11 => "\x1b[23",
                        12 => "\x1b[24",
                        _ => unreachable!(),
                    };
                    Ok(format!("{intro};{modifiers}{event_type}~"))
                }
            },

            _ => {
                if let Some(code) = key.kitty_function_code() {
                    Ok(format!("\x1b[{code};{modifiers}{event_type}u"))
                } else {
                    Ok(String::new())
                }
            },
        }
    }