From 3dd581b97d051e091037abca62564630d51bfea8 Mon Sep 17 00:00:00 2001 From: rainy-me Date: Tue, 12 Apr 2022 23:01:53 +0900 Subject: [PATCH] fix: move dir on rename mod --- crates/ide/src/rename.rs | 74 ++++++++++++++++++++++++++-- crates/ide_assists/src/tests.rs | 4 ++ crates/ide_db/src/rename.rs | 26 ++++++---- crates/ide_db/src/source_change.rs | 1 + crates/rust-analyzer/src/to_proto.rs | 14 ++++++ 5 files changed, 106 insertions(+), 13 deletions(-) diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index 83bc299adcc..b850908ce55 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -963,15 +963,21 @@ fn test_rename_mod_in_dir() { }, }, file_system_edits: [ - MoveFile { - src: FileId( + MoveDir { + src: AnchoredPathBuf { + anchor: FileId( + 1, + ), + path: "foo", + }, + src_id: FileId( 1, ), dst: AnchoredPathBuf { anchor: FileId( 1, ), - path: "../foo2/mod.rs", + path: "foo2", }, }, ], @@ -1108,6 +1114,68 @@ fn f() { ); } + #[test] + fn test_rename_mod_recursive() { + check_expect( + "foo2", + r#" +//- /lib.rs +mod foo$0; + +//- /foo.rs +mod bar; +mod corge; + +//- /foo/bar.rs +mod qux; + +//- /foo/bar/qux.rs +mod quux; + +//- /foo/bar/qux/quux/mod.rs +// empty + +//- /foo/corge.rs +// empty +"#, + expect![[r#" + SourceChange { + source_file_edits: { + FileId( + 0, + ): TextEdit { + indels: [ + Indel { + insert: "foo2", + delete: 4..7, + }, + ], + }, + }, + file_system_edits: [ + MoveDir { + src: AnchoredPathBuf { + anchor: FileId( + 1, + ), + path: "foo", + }, + src_id: FileId( + 1, + ), + dst: AnchoredPathBuf { + anchor: FileId( + 1, + ), + path: "foo2", + }, + }, + ], + is_snippet: false, + } + "#]], + ) + } #[test] fn test_rename_mod_ref_by_super() { check( diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs index 09260c12ed9..b3a0bd27730 100644 --- a/crates/ide_assists/src/tests.rs +++ b/crates/ide_assists/src/tests.rs @@ -162,6 +162,10 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label: FileSystemEdit::MoveFile { src, dst } => { (dst, db.file_text(src).as_ref().to_owned()) } + FileSystemEdit::MoveDir { src, src_id, dst } => { + // temporary placeholder for MoveDir since we are not using MoveDir in ide assists yet. + (dst, format!("{:?}\n{:?}", src_id, src)) + } }; let sr = db.file_source_root(dst.anchor); let sr = db.source_root(sr); diff --git a/crates/ide_db/src/rename.rs b/crates/ide_db/src/rename.rs index 13234a817b2..589975406a4 100644 --- a/crates/ide_db/src/rename.rs +++ b/crates/ide_db/src/rename.rs @@ -178,17 +178,23 @@ fn rename_mod( let mut source_change = SourceChange::default(); let InFile { file_id, value: def_source } = module.definition_source(sema.db); - let file_id = file_id.original_file(sema.db); if let ModuleSource::SourceFile(..) = def_source { - // mod is defined in path/to/dir/mod.rs - let path = if module.is_mod_rs(sema.db) { - format!("../{}/mod.rs", new_name) - } else { - format!("{}.rs", new_name) - }; - let dst = AnchoredPathBuf { anchor: file_id, path }; - let move_file = FileSystemEdit::MoveFile { src: file_id, dst }; - source_change.push_file_system_edit(move_file); + let anchor = file_id.original_file(sema.db); + // not mod.rs and doesn't has children, rename file only + if !module.is_mod_rs(sema.db) && module.children(sema.db).next().is_none() { + let path = format!("{}.rs", new_name); + let dst = AnchoredPathBuf { anchor, path }; + source_change.push_file_system_edit(FileSystemEdit::MoveFile { src: anchor, dst }) + } else if let Some(mod_name) = module.name(sema.db) { + // is mod.rs or has children, rename dir + let src = AnchoredPathBuf { anchor, path: mod_name.to_string() }; + let dst = AnchoredPathBuf { anchor, path: new_name.to_string() }; + source_change.push_file_system_edit(FileSystemEdit::MoveDir { + src, + src_id: anchor, + dst, + }) + } } if let Some(src) = module.declaration_source(sema.db) { diff --git a/crates/ide_db/src/source_change.rs b/crates/ide_db/src/source_change.rs index aa910eb3254..8132c73ef26 100644 --- a/crates/ide_db/src/source_change.rs +++ b/crates/ide_db/src/source_change.rs @@ -85,6 +85,7 @@ fn from(source_file_edits: FxHashMap) -> SourceChange { pub enum FileSystemEdit { CreateFile { dst: AnchoredPathBuf, initial_contents: String }, MoveFile { src: FileId, dst: AnchoredPathBuf }, + MoveDir { src: AnchoredPathBuf, src_id: FileId, dst: AnchoredPathBuf }, } impl From for SourceChange { diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 9b377f742b3..779f7d24ef6 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -864,6 +864,20 @@ pub(crate) fn snippet_text_document_ops( rename_file, ))) } + FileSystemEdit::MoveDir { src, src_id, dst } => { + let old_uri = snap.anchored_path(&src); + let new_uri = snap.anchored_path(&dst); + let mut rename_file = + lsp_types::RenameFile { old_uri, new_uri, options: None, annotation_id: None }; + if snap.analysis.is_library_file(src_id).ok() == Some(true) + && snap.config.change_annotation_support() + { + rename_file.annotation_id = Some(outside_workspace_annotation_id()) + } + ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(lsp_types::ResourceOp::Rename( + rename_file, + ))) + } } Ok(ops) } -- 2.44.0