From 3af69b535992203c2582433d968eed22a7e7fe69 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 10 Mar 2021 15:49:01 +0100 Subject: Avoid double text edits when renaming mod declaration --- crates/hir/src/lib.rs | 1 - crates/ide/src/references/rename.rs | 1 + crates/rust-analyzer/src/config.rs | 3 +++ crates/rust-analyzer/src/handlers.rs | 12 +++++++++++- 4 files changed, 15 insertions(+), 2 deletions(-) (limited to 'crates') diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 4ef38c0f0..58adc8fd3 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -305,7 +305,6 @@ impl ModuleDef { ModuleDef::Module(it) => it.name(db), ModuleDef::Const(it) => it.name(db), ModuleDef::Static(it) => it.name(db), - ModuleDef::BuiltinType(it) => Some(it.name()), } } diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 05c73de88..bb68bcc78 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs @@ -94,6 +94,7 @@ pub(crate) fn rename_with_semantics( } } +/// Called by the client when it is about to rename a file. pub(crate) fn will_rename_file( db: &RootDatabase, file_id: FileId, diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 25df13554..8af7871ac 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -395,6 +395,9 @@ impl Config { pub fn work_done_progress(&self) -> bool { try_or!(self.caps.window.as_ref()?.work_done_progress?, false) } + pub fn will_rename(&self) -> bool { + try_or!(self.caps.workspace.as_ref()?.file_operations.as_ref()?.will_rename?, false) + } pub fn code_action_resolve(&self) -> bool { try_or!( self.caps diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index b5b2ffe50..6cc433cb8 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -799,8 +799,18 @@ pub(crate) fn handle_rename( let _p = profile::span("handle_rename"); let position = from_proto::file_position(&snap, params.text_document_position)?; - let change = + let mut change = snap.analysis.rename(position, &*params.new_name)?.map_err(to_proto::rename_error)?; + + // this is kind of a hack to prevent double edits from happening when moving files + // When a module gets renamed by renaming the mod declaration this causes the file to move + // which in turn will trigger a WillRenameFiles request to the server for which we reply with a + // a second identical set of renames, the client will then apply both edits causing incorrect edits + // with this we only emit source_file_edits in the WillRenameFiles response which will do the rename instead + // See https://github.com/microsoft/vscode-languageserver-node/issues/752 for more info + if !change.file_system_edits.is_empty() && snap.config.will_rename() { + change.source_file_edits.clear(); + } let workspace_edit = to_proto::workspace_edit(&snap, change)?; Ok(Some(workspace_edit)) } -- cgit v1.2.3