Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide/src/rename.rs74
-rw-r--r--crates/ide_assists/src/tests.rs4
-rw-r--r--crates/ide_db/src/rename.rs26
-rw-r--r--crates/ide_db/src/source_change.rs1
-rw-r--r--crates/rust-analyzer/src/to_proto.rs14
5 files changed, 106 insertions, 13 deletions
diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs
index 1bb3cdb907..f5bff5fd91 100644
--- a/crates/ide/src/rename.rs
+++ b/crates/ide/src/rename.rs
@@ -968,15 +968,21 @@ mod fo$0o;
},
},
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",
},
},
],
@@ -1114,6 +1120,68 @@ pub mod foo$0;
}
#[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(
"baz",
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
index 09260c12ed..b3a0bd2773 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 13234a817b..589975406a 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 aa910eb325..8132c73ef2 100644
--- a/crates/ide_db/src/source_change.rs
+++ b/crates/ide_db/src/source_change.rs
@@ -85,6 +85,7 @@ impl From<FxHashMap<FileId, TextEdit>> for 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<FileSystemEdit> for SourceChange {
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 0588f00678..3d83f090e2 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -866,6 +866,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)
}