@@ -372,28 +372,39 @@ impl UndoMap {
}
struct Edits<'a, F: Fn(&FragmentSummary) -> bool> {
+ visible_text: &'a Rope,
deleted_text: &'a Rope,
cursor: FilterCursor<'a, F, Fragment, FragmentTextSummary>,
undos: &'a UndoMap,
since: time::Global,
- delta: isize,
+ old_offset: usize,
+ new_offset: usize,
+ old_point: Point,
+ new_point: Point,
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Edit {
- pub old_range: Range<usize>,
- pub new_range: Range<usize>,
- pub old_lines: Point,
+ pub old_bytes: Range<usize>,
+ pub new_bytes: Range<usize>,
+ pub old_lines: Range<Point>,
}
impl Edit {
pub fn delta(&self) -> isize {
- (self.new_range.end - self.new_range.start) as isize
- - (self.old_range.end - self.old_range.start) as isize
+ self.inserted_bytes() as isize - self.deleted_bytes() as isize
}
- pub fn old_extent(&self) -> usize {
- self.old_range.end - self.old_range.start
+ pub fn deleted_bytes(&self) -> usize {
+ self.old_bytes.end - self.old_bytes.start
+ }
+
+ pub fn inserted_bytes(&self) -> usize {
+ self.new_bytes.end - self.new_bytes.start
+ }
+
+ pub fn deleted_lines(&self) -> Point {
+ self.old_lines.end - self.old_lines.start
}
}
@@ -776,25 +787,21 @@ impl Buffer {
if let Some(syntax_tree) = self.syntax_tree.lock().as_mut() {
let mut edited = false;
let mut delta = 0_isize;
- for Edit {
- old_range,
- new_range,
- old_lines,
- } in self.edits_since(syntax_tree.version.clone())
- {
- let start_offset = (old_range.start as isize + delta) as usize;
+ for edit in self.edits_since(syntax_tree.version.clone()) {
+ let start_offset = (edit.old_bytes.start as isize + delta) as usize;
let start_point = self.visible_text.to_point(start_offset);
- let old_bytes = old_range.end - old_range.start;
- let new_bytes = new_range.end - new_range.start;
syntax_tree.tree.edit(&InputEdit {
start_byte: start_offset,
- old_end_byte: start_offset + old_bytes,
- new_end_byte: start_offset + new_bytes,
+ old_end_byte: start_offset + edit.deleted_bytes(),
+ new_end_byte: start_offset + edit.inserted_bytes(),
start_position: start_point.into(),
- old_end_position: (start_point + old_lines).into(),
- new_end_position: self.visible_text.to_point(start_offset + new_bytes).into(),
+ old_end_position: (start_point + edit.deleted_lines()).into(),
+ new_end_position: self
+ .visible_text
+ .to_point(start_offset + edit.inserted_bytes())
+ .into(),
});
- delta += new_bytes as isize - old_bytes as isize;
+ delta += edit.inserted_bytes() as isize - edit.deleted_bytes() as isize;
edited = true;
}
syntax_tree.parsed &= !edited;
@@ -1051,11 +1058,15 @@ impl Buffer {
);
Edits {
+ visible_text: &self.visible_text,
deleted_text: &self.deleted_text,
cursor,
undos: &self.undo_map,
since,
- delta: 0,
+ old_offset: 0,
+ new_offset: 0,
+ old_point: Point::zero(),
+ new_point: Point::zero(),
}
}
@@ -2089,45 +2100,53 @@ impl<'a, F: Fn(&FragmentSummary) -> bool> Iterator for Edits<'a, F> {
let mut change: Option<Edit> = None;
while let Some(fragment) = self.cursor.item() {
- let new_offset = self.cursor.start().visible;
- let old_offset = (new_offset as isize - self.delta) as usize;
+ let bytes = self.cursor.start().visible - self.new_offset;
+ let lines = self.visible_text.to_point(self.cursor.start().visible) - self.new_point;
+ self.old_offset += bytes;
+ self.old_point += &lines;
+ self.new_offset += bytes;
+ self.new_point += &lines;
if !fragment.was_visible(&self.since, &self.undos) && fragment.visible {
+ let fragment_lines =
+ self.visible_text.to_point(self.new_offset + fragment.len) - self.new_point;
if let Some(ref mut change) = change {
- if change.new_range.end == new_offset {
- change.new_range.end += fragment.len;
- self.delta += fragment.len as isize;
+ if change.new_bytes.end == self.new_offset {
+ change.new_bytes.end += fragment.len;
} else {
break;
}
} else {
change = Some(Edit {
- old_range: old_offset..old_offset,
- new_range: new_offset..new_offset + fragment.len,
- old_lines: Point::zero(),
+ old_bytes: self.old_offset..self.old_offset,
+ new_bytes: self.new_offset..self.new_offset + fragment.len,
+ old_lines: self.old_point..self.old_point,
});
- self.delta += fragment.len as isize;
}
+
+ self.new_offset += fragment.len;
+ self.new_point += &fragment_lines;
} else if fragment.was_visible(&self.since, &self.undos) && !fragment.visible {
let deleted_start = self.cursor.start().deleted;
- let old_lines = self.deleted_text.to_point(deleted_start + fragment.len)
+ let fragment_lines = self.deleted_text.to_point(deleted_start + fragment.len)
- self.deleted_text.to_point(deleted_start);
if let Some(ref mut change) = change {
- if change.new_range.end == new_offset {
- change.old_range.end += fragment.len;
- change.old_lines += &old_lines;
- self.delta -= fragment.len as isize;
+ if change.new_bytes.end == self.new_offset {
+ change.old_bytes.end += fragment.len;
+ change.old_lines.end += &fragment_lines;
} else {
break;
}
} else {
change = Some(Edit {
- old_range: old_offset..old_offset + fragment.len,
- new_range: new_offset..new_offset,
- old_lines,
+ old_bytes: self.old_offset..self.old_offset + fragment.len,
+ new_bytes: self.new_offset..self.new_offset,
+ old_lines: self.old_point..self.old_point + &fragment_lines,
});
- self.delta -= fragment.len as isize;
}
+
+ self.old_offset += fragment.len;
+ self.old_point += &fragment_lines;
}
self.cursor.next(&None);
@@ -2898,19 +2917,16 @@ mod tests {
);
let mut delta = 0_isize;
- for Edit {
- old_range,
- new_range,
- ..
- } in edits
- {
- let old_len = old_range.end - old_range.start;
- let new_len = new_range.end - new_range.start;
- let old_start = (old_range.start as isize + delta) as usize;
- let new_text: String = buffer.text_for_range(new_range).collect();
- old_buffer.edit(Some(old_start..old_start + old_len), new_text, cx);
-
- delta += new_len as isize - old_len as isize;
+ for edit in edits {
+ let old_start = (edit.old_bytes.start as isize + delta) as usize;
+ let new_text: String =
+ buffer.text_for_range(edit.new_bytes.clone()).collect();
+ old_buffer.edit(
+ Some(old_start..old_start + edit.deleted_bytes()),
+ new_text,
+ cx,
+ );
+ delta += edit.delta();
}
assert_eq!(old_buffer.text(), buffer.text());
}
@@ -106,8 +106,8 @@ impl FoldMap {
let fold = Fold(buffer.anchor_after(range.start)..buffer.anchor_before(range.end));
folds.push(fold);
edits.push(Edit {
- old_range: range.clone(),
- new_range: range.clone(),
+ old_bytes: range.clone(),
+ new_bytes: range.clone(),
..Default::default()
});
}
@@ -115,10 +115,10 @@ impl FoldMap {
folds.sort_unstable_by(|a, b| sum_tree::SeekDimension::cmp(a, b, buffer));
edits.sort_unstable_by(|a, b| {
- a.old_range
+ a.old_bytes
.start
- .cmp(&b.old_range.start)
- .then_with(|| b.old_range.end.cmp(&a.old_range.end))
+ .cmp(&b.old_bytes.start)
+ .then_with(|| b.old_bytes.end.cmp(&a.old_bytes.end))
});
self.folds = {
@@ -151,8 +151,8 @@ impl FoldMap {
while let Some(fold) = folds_cursor.item() {
let offset_range = fold.0.start.to_offset(buffer)..fold.0.end.to_offset(buffer);
edits.push(Edit {
- old_range: offset_range.clone(),
- new_range: offset_range,
+ old_bytes: offset_range.clone(),
+ new_bytes: offset_range,
..Default::default()
});
fold_ixs_to_delete.push(*folds_cursor.start());
@@ -163,10 +163,10 @@ impl FoldMap {
fold_ixs_to_delete.sort_unstable();
fold_ixs_to_delete.dedup();
edits.sort_unstable_by(|a, b| {
- a.old_range
+ a.old_bytes
.start
- .cmp(&b.old_range.start)
- .then_with(|| b.old_range.end.cmp(&a.old_range.end))
+ .cmp(&b.old_bytes.start)
+ .then_with(|| b.old_bytes.end.cmp(&a.old_bytes.end))
});
self.folds = {
@@ -278,28 +278,28 @@ impl FoldMap {
cursor.seek(&0, Bias::Right, &());
while let Some(mut edit) = edits.next() {
- new_transforms.push_tree(cursor.slice(&edit.old_range.start, Bias::Left, &()), &());
- edit.new_range.start -= edit.old_range.start - cursor.seek_start();
- edit.old_range.start = *cursor.seek_start();
+ new_transforms.push_tree(cursor.slice(&edit.old_bytes.start, Bias::Left, &()), &());
+ edit.new_bytes.start -= edit.old_bytes.start - cursor.seek_start();
+ edit.old_bytes.start = *cursor.seek_start();
- cursor.seek(&edit.old_range.end, Bias::Right, &());
+ cursor.seek(&edit.old_bytes.end, Bias::Right, &());
cursor.next(&());
let mut delta = edit.delta();
loop {
- edit.old_range.end = *cursor.seek_start();
+ edit.old_bytes.end = *cursor.seek_start();
if let Some(next_edit) = edits.peek() {
- if next_edit.old_range.start > edit.old_range.end {
+ if next_edit.old_bytes.start > edit.old_bytes.end {
break;
}
let next_edit = edits.next().unwrap();
delta += next_edit.delta();
- if next_edit.old_range.end >= edit.old_range.end {
- edit.old_range.end = next_edit.old_range.end;
- cursor.seek(&edit.old_range.end, Bias::Right, &());
+ if next_edit.old_bytes.end >= edit.old_bytes.end {
+ edit.old_bytes.end = next_edit.old_bytes.end;
+ cursor.seek(&edit.old_bytes.end, Bias::Right, &());
cursor.next(&());
}
} else {
@@ -307,10 +307,10 @@ impl FoldMap {
}
}
- edit.new_range.end =
- ((edit.new_range.start + edit.old_extent()) as isize + delta) as usize;
+ edit.new_bytes.end =
+ ((edit.new_bytes.start + edit.deleted_bytes()) as isize + delta) as usize;
- let anchor = buffer.anchor_before(edit.new_range.start);
+ let anchor = buffer.anchor_before(edit.new_bytes.start);
let mut folds_cursor = self.folds.cursor::<_, ()>();
folds_cursor.seek(&Fold(anchor..Anchor::max()), Bias::Left, buffer);
let mut folds = iter::from_fn(move || {
@@ -324,7 +324,7 @@ impl FoldMap {
while folds
.peek()
- .map_or(false, |fold| fold.start < edit.new_range.end)
+ .map_or(false, |fold| fold.start < edit.new_bytes.end)
{
let mut fold = folds.next().unwrap();
let sum = new_transforms.summary();
@@ -380,9 +380,9 @@ impl FoldMap {
}
let sum = new_transforms.summary();
- if sum.buffer.bytes < edit.new_range.end {
+ if sum.buffer.bytes < edit.new_bytes.end {
let text_summary =
- buffer.text_summary_for_range(sum.buffer.bytes..edit.new_range.end);
+ buffer.text_summary_for_range(sum.buffer.bytes..edit.new_bytes.end);
new_transforms.push(
Transform {
summary: TransformSummary {
@@ -117,9 +117,8 @@ impl BackgroundWrapper {
{
let mut old_cursor = self.snapshot.transforms.cursor::<Point, ()>();
for edit in buffer.edits_since(self.snapshot.version.clone()) {
- // TODO: old lines gives us an extent but we really want to park ourselves at the start of the line.
new_transforms.push_tree(
- old_cursor.slice(&Point::new(edit.old_lines.row, 0), Bias::Left, &()),
+ old_cursor.slice(&Point::new(edit.old_lines.start.row, 0), Bias::Left, &()),
&(),
);
}