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:
parent
14ba4a9c94
commit
f561a91daf
5 changed files with 537 additions and 106 deletions
|
@ -26,7 +26,7 @@ use text::ReplicaId;
|
|||
use util::{paths::SanitizedPath, ResultExt};
|
||||
use worktree::{Entry, ProjectEntryId, Worktree, WorktreeId, WorktreeSettings};
|
||||
|
||||
use crate::{search::SearchQuery, ProjectPath};
|
||||
use crate::{search::SearchQuery, LspStore, ProjectPath};
|
||||
|
||||
struct MatchingEntry {
|
||||
worktree_path: Arc<Path>,
|
||||
|
@ -69,7 +69,6 @@ impl EventEmitter<WorktreeStoreEvent> for WorktreeStore {}
|
|||
impl WorktreeStore {
|
||||
pub fn init(client: &AnyProtoClient) {
|
||||
client.add_model_request_handler(Self::handle_create_project_entry);
|
||||
client.add_model_request_handler(Self::handle_rename_project_entry);
|
||||
client.add_model_request_handler(Self::handle_copy_project_entry);
|
||||
client.add_model_request_handler(Self::handle_delete_project_entry);
|
||||
client.add_model_request_handler(Self::handle_expand_project_entry);
|
||||
|
@ -184,6 +183,19 @@ impl WorktreeStore {
|
|||
.find_map(|worktree| worktree.read(cx).entry_for_id(entry_id))
|
||||
}
|
||||
|
||||
pub fn worktree_and_entry_for_id<'a>(
|
||||
&'a self,
|
||||
entry_id: ProjectEntryId,
|
||||
cx: &'a AppContext,
|
||||
) -> Option<(Model<Worktree>, &'a Entry)> {
|
||||
self.worktrees().find_map(|worktree| {
|
||||
worktree
|
||||
.read(cx)
|
||||
.entry_for_id(entry_id)
|
||||
.map(|e| (worktree.clone(), e))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn entry_for_path(&self, path: &ProjectPath, cx: &AppContext) -> Option<Entry> {
|
||||
self.worktree_for_id(path.worktree_id, cx)?
|
||||
.read(cx)
|
||||
|
@ -1004,16 +1016,56 @@ impl WorktreeStore {
|
|||
}
|
||||
|
||||
pub async fn handle_rename_project_entry(
|
||||
this: Model<Self>,
|
||||
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 = this.update(&mut cx, |this, cx| {
|
||||
this.worktree_for_entry(entry_id, cx)
|
||||
.ok_or_else(|| anyhow!("worktree not found"))
|
||||
})??;
|
||||
Worktree::handle_rename_entry(worktree, envelope.payload, cx).await
|
||||
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(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue