Skip to content

Commit

Permalink
Fix project entry rename in Remote Development (#23382)
Browse files Browse the repository at this point in the history
Closes #22883

To fix the problem, we move `handle_rename_project_entry` from
`Worktree` to `LspStore` and register it there. This way it becomes
available both in local and headless projects and this avoids the
duplication.

Release Notes:

- Fixed renaming project entries in Remote Development
  • Loading branch information
aborg-dev authored Jan 21, 2025
1 parent cc1af7d commit d40177c
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 56 deletions.
47 changes: 47 additions & 0 deletions crates/project/src/lsp_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2872,6 +2872,7 @@ impl LspStore {
client.add_model_request_handler(Self::handle_on_type_formatting);
client.add_model_request_handler(Self::handle_apply_additional_edits_for_completion);
client.add_model_request_handler(Self::handle_register_buffer_with_language_servers);
client.add_model_request_handler(Self::handle_rename_project_entry);
client.add_model_request_handler(Self::handle_lsp_command::<GetCodeActions>);
client.add_model_request_handler(Self::handle_lsp_command::<GetCompletions>);
client.add_model_request_handler(Self::handle_lsp_command::<GetHover>);
Expand Down Expand Up @@ -5928,6 +5929,52 @@ impl LspStore {
Ok(proto::Ack {})
}

async fn handle_rename_project_entry(
this: Model<Self>,
envelope: TypedEnvelope<proto::RenameProjectEntry>,
mut cx: AsyncAppContext,
) -> Result<proto::ProjectEntryResponse> {
let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
let (worktree_id, worktree, old_path, is_dir) = this
.update(&mut cx, |this, cx| {
this.worktree_store
.read(cx)
.worktree_and_entry_for_id(entry_id, cx)
.map(|(worktree, entry)| {
(
worktree.read(cx).id(),
worktree,
entry.path.clone(),
entry.is_dir(),
)
})
})?
.ok_or_else(|| anyhow!("worktree not found"))?;
let (old_abs_path, new_abs_path) = {
let root_path = worktree.update(&mut cx, |this, _| this.abs_path())?;
(
root_path.join(&old_path),
root_path.join(&envelope.payload.new_path),
)
};

Self::will_rename_entry(
this.downgrade(),
worktree_id,
&old_abs_path,
&new_abs_path,
is_dir,
cx.clone(),
)
.await;
let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
this.update(&mut cx, |this, _| {
this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
})
.ok();
response
}

async fn handle_update_diagnostic_summary(
this: Model<Self>,
envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
Expand Down
2 changes: 0 additions & 2 deletions crates/project/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,6 @@ impl Project {
client.add_model_request_handler(Self::handle_open_new_buffer);
client.add_model_message_handler(Self::handle_create_buffer_for_peer);

client.add_model_request_handler(WorktreeStore::handle_rename_project_entry);

WorktreeStore::init(&client);
BufferStore::init(&client);
LspStore::init(&client);
Expand Down
55 changes: 1 addition & 54 deletions crates/project/src/worktree_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use text::ReplicaId;
use util::{paths::SanitizedPath, ResultExt};
use worktree::{Entry, ProjectEntryId, Worktree, WorktreeId, WorktreeSettings};

use crate::{search::SearchQuery, LspStore, ProjectPath};
use crate::{search::SearchQuery, ProjectPath};

struct MatchingEntry {
worktree_path: Arc<Path>,
Expand Down Expand Up @@ -1018,59 +1018,6 @@ impl WorktreeStore {
Worktree::handle_create_entry(worktree, envelope.payload, cx).await
}

pub async fn handle_rename_project_entry(
this: Model<super::Project>,
envelope: TypedEnvelope<proto::RenameProjectEntry>,
mut cx: AsyncAppContext,
) -> Result<proto::ProjectEntryResponse> {
let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
let (worktree_id, worktree, old_path, is_dir) = this
.update(&mut cx, |this, cx| {
this.worktree_store
.read(cx)
.worktree_and_entry_for_id(entry_id, cx)
.map(|(worktree, entry)| {
(
worktree.read(cx).id(),
worktree,
entry.path.clone(),
entry.is_dir(),
)
})
})?
.ok_or_else(|| anyhow!("worktree not found"))?;
let (old_abs_path, new_abs_path) = {
let root_path = worktree.update(&mut cx, |this, _| this.abs_path())?;
(
root_path.join(&old_path),
root_path.join(&envelope.payload.new_path),
)
};
let lsp_store = this
.update(&mut cx, |this, _| this.lsp_store())?
.downgrade();
LspStore::will_rename_entry(
lsp_store,
worktree_id,
&old_abs_path,
&new_abs_path,
is_dir,
cx.clone(),
)
.await;
let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
this.update(&mut cx, |this, cx| {
this.lsp_store().read(cx).did_rename_entry(
worktree_id,
&old_abs_path,
&new_abs_path,
is_dir,
);
})
.ok();
response
}

pub async fn handle_copy_project_entry(
this: Model<Self>,
envelope: TypedEnvelope<proto::CopyProjectEntry>,
Expand Down
40 changes: 40 additions & 0 deletions crates/remote_server/src/remote_editing_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,46 @@ async fn test_remote_root_rename(cx: &mut TestAppContext, server_cx: &mut TestAp
})
}

#[gpui::test]
async fn test_remote_rename_entry(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
let fs = FakeFs::new(server_cx.executor());
fs.insert_tree(
"/code",
json!({
"project1": {
".git": {},
"README.md": "# project 1",
},
}),
)
.await;

let (project, _) = init_test(&fs, cx, server_cx).await;
let (worktree, _) = project
.update(cx, |project, cx| {
project.find_or_create_worktree("/code/project1", true, cx)
})
.await
.unwrap();

cx.run_until_parked();

let entry = worktree
.update(cx, |worktree, cx| {
let entry = worktree.entry_for_path("README.md").unwrap();
worktree.rename_entry(entry.id, Path::new("README.rst"), cx)
})
.await
.unwrap()
.to_included()
.unwrap();

cx.run_until_parked();

worktree.update(cx, |worktree, _| {
assert_eq!(worktree.entry_for_path("README.rst").unwrap().id, entry.id)
});
}
#[gpui::test]
async fn test_remote_git_branches(cx: &mut TestAppContext, server_cx: &mut TestAppContext) {
let fs = FakeFs::new(server_cx.executor());
Expand Down

0 comments on commit d40177c

Please sign in to comment.