mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
Load diff base for buffers that are opening but not yet opened when repositories are discovered
This commit is contained in:
parent
fc82489128
commit
51d94f532b
@ -16,6 +16,7 @@ use copilot::Copilot;
|
||||
use futures::{
|
||||
channel::mpsc::{self, UnboundedReceiver},
|
||||
future::{try_join_all, Shared},
|
||||
stream::FuturesUnordered,
|
||||
AsyncWriteExt, Future, FutureExt, StreamExt, TryFutureExt,
|
||||
};
|
||||
use globset::{Glob, GlobSet, GlobSetBuilder};
|
||||
@ -1374,7 +1375,7 @@ impl Project {
|
||||
return Task::ready(Ok(existing_buffer));
|
||||
}
|
||||
|
||||
let mut loading_watch = match self.loading_buffers_by_path.entry(project_path.clone()) {
|
||||
let loading_watch = match self.loading_buffers_by_path.entry(project_path.clone()) {
|
||||
// If the given path is already being loaded, then wait for that existing
|
||||
// task to complete and return the same buffer.
|
||||
hash_map::Entry::Occupied(e) => e.get().clone(),
|
||||
@ -1405,15 +1406,9 @@ impl Project {
|
||||
};
|
||||
|
||||
cx.foreground().spawn(async move {
|
||||
loop {
|
||||
if let Some(result) = loading_watch.borrow().as_ref() {
|
||||
match result {
|
||||
Ok(buffer) => return Ok(buffer.clone()),
|
||||
Err(error) => return Err(anyhow!("{}", error)),
|
||||
}
|
||||
}
|
||||
loading_watch.next().await;
|
||||
}
|
||||
pump_loading_buffer_reciever(loading_watch)
|
||||
.await
|
||||
.map_err(|error| anyhow!("{}", error))
|
||||
})
|
||||
}
|
||||
|
||||
@ -4822,6 +4817,51 @@ impl Project {
|
||||
) {
|
||||
debug_assert!(worktree_handle.read(cx).is_local());
|
||||
|
||||
// Setup the pending buffers
|
||||
let future_buffers = self
|
||||
.loading_buffers_by_path
|
||||
.iter()
|
||||
.filter_map(|(path, receiver)| {
|
||||
let path = &path.path;
|
||||
let (work_directory, repo) = repos
|
||||
.iter()
|
||||
.find(|(work_directory, _)| path.starts_with(work_directory))?;
|
||||
|
||||
let repo_relative_path = path.strip_prefix(work_directory).log_err()?;
|
||||
|
||||
let receiver = receiver.clone();
|
||||
let repo_ptr = repo.repo_ptr.clone();
|
||||
let repo_relative_path = repo_relative_path.to_owned();
|
||||
Some(async move {
|
||||
pump_loading_buffer_reciever(receiver)
|
||||
.await
|
||||
.ok()
|
||||
.map(|buffer| (buffer, repo_relative_path, repo_ptr))
|
||||
})
|
||||
})
|
||||
.collect::<FuturesUnordered<_>>()
|
||||
.filter_map(|result| async move {
|
||||
let (buffer_handle, repo_relative_path, repo_ptr) = result?;
|
||||
|
||||
let lock = repo_ptr.lock();
|
||||
lock.load_index_text(&repo_relative_path)
|
||||
.map(|diff_base| (diff_base, buffer_handle))
|
||||
});
|
||||
|
||||
let update_diff_base_fn = update_diff_base(self);
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
let diff_base_tasks = cx
|
||||
.background()
|
||||
.spawn(future_buffers.collect::<Vec<_>>())
|
||||
.await;
|
||||
|
||||
for (diff_base, buffer) in diff_base_tasks.into_iter() {
|
||||
update_diff_base_fn(Some(diff_base), buffer, &mut cx);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
// And the current buffers
|
||||
for (_, buffer) in &self.opened_buffers {
|
||||
if let Some(buffer) = buffer.upgrade(cx) {
|
||||
let file = match File::from_dyn(buffer.read(cx).file()) {
|
||||
@ -4841,18 +4881,17 @@ impl Project {
|
||||
.find(|(work_directory, _)| path.starts_with(work_directory))
|
||||
{
|
||||
Some(repo) => repo.clone(),
|
||||
None => return,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let relative_repo = match path.strip_prefix(work_directory).log_err() {
|
||||
Some(relative_repo) => relative_repo.to_owned(),
|
||||
None => return,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
drop(worktree);
|
||||
|
||||
let remote_id = self.remote_id();
|
||||
let client = self.client.clone();
|
||||
let update_diff_base_fn = update_diff_base(self);
|
||||
let git_ptr = repo.repo_ptr.clone();
|
||||
let diff_base_task = cx
|
||||
.background()
|
||||
@ -4860,21 +4899,7 @@ impl Project {
|
||||
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
let diff_base = diff_base_task.await;
|
||||
|
||||
let buffer_id = buffer.update(&mut cx, |buffer, cx| {
|
||||
buffer.set_diff_base(diff_base.clone(), cx);
|
||||
buffer.remote_id()
|
||||
});
|
||||
|
||||
if let Some(project_id) = remote_id {
|
||||
client
|
||||
.send(proto::UpdateDiffBase {
|
||||
project_id,
|
||||
buffer_id: buffer_id as u64,
|
||||
diff_base,
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
update_diff_base_fn(diff_base, buffer, &mut cx);
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
@ -6764,3 +6789,40 @@ impl Item for Buffer {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn pump_loading_buffer_reciever(
|
||||
mut receiver: postage::watch::Receiver<Option<Result<ModelHandle<Buffer>, Arc<anyhow::Error>>>>,
|
||||
) -> Result<ModelHandle<Buffer>, Arc<anyhow::Error>> {
|
||||
loop {
|
||||
if let Some(result) = receiver.borrow().as_ref() {
|
||||
match result {
|
||||
Ok(buffer) => return Ok(buffer.to_owned()),
|
||||
Err(e) => return Err(e.to_owned()),
|
||||
}
|
||||
}
|
||||
receiver.next().await;
|
||||
}
|
||||
}
|
||||
|
||||
fn update_diff_base(
|
||||
project: &Project,
|
||||
) -> impl Fn(Option<String>, ModelHandle<Buffer>, &mut AsyncAppContext) {
|
||||
let remote_id = project.remote_id();
|
||||
let client = project.client().clone();
|
||||
move |diff_base, buffer, cx| {
|
||||
let buffer_id = buffer.update(cx, |buffer, cx| {
|
||||
buffer.set_diff_base(diff_base.clone(), cx);
|
||||
buffer.remote_id()
|
||||
});
|
||||
|
||||
if let Some(project_id) = remote_id {
|
||||
client
|
||||
.send(proto::UpdateDiffBase {
|
||||
project_id,
|
||||
buffer_id: buffer_id as u64,
|
||||
diff_base,
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -839,6 +839,7 @@ impl LocalWorktree {
|
||||
fn set_snapshot(&mut self, new_snapshot: LocalSnapshot, cx: &mut ModelContext<Worktree>) {
|
||||
let updated_repos =
|
||||
self.changed_repos(&self.git_repositories, &new_snapshot.git_repositories);
|
||||
|
||||
self.snapshot = new_snapshot;
|
||||
|
||||
if let Some(share) = self.share.as_mut() {
|
||||
|
Loading…
Reference in New Issue
Block a user