mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-10 05:37:29 +03:00
WIP
Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
parent
2018537bb8
commit
54932a8050
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user