From 54421b11f33ad4d27e49950da776025c0a608946 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 18 May 2023 10:58:24 -0700 Subject: [PATCH] wip --- crates/language/src/buffer.rs | 18 +++++++++++++++- crates/project/src/project.rs | 40 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 5539d1d941..93955a2474 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -682,6 +682,20 @@ impl Buffer { self.git_diff_status.diff.needs_update(self) } + fn git_diff_recalc_2(&mut self, cx: &mut ModelContext) -> Option> { + let diff_base = &self.diff_base?; + let snapshot = self.snapshot(); + let handle = cx.weak_handle(); + + let mut diff = self.git_diff_status.diff.clone(); + Some(cx.background().spawn(async move { + diff.update(&diff_base, &snapshot).await; + if let Some(this) = handle.upgrade(cx) { + // this.update(cx) + } + })) + } + pub fn git_diff_recalc(&mut self, cx: &mut ModelContext) { if self.git_diff_status.update_in_progress { self.git_diff_status.update_requested = true; @@ -689,6 +703,7 @@ impl Buffer { } if let Some(diff_base) = &self.diff_base { + self.git_diff_status.update_in_progress = true; let snapshot = self.snapshot(); let diff_base = diff_base.clone(); @@ -706,9 +721,10 @@ impl Buffer { this.git_diff_update_count += 1; cx.notify(); - this.git_diff_status.update_in_progress = false; if this.git_diff_status.update_requested { this.git_diff_recalc(cx); + } else { + this.git_diff_status.update_in_progress = false; } }) } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 391a698a1b..f93d7d4b50 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -130,6 +130,7 @@ pub struct Project { incomplete_remote_buffers: HashMap>>, buffer_snapshots: HashMap>>, // buffer_id -> server_id -> vec of snapshots buffers_being_formatted: HashSet, + buffers_needing_diff: HashSet>, nonce: u128, _maintain_buffer_languages: Task<()>, _maintain_workspace_config: Task<()>, @@ -484,6 +485,7 @@ impl Project { language_server_statuses: Default::default(), last_workspace_edits_by_language_server: Default::default(), buffers_being_formatted: Default::default(), + buffers_needing_diff: Default::default(), nonce: StdRng::from_entropy().gen(), terminals: Terminals { local_handles: Vec::new(), @@ -573,6 +575,7 @@ impl Project { last_workspace_edits_by_language_server: Default::default(), opened_buffers: Default::default(), buffers_being_formatted: Default::default(), + buffers_needing_diff: Default::default(), buffer_snapshots: Default::default(), nonce: StdRng::from_entropy().gen(), terminals: Terminals { @@ -1924,6 +1927,20 @@ impl Project { event: &BufferEvent, cx: &mut ModelContext, ) -> Option<()> { + if matches!(event, BufferEvent::Edited { .. } | BufferEvent::Reloaded) { + self.buffers_needing_diff.insert(buffer.downgrade()); + if self.buffers_needing_diff.len() == 1 { + let this = cx.weak_handle(); + cx.defer(move |cx| { + if let Some(this) = this.upgrade(cx) { + this.update(cx, |this, cx| { + this.recalculate_buffer_diffs(cx); + }); + } + }); + } + } + match event { BufferEvent::Operation(operation) => { self.buffer_ordered_messages_tx @@ -2063,6 +2080,29 @@ impl Project { None } + fn recalculate_buffer_diffs(&mut self, cx: &mut ModelContext) { + cx.spawn(|this, mut cx| async move { + let tasks: Vec<_> = this.update(&mut cx, |this, cx| { + this.buffers_needing_diff + .drain() + .filter_map(|buffer| { + let buffer = buffer.upgrade(cx)?; + buffer.update(cx, |buffer, cx| buffer.git_diff_recalc_2(cx)) + }) + .collect() + }); + + let updates = futures::future::join_all(tasks).await; + + this.update(&mut cx, |this, cx| { + if !this.buffers_needing_diff.is_empty() { + this.recalculate_buffer_diffs(cx); + } + }); + }) + .detach(); + } + fn language_servers_for_worktree( &self, worktree_id: WorktreeId,