Introduce FoldMapSnapshot::chunks_at, use it in FoldMap::text

Get the FoldMap randomized tests passing. This also required adding
a test-only FoldMap::prev_char_boundary method.
This commit is contained in:
Max Brunsfeld
2021-05-20 12:47:08 +02:00
committed by Antonio Scandurra
parent b3d2a70834
commit a9583d0074
3 changed files with 163 additions and 55 deletions
+2 -5
View File
@@ -5,7 +5,7 @@ mod selection;
pub use anchor::*;
pub use point::*;
pub use rope::{Rope, TextSummary};
pub use rope::{ChunksIter, Rope, TextSummary};
use seahash::SeaHasher;
pub use selection::*;
use similar::{ChangeTag, TextDiff};
@@ -637,10 +637,7 @@ impl Buffer {
self.text_for_range(0..self.len()).collect()
}
pub fn text_for_range<'a, T: ToOffset>(
&'a self,
range: Range<T>,
) -> impl 'a + Iterator<Item = &'a str> {
pub fn text_for_range<'a, T: ToOffset>(&'a self, range: Range<T>) -> ChunksIter<'a> {
let start = range.start.to_offset(self);
let end = range.end.to_offset(self);
self.visible_text.chunks_in_range(start..end)
+29 -10
View File
@@ -115,11 +115,11 @@ impl Rope {
Chars::new(self, start)
}
pub fn chunks<'a>(&'a self) -> impl Iterator<Item = &'a str> {
pub fn chunks<'a>(&'a self) -> ChunksIter<'a> {
self.chunks_in_range(0..self.len())
}
pub fn chunks_in_range<'a>(&'a self, range: Range<usize>) -> impl Iterator<Item = &'a str> {
pub fn chunks_in_range<'a>(&'a self, range: Range<usize>) -> ChunksIter<'a> {
ChunksIter::new(self, range)
}
@@ -270,21 +270,40 @@ impl<'a> ChunksIter<'a> {
chunks.seek(&range.start, SeekBias::Right, &());
Self { chunks, range }
}
pub fn offset(&self) -> usize {
self.range.start.max(*self.chunks.start())
}
pub fn advance_to(&mut self, offset: usize) {
if offset >= self.chunks.end() {
self.chunks.seek_forward(&offset, SeekBias::Right, &());
self.range.start = offset;
}
}
pub fn peek(&self) -> Option<&'a str> {
if let Some(chunk) = self.chunks.item() {
let offset = *self.chunks.start();
if self.range.end > offset {
let start = self.range.start.saturating_sub(*self.chunks.start());
let end = self.range.end - self.chunks.start();
return Some(&chunk.0[start..chunk.0.len().min(end)]);
}
}
None
}
}
impl<'a> Iterator for ChunksIter<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<Self::Item> {
if let Some(chunk) = self.chunks.item() {
if self.range.end > *self.chunks.start() {
let start = self.range.start.saturating_sub(*self.chunks.start());
let end = self.range.end - self.chunks.start();
self.chunks.next();
return Some(&chunk.0[start..chunk.0.len().min(end)]);
}
let result = self.peek();
if result.is_some() {
self.chunks.next();
}
None
result
}
}