ssh: Fix abs paths in file history & repeated go-to-def (#19027)

This fixes two things:

- Go-to-def to absolute paths (i.e. opening stdlib files) multiple times
(opening, dropping, and re-opening worktrees)
- Re-opening abs paths from the file picker history that were added
there by go-to-def


Release Notes:

- N/A

---------

Co-authored-by: Bennet <bennet@zed.dev>
This commit is contained in:
Thorsten Ball 2024-10-11 11:21:34 +02:00 committed by GitHub
parent 4726f30bd6
commit 1691652948
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 145 additions and 74 deletions

View file

@ -135,6 +135,8 @@ impl HeadlessProject {
client.add_request_handler(cx.weak_model(), Self::handle_ping);
client.add_model_request_handler(Self::handle_add_worktree);
client.add_request_handler(cx.weak_model(), Self::handle_remove_worktree);
client.add_model_request_handler(Self::handle_open_buffer_by_path);
client.add_model_request_handler(Self::handle_find_search_candidates);
@ -238,7 +240,7 @@ impl HeadlessProject {
.update(&mut cx.clone(), |this, _| {
Worktree::local(
Arc::from(canonicalized),
true,
message.payload.visible,
this.fs.clone(),
this.next_entry_id.clone(),
&mut cx,
@ -246,14 +248,49 @@ impl HeadlessProject {
})?
.await?;
this.update(&mut cx, |this, cx| {
this.worktree_store.update(cx, |worktree_store, cx| {
worktree_store.add(&worktree, cx);
});
let response = this.update(&mut cx, |_, cx| {
worktree.update(cx, |worktree, _| proto::AddWorktreeResponse {
worktree_id: worktree.id().to_proto(),
})
})?;
// We spawn this asynchronously, so that we can send the response back
// *before* `worktree_store.add()` can send out UpdateProject requests
// to the client about the new worktree.
//
// That lets the client manage the reference/handles of the newly-added
// worktree, before getting interrupted by an UpdateProject request.
//
// This fixes the problem of the client sending the AddWorktree request,
// headless project sending out a project update, client receiving it
// and immediately dropping the reference of the new client, causing it
// to be dropped on the headless project, and the client only then
// receiving a response to AddWorktree.
cx.spawn(|mut cx| async move {
this.update(&mut cx, |this, cx| {
this.worktree_store.update(cx, |worktree_store, cx| {
worktree_store.add(&worktree, cx);
});
})
.log_err();
})
.detach();
Ok(response)
}
pub async fn handle_remove_worktree(
this: Model<Self>,
envelope: TypedEnvelope<proto::RemoveWorktree>,
mut cx: AsyncAppContext,
) -> Result<proto::Ack> {
let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
this.update(&mut cx, |this, cx| {
this.worktree_store.update(cx, |worktree_store, cx| {
worktree_store.remove_worktree(worktree_id, cx);
});
})?;
Ok(proto::Ack {})
}
pub async fn handle_open_buffer_by_path(