Repository: zellij-org/zellij
File: zellij-server/src/panes/grid.rs (Rust)

Code before:
            // Replace the spaces at the end of the line. Sometimes, the lines are
            // collected with spaces until the end of the panel.
            buf.push_str(&s.trim_end_matches(' '));
            is_first = false;
        }
        buf
    }};
}

macro_rules! dump_screen_with_ansi {
    ($lines:expr) => {{
        use std::fmt::Write;
        let mut is_first = true;
        let mut buf = String::new();
        let mut last_styles: Option<RcCharacterStyles> = None;

        for line in &$lines {
            if line.is_canonical && !is_first {
                buf.push_str("\u{1b}[m\n");
                last_styles = None;
            }

            let last_non_space = line
                .columns
                .iter()
                .rposition(|tc| tc.character != ' ')
                .map(|i| i + 1)
                .unwrap_or(0);

            for tc in line.columns.iter().take(last_non_space) {
                // Only output style codes if style changed
                if last_styles.as_ref() != Some(&tc.styles) {
                    write!(buf, "{}", tc.styles).unwrap();
                    last_styles = Some(tc.styles.clone());
                }
                buf.push(tc.character);
            }
            is_first = false;
        }
        buf.push_str("\u{1b}[m");
        buf
    }};
}

fn utf8_mouse_coordinates(column: usize, line: isize) -> Vec<u8> {
    let mut coordinates = vec![];
    let mouse_pos_encode = |pos: usize| -> Vec<u8> {
        let pos = 32 + pos;
        let first = 0xC0 + pos / 64;
        let second = 0x80 + (pos & 63);
        vec![first as u8, second as u8]

Review comment (bug):
So, here we want the last space character that doesn't have styles (otherwise we will truncate space characters with backgrounds - a real world example is `delta`'s git diff). I recently fixed this bug in our own rendering engine if you'd like to see how it's done: https://github.com/zellij-org/zellij/pull/4680

Code after:
            // Replace the spaces at the end of the line. Sometimes, the lines are
            // collected with spaces until the end of the panel.
            buf.push_str(&s.trim_end_matches(' '));
            is_first = false;
        }
        buf
    }};
}

macro_rules! dump_screen_with_ansi {
    ($lines:expr) => {{
        use std::fmt::Write;
        let mut is_first = true;
        let mut buf = String::new();
        let mut last_styles: Option<RcCharacterStyles> = None;

        for line in &$lines {
            if line.is_canonical && !is_first {
                buf.push_str("\n");
                last_styles = None;
            }

            let last_non_space = line
                .columns
                .iter()
                .rposition(|tc| {
                    let space = tc.character == ' ';
                    let styled = !matches!(tc.styles.background, Some(AnsiCode::Reset) | None);
                    !space || styled // it's, something drawable
                })
                .map(|i| i + 1)
                .unwrap_or(0);

            for tc in line.columns.iter().take(last_non_space) {
                // Only output style codes if style changed
                if last_styles.as_ref() != Some(&tc.styles) {
                    write!(buf, "{}", tc.styles).unwrap();
                    last_styles = Some(tc.styles.clone());
                }
                buf.push(tc.character);
            }
            is_first = false;
        }
        buf.push_str("\u{1b}[m");
        buf
    }};
}

fn utf8_mouse_coordinates(column: usize, line: isize) -> Vec<u8> {
    let mut coordinates = vec![];
    let mouse_pos_encode = |pos: usize| -> Vec<u8> {