From d7fd5910d7d0ae4404be21ada5be1f39d83d3aea Mon Sep 17 00:00:00 2001 From: Michael Sloan Date: Wed, 3 Sep 2025 00:35:31 -0600 Subject: [PATCH] Use slice from Rope chunk when possible while iterating lines (#37430) Release Notes: - N/A --- crates/rope/src/rope.rs | 48 +++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/crates/rope/src/rope.rs b/crates/rope/src/rope.rs index 0d3f5abbdefd3850d02e66a1efbef5b58a5f2835..41b2a2d033eb49a1851c02e7066be22d807bca4b 100644 --- a/crates/rope/src/rope.rs +++ b/crates/rope/src/rope.rs @@ -936,24 +936,36 @@ impl Lines<'_> { self.current_line.clear(); while let Some(chunk) = self.chunks.peek() { - let lines = chunk.split('\n'); + let chunk_lines = chunk.split('\n'); if self.reversed { - let mut lines = lines.rev().peekable(); - while let Some(line) = lines.next() { - self.current_line.insert_str(0, line); - if lines.peek().is_some() { + let mut chunk_lines = chunk_lines.rev().peekable(); + if let Some(chunk_line) = chunk_lines.next() { + let done = chunk_lines.peek().is_some(); + if done { self.chunks - .seek(self.chunks.offset() - line.len() - "\n".len()); + .seek(self.chunks.offset() - chunk_line.len() - "\n".len()); + if self.current_line.is_empty() { + return Some(chunk_line); + } + } + self.current_line.insert_str(0, chunk_line); + if done { return Some(&self.current_line); } } } else { - let mut lines = lines.peekable(); - while let Some(line) = lines.next() { - self.current_line.push_str(line); - if lines.peek().is_some() { + let mut chunk_lines = chunk_lines.peekable(); + if let Some(chunk_line) = chunk_lines.next() { + let done = chunk_lines.peek().is_some(); + if done { self.chunks - .seek(self.chunks.offset() + line.len() + "\n".len()); + .seek(self.chunks.offset() + chunk_line.len() + "\n".len()); + if self.current_line.is_empty() { + return Some(chunk_line); + } + } + self.current_line.push_str(chunk_line); + if done { return Some(&self.current_line); } } @@ -1573,6 +1585,20 @@ mod tests { assert_eq!(lines.next(), Some("defg")); assert_eq!(lines.next(), Some("abc")); assert_eq!(lines.next(), None); + + let rope = Rope::from("abc\nlonger line test\nhi"); + let mut lines = rope.chunks().lines(); + assert_eq!(lines.next(), Some("abc")); + assert_eq!(lines.next(), Some("longer line test")); + assert_eq!(lines.next(), Some("hi")); + assert_eq!(lines.next(), None); + + let rope = Rope::from("abc\nlonger line test\nhi"); + let mut lines = rope.reversed_chunks_in_range(0..rope.len()).lines(); + assert_eq!(lines.next(), Some("hi")); + assert_eq!(lines.next(), Some("longer line test")); + assert_eq!(lines.next(), Some("abc")); + assert_eq!(lines.next(), None); } #[gpui::test(iterations = 100)]