diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 5ddebcaff6..90e86a20c4 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -425,8 +425,6 @@ impl Buffer { UNIX_EPOCH }; - let git_diff = smol::block_on(BufferDiff::new(head_text.clone(), &buffer)); - Self { saved_mtime, saved_version: buffer.version(), @@ -435,7 +433,7 @@ impl Buffer { was_dirty_before_starting_transaction: None, text: buffer, head_text, - git_diff, + git_diff: BufferDiff::new(), file, syntax_map: Mutex::new(SyntaxMap::new()), parsing_in_background: false, @@ -659,16 +657,18 @@ impl Buffer { } pub fn update_git(&mut self, cx: &mut ModelContext) { - if self.head_text.is_some() { + if let Some(head_text) = &self.head_text { let snapshot = self.snapshot(); - let head_text = self.head_text.clone(); + let head_text = head_text.clone(); - let buffer_diff = cx - .background() - .spawn(async move { BufferDiff::new(head_text, &snapshot).await }); + let mut diff = self.git_diff.clone(); + let diff = cx.background().spawn(async move { + diff.update(&head_text, &snapshot).await; + diff + }); cx.spawn_weak(|this, mut cx| async move { - let buffer_diff = buffer_diff.await; + let buffer_diff = diff.await; if let Some(this) = this.upgrade(&cx) { this.update(&mut cx, |this, cx| { this.git_diff = buffer_diff; diff --git a/crates/language/src/git.rs b/crates/language/src/git.rs index 65ac373f7a..d713dcbc14 100644 --- a/crates/language/src/git.rs +++ b/crates/language/src/git.rs @@ -1,4 +1,4 @@ -use std::{ops::Range, sync::Arc}; +use std::ops::Range; use sum_tree::SumTree; use text::{Anchor, BufferSnapshot, OffsetRangeExt, Point, ToPoint}; @@ -98,22 +98,16 @@ impl<'a> sum_tree::Dimension<'a, DiffHunkSummary> for HunkBufferEnd { #[derive(Clone)] pub struct BufferDiff { - last_buffer_version: clock::Global, + last_buffer_version: Option, tree: SumTree>, } impl BufferDiff { - pub async fn new(head_text: Option>, buffer: &text::BufferSnapshot) -> BufferDiff { - let mut instance = BufferDiff { - last_buffer_version: buffer.version().clone(), + pub fn new() -> BufferDiff { + BufferDiff { + last_buffer_version: None, tree: SumTree::new(), - }; - - if let Some(head_text) = head_text { - instance.update(&*head_text, buffer); } - - instance } pub fn hunks_in_range<'a>( @@ -142,10 +136,13 @@ impl BufferDiff { } pub fn needs_update(&self, buffer: &text::BufferSnapshot) -> bool { - buffer.version().changed_since(&self.last_buffer_version) + match &self.last_buffer_version { + Some(last) => buffer.version().changed_since(last), + None => true, + } } - fn update(&mut self, head_text: &str, buffer: &text::BufferSnapshot) { + pub async fn update(&mut self, head_text: &str, buffer: &text::BufferSnapshot) { let mut tree = SumTree::new(); let buffer_text = buffer.as_rope().to_string(); @@ -160,7 +157,7 @@ impl BufferDiff { } self.tree = tree; - self.last_buffer_version = buffer.version().clone(); + self.last_buffer_version = Some(buffer.version().clone()); } #[cfg(test)] @@ -279,7 +276,8 @@ mod tests { .unindent(); let mut buffer = Buffer::new(0, 0, buffer_text); - let diff = smol::block_on(BufferDiff::new(Some(Arc::new(head_text.clone())), &buffer)); + let mut diff = BufferDiff::new(); + smol::block_on(diff.update(&head_text, &buffer)); assert_hunks(&diff, &buffer, &head_text, &[(1..2, "two\n")]); buffer.edit([(0..0, "point five\n")]); diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 42d18eb3bb..2ff3e6fe04 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -449,7 +449,11 @@ impl LocalWorktree { let (file, contents, head_text) = this .update(&mut cx, |t, cx| t.as_local().unwrap().load(&path, cx)) .await?; - Ok(cx.add_model(|cx| Buffer::from_file(0, contents, head_text, Arc::new(file), cx))) + Ok(cx.add_model(|cx| { + let mut buffer = Buffer::from_file(0, contents, head_text, Arc::new(file), cx); + buffer.update_git(cx); + buffer + })) }) }