Files
galaxy/app/src/code_review/hidden_lines.rs
T

75 lines
2.7 KiB
Rust

use std::ops::Range;
use ai::diff_validation::DiffDelta;
use galaxy_editor::content::text::LineCount;
use galaxy_editor::render::model::LineCount as RenderLineCount;
use rangemap::RangeSet;
/// The number of context lines to show before and after each change
const CONTEXT_LINES: usize = 4;
/// Calculate which lines should be hidden in a file after applying diffs.
///
/// This function takes a list of diff deltas and comment line numbers, then calculates which lines should be hidden
/// (everything except for CONTEXT_LINES before and after each change and comment).
///
/// These are 0-indexed line numbers BEFORE the diffs are applied, so the first line is 0.
///
/// # Arguments
///
/// * `diffs` - The list of diff deltas that will be applied to the file
/// * `line_count` - The total number of lines in the file before any diffs are applied
/// * `comment_line_numbers` - Line numbers where comments exist (0-indexed)
///
/// # Returns
///
/// A `RangeSet<usize>` containing the line ranges that should be hidden (0-indexed).
///
/// Note that DiffDelta uses 1-indexed line ranges, so we convert them to 0-indexed
/// ```
pub fn calculate_hidden_lines(
diffs: &[DiffDelta],
line_count: usize,
comment_line_numbers: &[RenderLineCount],
) -> RangeSet<LineCount> {
// Calculate the visible line ranges (with context)
let mut visible_ranges: RangeSet<LineCount> = RangeSet::new();
// Add ranges for diffs
for diff in diffs {
// Convert 1-indexed line ranges to 0-indexed
let start_line = diff.replacement_line_range.start.saturating_sub(1);
let end_line = diff.replacement_line_range.end.saturating_sub(1);
let context_start = start_line.saturating_sub(CONTEXT_LINES);
let context_end = end_line + CONTEXT_LINES;
if context_start < context_end {
visible_ranges.insert(context_start.into()..context_end.into());
}
}
// Add ranges for comments
for &comment_line in comment_line_numbers {
let line_number = comment_line.as_usize();
let context_start = line_number.saturating_sub(CONTEXT_LINES);
let context_end = (line_number + CONTEXT_LINES + 1).min(line_count); // +1 because we want to include the line itself, clamped to file bounds
if context_start < context_end {
visible_ranges.insert(LineCount::from(context_start)..LineCount::from(context_end));
}
}
// Calculate hidden ranges as the complement of visible ranges
let all_lines: Range<LineCount> = LineCount::from(0)..LineCount::from(line_count);
// Find gaps in the visible ranges
visible_ranges
.gaps(&all_lines)
.collect::<RangeSet<LineCount>>()
}
#[cfg(test)]
#[path = "hidden_lines_tests.rs"]
mod tests;