Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
Antonio Scandurra 2021-10-07 19:09:14 +02:00
parent 2018537bb8
commit 54932a8050

View File

@ -151,6 +151,7 @@ impl Drop for QueryCursorHandle {
QUERY_CURSORS.lock().push(cursor)
}
}
pub struct Buffer {
fragments: SumTree<Fragment>,
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<Tree> {
fn syntax_tree(&self) -> Option<Tree> {
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<Tree>,
new_tree: Tree,
old_snapshot: Snapshot,
new_version: clock::Global,
language: Arc<Language>,
cx: &mut ModelContext<Self>,
) {
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<Tree>,
new_tree: &Tree,
language: Arc<Language>,
cx: &mut ModelContext<Self>,
) {
@ -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<u32>,
old_tree: Option<&Tree>,
new_tree: &Tree,
old_snapshot: &Snapshot,
autoindent_requests: &BTreeMap<u32, AutoindentRequest>,
language: &Language,
cursor: &mut QueryCursor,