From 4ed2b3d04139fc15a50a535ddfae30ffbd70263f Mon Sep 17 00:00:00 2001 From: Jordi Villar Date: Wed, 11 Feb 2026 14:21:13 +0100 Subject: [PATCH] rope: Fix `point_utf16_to_offset` returning relative offset instead of absolute (#48862) `ChunkSlice::point_utf16_to_offset` returned `line.len()` (a relative line byte length) instead of `row_offset_range.end` (the absolute byte offset within the chunk) when clipping an out-of-range UTF-16 column on a non-first row. This caused incorrect position calculations in LSP coordinate conversions whenever a UTF-16 point had a column beyond the line's extent on any row after the first in a chunk. Added a regression test covering clipping on both row 0 and row 1. Not sure if it's the best place for a test like this one though. Release Notes: - N/A --- crates/rope/src/chunk.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/crates/rope/src/chunk.rs b/crates/rope/src/chunk.rs index 49bc88462171c271e8adbdeb7d0976e51e2514c7..1f94465282c1de01f5604a1f435831238afe64bc 100644 --- a/crates/rope/src/chunk.rs +++ b/crates/rope/src/chunk.rs @@ -501,7 +501,7 @@ impl<'a> ChunkSlice<'a> { self.text ); } - return line.len(); + return row_offset_range.end; } let mut offset = row_offset_range.start; @@ -1176,4 +1176,19 @@ mod tests { assert_eq!((max_row, max_chars as u32), (longest_row, longest_chars)); assert_eq!(chunk.tabs().collect::>(), expected_tab_positions); } + + #[gpui::test] + fn test_point_utf16_to_offset_clips_to_correct_absolute_offset() { + let text = "abc\nde"; + let chunk = Chunk::new(text); + let slice = chunk.as_slice(); + + // Clipping on row 0 (row_offset_range.start == 0, so relative == absolute) + assert_eq!(slice.point_utf16_to_offset(PointUtf16::new(0, 99), true), 3,); + + // Clipping on row 1 — this is the case that was buggy. + // Row 1 starts at byte offset 4 ("de" is bytes 4..6), so the + // clipped result must be 6, not 2. + assert_eq!(slice.point_utf16_to_offset(PointUtf16::new(1, 99), true), 6,); + } }