Implement SuggestionSnapshot::line_len

Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
Antonio Scandurra 2023-03-20 19:45:39 +01:00
parent f44549eb29
commit 3edf83cb99

View File

@ -41,6 +41,16 @@ impl AddAssign for SuggestionOffset {
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
pub struct SuggestionPoint(pub Point);
impl SuggestionPoint {
pub fn row(self) -> u32 {
self.0.row
}
pub fn column(self) -> u32 {
self.0.column
}
}
#[derive(Clone, Debug)]
pub struct Suggestion<T> {
position: T,
@ -183,6 +193,32 @@ impl SuggestionSnapshot {
}
}
pub fn line_len(&self, row: u32) -> u32 {
if let Some(suggestion) = self.suggestion.as_ref() {
let suggestion_lines = suggestion.text.max_point();
let suggestion_start = suggestion.position.to_point(&self.fold_snapshot).0;
let suggestion_end = suggestion_start + suggestion_lines;
if row < suggestion_start.row {
self.fold_snapshot.line_len(row)
} else if row > suggestion_end.row {
self.fold_snapshot.line_len(row - suggestion_lines.row)
} else {
let mut len = suggestion.text.line_len(row - suggestion_start.row);
if row == suggestion_start.row {
len += suggestion_start.column;
}
if row == suggestion_end.row {
len +=
self.fold_snapshot.line_len(suggestion_start.row) - suggestion_start.column;
}
len
}
} else {
self.fold_snapshot.line_len(row)
}
}
pub fn chunks<'a>(
&'a self,
range: Range<SuggestionOffset>,
@ -389,21 +425,20 @@ mod tests {
log::info!("folds text: {:?}", fold_snapshot.text());
log::info!("suggestions text: {:?}", suggestion_snapshot.text());
let mut expected_text = fold_snapshot.text();
let mut expected_text = Rope::from(fold_snapshot.text().as_str());
if let Some(suggestion) = suggestion_snapshot.suggestion.as_ref() {
expected_text.insert_str(suggestion.position.0, &suggestion.text.to_string());
expected_text.replace(
suggestion.position.0..suggestion.position.0,
&suggestion.text.to_string(),
);
}
assert_eq!(suggestion_snapshot.text(), expected_text);
assert_eq!(suggestion_snapshot.text(), expected_text.to_string());
for _ in 0..3 {
for _ in 0..5 {
let mut end = rng.gen_range(0..=suggestion_snapshot.len().0);
while !expected_text.is_char_boundary(end) {
end += 1;
}
end = expected_text.clip_offset(end, Bias::Right);
let mut start = rng.gen_range(0..=end);
while !expected_text.is_char_boundary(start) {
start += 1;
}
start = expected_text.clip_offset(start, Bias::Right);
let actual_text = suggestion_snapshot
.chunks(SuggestionOffset(start)..SuggestionOffset(end), false, None)
@ -411,7 +446,7 @@ mod tests {
.collect::<String>();
assert_eq!(
actual_text,
&expected_text[start..end],
expected_text.slice(start..end).to_string(),
"incorrect text in range {:?}",
start..end
);
@ -424,6 +459,17 @@ mod tests {
);
}
assert_eq!(prev_suggestion_text, suggestion_snapshot.text());
assert_eq!(expected_text.max_point(), suggestion_snapshot.max_point().0);
assert_eq!(expected_text.len(), suggestion_snapshot.len().0);
for row in 0..=suggestion_snapshot.max_point().row() {
assert_eq!(
suggestion_snapshot.line_len(row),
expected_text.line_len(row),
"incorrect line len for row {}",
row
);
}
}
}
}