lsp: Add support for didRename/willRename LSP messages (#21651)

Closes #21564

Notably, RA will now rename module references if you change the source
file name via our project panel.

This PR is a tad bigger than necessary as I torn out the Model<> from
didSave watchers (I tried to reuse that code for the same purpose).
Release Notes:

- Added support for language server actions being executed on file
rename.
This commit is contained in:
Piotr Osiewicz 2024-12-07 13:08:18 +01:00 committed by GitHub
parent 14ba4a9c94
commit f561a91daf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 537 additions and 106 deletions

View file

@ -583,6 +583,8 @@ 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);
@ -1489,11 +1491,45 @@ impl Project {
new_path: impl Into<Arc<Path>>,
cx: &mut ModelContext<Self>,
) -> Task<Result<CreatedEntry>> {
let Some(worktree) = self.worktree_for_entry(entry_id, cx) else {
let worktree_store = self.worktree_store.read(cx);
let new_path = new_path.into();
let Some((worktree, old_path, is_dir)) = worktree_store
.worktree_and_entry_for_id(entry_id, cx)
.map(|(worktree, entry)| (worktree, entry.path.clone(), entry.is_dir()))
else {
return Task::ready(Err(anyhow!(format!("No worktree for entry {entry_id:?}"))));
};
worktree.update(cx, |worktree, cx| {
worktree.rename_entry(entry_id, new_path, cx)
let worktree_id = worktree.read(cx).id();
let lsp_store = self.lsp_store().downgrade();
cx.spawn(|_, mut cx| async move {
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(&new_path))
};
LspStore::will_rename_entry(
lsp_store.clone(),
worktree_id,
&old_abs_path,
&new_abs_path,
is_dir,
cx.clone(),
)
.await;
let entry = worktree
.update(&mut cx, |worktree, cx| {
worktree.rename_entry(entry_id, new_path.clone(), cx)
})?
.await?;
lsp_store
.update(&mut cx, |this, _| {
this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
})
.ok();
Ok(entry)
})
}