102 lines · 3.7 KB · Rust
RawDownload
use std::ops::Range; use regex::Regex;use warpui::keymap::Keystroke; use crate::terminal::model::escape_sequences::C0; lazy_static::lazy_static! {    /// Matches control code values specified in hex format delimited by angle brackets, e.g. <0x1B>.    static ref CONTROL_CODE_REGEX: Regex = Regex::new(r"<0x([0-9a-fA-F]{2})>").expect("Regex is valid.");     /// Matches an incomplete control code at the end of the response stream.    static ref INCOMPLETE_CONTROL_CODE_REGEX: Regex = Regex::new(r"<(0|0x|0x[0-9a-fA-F]|0x[0-9a-fA-F]{2})$").expect("Regex is valid.");} /// Parsed output that separates raw bytes from display-friendly text.#[derive(Debug, Clone, Default)]pub struct ParsedControlCodeOutput {    /// Human-readable display text (e.g., "<ctrl-c>" instead of 0x03).    pub display: String,     /// Ranges in `display` where control codes appear (for styling).    pub control_code_ranges: Vec<Range<usize>>,} /// Parses raw bytes containing control codes like `\x1B`.pub fn parse_control_codes_from_bytes(bytes: &[u8]) -> ParsedControlCodeOutput {    let mut parsed_output = String::new();    let mut control_code_ranges = vec![];    let mut output_bytes = Vec::with_capacity(bytes.len());     for &byte in bytes {        output_bytes.push(byte);         if let Some(keystroke) = byte_value_to_keystroke(byte) {            let keystroke_string = format!(" <{}>", keystroke.normalized());            control_code_ranges                .push(parsed_output.len() + 1..parsed_output.len() + keystroke_string.len());            parsed_output.push_str(&keystroke_string);        } else if byte.is_ascii_graphic() || byte == b' ' {            parsed_output.push(byte as char);        } else {            // For non-control, non-printable bytes, show as hex notation            let hex_string = format!("<0x{byte:02X}>");            parsed_output.push_str(&hex_string);        }    }     ParsedControlCodeOutput {        display: parsed_output,        control_code_ranges,    }} /// Returns the corresponding `Keystroke` for the given byte value if it represents a C0 control code.////// For example, given the byte value for `C0::CR` (carriage return), returns the "enter" `Keystroke`.fn byte_value_to_keystroke(value: u8) -> Option<Keystroke> {    let (ctrl, key) = match value {        C0::SOH => (true, "a".into()),        C0::STX => (true, "b".into()),        C0::ETX => (true, "c".into()),        C0::EOT => (true, "d".into()),        C0::ENQ => (true, "e".into()),        C0::ACK => (true, "f".into()),        C0::BEL => (true, "g".into()),        C0::VT => (true, "k".into()),        C0::FF => (true, "l".into()),        C0::SO => (true, "n".into()),        C0::SI => (true, "o".into()),        C0::DLE => (true, "p".into()),        C0::XON => (true, "q".into()),        C0::DC2 => (true, "r".into()),        C0::XOFF => (true, "s".into()),        C0::DC4 => (true, "t".into()),        C0::NAK => (true, "u".into()),        C0::SYN => (true, "v".into()),        C0::ETB => (true, "w".into()),        C0::CAN => (true, "x".into()),        C0::EM => (true, "y".into()),        C0::SUB => (true, "z".into()),        C0::FS => (true, "\\".into()),        C0::GS => (true, "]".into()),        C0::RS => (true, "^".into()),        C0::US => (true, "_".into()),        C0::HT => (false, "tab".into()),        C0::ESC => (false, "escape".into()),        C0::DEL => (false, "delete".into()),        C0::BS => (false, "backspace".into()),        C0::LF | C0::CR => (false, "enter".into()),        _ => return None,    };     Some(Keystroke {        ctrl,        alt: false,        shift: false,        cmd: false,        meta: false,        key,    })}