This commit is contained in:
Josh Thomas 2025-01-05 22:27:46 -06:00
parent adf8cdac3e
commit 78e25338f8

View file

@ -46,8 +46,9 @@ pub struct LineOffsets(pub Vec<u32>);
impl LineOffsets { impl LineOffsets {
pub fn new() -> Self { pub fn new() -> Self {
let offsets = vec![0]; // Start with offset 0 for line 1
Self(offsets) // This maintains compatibility with existing code
Self(vec![0])
} }
pub fn add_line(&mut self, offset: u32) { pub fn add_line(&mut self, offset: u32) {
@ -58,29 +59,25 @@ impl LineOffsets {
// Find which line contains this offset by looking for the first line start // Find which line contains this offset by looking for the first line start
// that's greater than our position // that's greater than our position
let line = match self.0.binary_search(&offset) { let line = match self.0.binary_search(&offset) {
Ok(exact_line) => exact_line, // We're exactly at a line start, so we're on that line Ok(exact_line) => exact_line, // We're exactly at a line start
Err(next_line) => { Err(next_line) => {
if next_line == 0 { if next_line == 0 {
0 // Before first line start, so we're on line 0 0 // Before first line start, so we're on line 1
} else { } else {
let prev_line = next_line - 1; next_line - 1 // We're on the previous line
// If we're at the start of the next line, we're on that line
if offset == self.0[next_line] - 1 {
prev_line
} else {
// Otherwise we're on the previous line
prev_line
}
} }
} }
}; };
// Calculate column as offset from line start // Calculate column as offset from line start
let col = offset - self.0[line]; let col = offset - self.0[line];
((line as u32) + 1, col)
// Convert to 1-based line number
(line as u32 + 1, col)
} }
pub fn line_col_to_position(&self, line: u32, col: u32) -> u32 { pub fn line_col_to_position(&self, line: u32, col: u32) -> u32 {
// line is 1-based, so subtract 1 to get the index
self.0[(line - 1) as usize] + col self.0[(line - 1) as usize] + col
} }
} }
@ -264,18 +261,18 @@ mod tests {
#[test] #[test]
fn test_new_starts_at_zero() { fn test_new_starts_at_zero() {
let offsets = LineOffsets::new(); let offsets = LineOffsets::new();
assert_eq!(offsets.position_to_line_col(0), (1, 0)); assert_eq!(offsets.position_to_line_col(0), (1, 0)); // Line 1, column 0
} }
#[test] #[test]
fn test_start_of_lines() { fn test_start_of_lines() {
let mut offsets = LineOffsets::new(); let mut offsets = LineOffsets::new();
offsets.add_line(10); // Line 1 offsets.add_line(10); // Line 2 starts at offset 10
offsets.add_line(25); // Line 2 offsets.add_line(25); // Line 3 starts at offset 25
assert_eq!(offsets.position_to_line_col(0), (1, 0)); // Line 1 assert_eq!(offsets.position_to_line_col(0), (1, 0)); // Line 1, start
assert_eq!(offsets.position_to_line_col(10), (2, 0)); // Line 2 assert_eq!(offsets.position_to_line_col(10), (2, 0)); // Line 2, start
assert_eq!(offsets.position_to_line_col(25), (3, 0)); // Line 3 assert_eq!(offsets.position_to_line_col(25), (3, 0)); // Line 3, start
} }
} }