+use std::iter;
+
use ast::edit::IndentLevel;
use ide_db::base_db::AnchoredPathBuf;
+use itertools::Itertools;
use stdx::format_to;
use syntax::{
ast::{self, edit::AstNodeEdit, NameOwner},
let module_name = module_ast.name()?;
- let module_def = ctx.sema.to_def(&module_ast)?;
+ // get to the outermost module syntax so we can grab the module of file we are in
+ let outermost_mod_decl =
+ iter::successors(Some(module_ast.clone()), |module| module.parent()).last()?;
+ let module_def = ctx.sema.to_def(&outermost_mod_decl)?;
let parent_module = module_def.parent(ctx.db())?;
acc.add(
target,
|builder| {
let path = {
- let dir = match parent_module.name(ctx.db()) {
- Some(name) if !parent_module.is_mod_rs(ctx.db()) => format!("{}/", name),
- _ => String::new(),
- };
- format!("./{}{}.rs", dir, module_name)
+ let mut buf = String::from("./");
+ match parent_module.name(ctx.db()) {
+ Some(name) if !parent_module.is_mod_rs(ctx.db()) => {
+ format_to!(buf, "{}/", name)
+ }
+ _ => (),
+ }
+ let segments = iter::successors(Some(module_ast.clone()), |module| module.parent())
+ .filter_map(|it| it.name())
+ .collect::<Vec<_>>();
+ format_to!(buf, "{}", segments.into_iter().rev().format("/"));
+ format_to!(buf, ".rs");
+ buf
};
let contents = {
let items = module_items.dedent(IndentLevel(1)).to_string();
items
};
- let mut buf = String::new();
- format_to!(buf, "mod {};", module_name);
+ let buf = format!("mod {};", module_name);
- let replacement_start = if let Some(mod_token) = module_ast.mod_token() {
- mod_token.text_range().start()
- } else {
- module_ast.syntax().text_range().start()
- };
+ let replacement_start = match module_ast.mod_token() {
+ Some(mod_token) => mod_token.text_range(),
+ None => module_ast.syntax().text_range(),
+ }
+ .start();
builder.replace(
TextRange::new(replacement_start, module_ast.syntax().text_range().end()),
mod tests;
//- /tests.rs
#[test] fn t() {}
+"#,
+ );
+ }
+
+ #[test]
+ fn extract_nested() {
+ check_assist(
+ move_module_to_file,
+ r#"
+//- /lib.rs
+mod foo;
+//- /foo.rs
+mod bar {
+ mod baz {
+ mod qux$0 {}
+ }
+}
+"#,
+ r#"
+//- /foo.rs
+mod bar {
+ mod baz {
+ mod qux;
+ }
+}
+//- /foo/bar/baz/qux.rs
"#,
);
}