mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-12 13:24:19 +00:00
Calculate an old_lines
range in Edits
iterator
This commit is contained in:
parent
c2e7460fcd
commit
be954872d0
3 changed files with 96 additions and 81 deletions
|
@ -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, &()),
|
||||
&(),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue