From 54932a805086d9a8974b944448f57d235e7307c8 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 7 Oct 2021 19:09:14 +0200 Subject: [PATCH] WIP Co-Authored-By: Max Brunsfeld --- crates/buffer/src/lib.rs | 126 ++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 48 deletions(-) diff --git a/crates/buffer/src/lib.rs b/crates/buffer/src/lib.rs index 19b5707405..ef3dcef929 100644 --- a/crates/buffer/src/lib.rs +++ b/crates/buffer/src/lib.rs @@ -151,6 +151,7 @@ impl Drop for QueryCursorHandle { QUERY_CURSORS.lock().push(cursor) } } + pub struct Buffer { fragments: SumTree, visible_text: Rope, @@ -192,6 +193,30 @@ struct SyntaxTree { version: clock::Global, } +impl SyntaxTree { + fn interpolate(&mut self, buffer: &Buffer) { + let mut delta = 0_isize; + for edit in buffer.edits_since(self.version.clone()) { + let start_offset = (edit.old_bytes.start as isize + delta) as usize; + let start_point = buffer.visible_text.to_point(start_offset); + self.tree.edit(&InputEdit { + start_byte: start_offset, + 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 + edit.deleted_lines()).into(), + new_end_position: buffer + .visible_text + .to_point(start_offset + edit.inserted_bytes()) + .into(), + }); + delta += edit.inserted_bytes() as isize - edit.deleted_bytes() as isize; + self.dirty = true; + } + self.version = buffer.version(); + } +} + #[derive(Clone, Debug)] struct AutoindentRequest { position: Anchor, @@ -850,27 +875,9 @@ impl Buffer { self.parse_count } - pub fn syntax_tree(&self) -> Option { + fn syntax_tree(&self) -> Option { if let Some(syntax_tree) = self.syntax_tree.lock().as_mut() { - let mut delta = 0_isize; - 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); - syntax_tree.tree.edit(&InputEdit { - start_byte: start_offset, - 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 + edit.deleted_lines()).into(), - new_end_position: self - .visible_text - .to_point(start_offset + edit.inserted_bytes()) - .into(), - }); - delta += edit.inserted_bytes() as isize - edit.deleted_bytes() as isize; - syntax_tree.dirty = true; - } - syntax_tree.version = self.version(); + syntax_tree.interpolate(self); Some(syntax_tree.tree.clone()) } else { None @@ -893,13 +900,16 @@ impl Buffer { } if let Some(language) = self.language.clone() { - let old_snapshot = self.snapshot(); + let old_tree = self.syntax_tree.lock().as_mut().map(|tree| { + tree.interpolate(self); + tree.clone() + }); + let text = self.visible_text.clone(); let parsed_version = self.version(); let parse_task = cx.background().spawn({ let language = language.clone(); - let text = old_snapshot.visible_text.clone(); - let tree = old_snapshot.tree.clone(); - async move { Self::parse_text(&text, tree, &language) } + let old_tree = old_tree.as_ref().map(|t| t.tree.clone()); + async move { Self::parse_text(&text, old_tree, &language) } }); match cx @@ -907,13 +917,13 @@ impl Buffer { .block_with_timeout(self.sync_parse_timeout, parse_task) { Ok(new_tree) => { - *self.syntax_tree.lock() = Some(SyntaxTree { - tree: new_tree.clone(), - dirty: false, - version: parsed_version, - }); - self.parse_count += 1; - self.did_finish_parsing(new_tree, old_snapshot, language, cx); + self.did_finish_parsing( + old_tree.map(|t| t.tree), + new_tree, + parsed_version, + language, + cx, + ); return true; } Err(parse_task) => { @@ -926,19 +936,22 @@ impl Buffer { !Arc::ptr_eq(curr_language, &language) }); let parse_again = this.version > parsed_version || language_changed; - *this.syntax_tree.lock() = Some(SyntaxTree { - tree: new_tree.clone(), - dirty: false, - version: parsed_version, + let old_tree = old_tree.map(|mut old_tree| { + old_tree.interpolate(this); + old_tree.tree }); - this.parse_count += 1; this.parsing_in_background = false; + this.did_finish_parsing( + old_tree, + new_tree, + parsed_version, + language, + cx, + ); if parse_again && this.reparse(cx) { return; } - - this.did_finish_parsing(new_tree, old_snapshot, language, cx); }); }) .detach(); @@ -970,8 +983,28 @@ impl Buffer { fn did_finish_parsing( &mut self, + old_tree: Option, new_tree: Tree, - old_snapshot: Snapshot, + new_version: clock::Global, + language: Arc, + cx: &mut ModelContext, + ) { + self.perform_autoindent(old_tree, &new_tree, language, cx); + + self.parse_count += 1; + *self.syntax_tree.lock() = Some(SyntaxTree { + tree: new_tree, + dirty: false, + version: new_version, + }); + cx.emit(Event::Reparsed); + cx.notify(); + } + + fn perform_autoindent( + &mut self, + old_tree: Option, + new_tree: &Tree, language: Arc, cx: &mut ModelContext, ) { @@ -999,10 +1032,10 @@ impl Buffer { if range.end == row { range.end += 1; } else { - self.perform_autoindent( + self.perform_autoindent_for_rows( range.clone(), + old_tree.as_ref(), &new_tree, - &old_snapshot, &autoindent_requests_by_row, language.as_ref(), &mut cursor, @@ -1014,10 +1047,10 @@ impl Buffer { } } if let Some(range) = row_range { - self.perform_autoindent( + self.perform_autoindent_for_rows( range, + old_tree.as_ref(), &new_tree, - &old_snapshot, &autoindent_requests_by_row, language.as_ref(), &mut cursor, @@ -1025,16 +1058,13 @@ impl Buffer { ); } self.end_transaction(None, cx).unwrap(); - - cx.emit(Event::Reparsed); - cx.notify(); } - fn perform_autoindent( + fn perform_autoindent_for_rows( &mut self, row_range: Range, + old_tree: Option<&Tree>, new_tree: &Tree, - old_snapshot: &Snapshot, autoindent_requests: &BTreeMap, language: &Language, cursor: &mut QueryCursor,