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

Code before:
        if next_lines.is_empty() {
            if !viewport.is_empty() {
                let next_line = viewport.remove(0);
                transferred_rows_height +=
                    (next_line.width() as f64 / max_viewport_width as f64).ceil() as usize;
                if !next_line.is_canonical {
                    let mut bottom_canonical_row_and_wraps_in_dst =
                        get_lines_above_bottom_canonical_row_and_wraps(lines_above);
                    next_lines.append(&mut bottom_canonical_row_and_wraps_in_dst);
                }
                next_lines.push(next_line);
                next_lines = vec![Row::from_rows(next_lines, 0)];
            } else {
                break; // no more rows
            }
        }
        bounded_push(lines_above, next_lines.remove(0));
    }
    if !next_lines.is_empty() {
        let excess_rows = Row::from_rows(next_lines, max_viewport_width)
            .split_to_rows_of_length(max_viewport_width);
        for row in excess_rows {
            viewport.insert(0, row);
        }
    }
    transferred_rows_height
}

fn transfer_rows_from_lines_below_to_viewport(
    lines_below: &mut Vec<Row>,
    viewport: &mut Vec<Row>,
    count: usize,
    max_viewport_width: usize,
) {
    let mut next_lines: Vec<Row> = vec![];
    for _ in 0..count {
        let mut lines_pulled_from_viewport = 0;
        if next_lines.is_empty() {
            if !lines_below.is_empty() {
                let mut top_non_canonical_rows_in_lines_below =
                    get_top_non_canonical_rows(lines_below);
                if !top_non_canonical_rows_in_lines_below.is_empty() {
                    let mut canonical_line = get_viewport_bottom_canonical_row_and_wraps(viewport);
                    lines_pulled_from_viewport += canonical_line.len();
                    canonical_line.append(&mut top_non_canonical_rows_in_lines_below);
                    next_lines = Row::from_rows(canonical_line, max_viewport_width)
                        .split_to_rows_of_length(max_viewport_width);
                } else {
                    let canonical_row = get_top_canonical_row_and_wraps(lines_below);
                    next_lines = Row::from_rows(canonical_row, max_viewport_width)
                        .split_to_rows_of_length(max_viewport_width);

Review comment (bug):
We need to account for the `bounded_push` above somehow. There's a chance that it drops a line if it overflows the buffer... maybe also return a value from it?

Code after:
        if next_lines.is_empty() {
            if !viewport.is_empty() {
                let next_line = viewport.remove(0);
                transferred_rows_count +=
                    calculate_row_display_height(next_line.width(), max_viewport_width) as isize;
                if !next_line.is_canonical {
                    let mut bottom_canonical_row_and_wraps_in_dst =
                        get_lines_above_bottom_canonical_row_and_wraps(lines_above);
                    next_lines.append(&mut bottom_canonical_row_and_wraps_in_dst);
                }
                next_lines.push(next_line);
                next_lines = vec![Row::from_rows(next_lines, 0)];
            } else {
                break; // no more rows
            }
        }
        let dropped_line_width = bounded_push(lines_above, next_lines.remove(0));
        if let Some(width) = dropped_line_width {
            transferred_rows_count -=
                calculate_row_display_height(width, max_viewport_width) as isize;
        }
    }
    if !next_lines.is_empty() {
        let excess_rows = Row::from_rows(next_lines, max_viewport_width)
            .split_to_rows_of_length(max_viewport_width);
        for row in excess_rows {
            viewport.insert(0, row);
        }
    }
    transferred_rows_count
}

fn transfer_rows_from_lines_below_to_viewport(
    lines_below: &mut Vec<Row>,
    viewport: &mut Vec<Row>,
    count: usize,
    max_viewport_width: usize,
) {
    let mut next_lines: Vec<Row> = vec![];
    for _ in 0..count {
        let mut lines_pulled_from_viewport = 0;
        if next_lines.is_empty() {
            if !lines_below.is_empty() {
                let mut top_non_canonical_rows_in_lines_below =
                    get_top_non_canonical_rows(lines_below);
                if !top_non_canonical_rows_in_lines_below.is_empty() {
                    let mut canonical_line = get_viewport_bottom_canonical_row_and_wraps(viewport);
                    lines_pulled_from_viewport += canonical_line.len();
                    canonical_line.append(&mut top_non_canonical_rows_in_lines_below);
                    next_lines = Row::from_rows(canonical_line, max_viewport_width)
                        .split_to_rows_of_length(max_viewport_width);