diff options
Diffstat (limited to 'crates/ide_assists')
-rw-r--r-- | crates/ide_assists/src/handlers/move_module_to_file.rs | 65 |
1 files changed, 52 insertions, 13 deletions
diff --git a/crates/ide_assists/src/handlers/move_module_to_file.rs b/crates/ide_assists/src/handlers/move_module_to_file.rs index 93f702c55..cfc54be8d 100644 --- a/crates/ide_assists/src/handlers/move_module_to_file.rs +++ b/crates/ide_assists/src/handlers/move_module_to_file.rs | |||
@@ -1,5 +1,8 @@ | |||
1 | use std::iter; | ||
2 | |||
1 | use ast::edit::IndentLevel; | 3 | use ast::edit::IndentLevel; |
2 | use ide_db::base_db::AnchoredPathBuf; | 4 | use ide_db::base_db::AnchoredPathBuf; |
5 | use itertools::Itertools; | ||
3 | use stdx::format_to; | 6 | use stdx::format_to; |
4 | use syntax::{ | 7 | use syntax::{ |
5 | ast::{self, edit::AstNodeEdit, NameOwner}, | 8 | ast::{self, edit::AstNodeEdit, NameOwner}, |
@@ -34,7 +37,10 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Opt | |||
34 | 37 | ||
35 | let module_name = module_ast.name()?; | 38 | let module_name = module_ast.name()?; |
36 | 39 | ||
37 | let module_def = ctx.sema.to_def(&module_ast)?; | 40 | // get to the outermost module syntax so we can grab the module of file we are in |
41 | let outermost_mod_decl = | ||
42 | iter::successors(Some(module_ast.clone()), |module| module.parent()).last()?; | ||
43 | let module_def = ctx.sema.to_def(&outermost_mod_decl)?; | ||
38 | let parent_module = module_def.parent(ctx.db())?; | 44 | let parent_module = module_def.parent(ctx.db())?; |
39 | 45 | ||
40 | acc.add( | 46 | acc.add( |
@@ -43,11 +49,19 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Opt | |||
43 | target, | 49 | target, |
44 | |builder| { | 50 | |builder| { |
45 | let path = { | 51 | let path = { |
46 | let dir = match parent_module.name(ctx.db()) { | 52 | let mut buf = String::from("./"); |
47 | Some(name) if !parent_module.is_mod_rs(ctx.db()) => format!("{}/", name), | 53 | match parent_module.name(ctx.db()) { |
48 | _ => String::new(), | 54 | Some(name) if !parent_module.is_mod_rs(ctx.db()) => { |
49 | }; | 55 | format_to!(buf, "{}/", name) |
50 | format!("./{}{}.rs", dir, module_name) | 56 | } |
57 | _ => (), | ||
58 | } | ||
59 | let segments = iter::successors(Some(module_ast.clone()), |module| module.parent()) | ||
60 | .filter_map(|it| it.name()) | ||
61 | .collect::<Vec<_>>(); | ||
62 | format_to!(buf, "{}", segments.into_iter().rev().format("/")); | ||
63 | format_to!(buf, ".rs"); | ||
64 | buf | ||
51 | }; | 65 | }; |
52 | let contents = { | 66 | let contents = { |
53 | let items = module_items.dedent(IndentLevel(1)).to_string(); | 67 | let items = module_items.dedent(IndentLevel(1)).to_string(); |
@@ -59,14 +73,13 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Opt | |||
59 | items | 73 | items |
60 | }; | 74 | }; |
61 | 75 | ||
62 | let mut buf = String::new(); | 76 | let buf = format!("mod {};", module_name); |
63 | format_to!(buf, "mod {};", module_name); | ||
64 | 77 | ||
65 | let replacement_start = if let Some(mod_token) = module_ast.mod_token() { | 78 | let replacement_start = match module_ast.mod_token() { |
66 | mod_token.text_range().start() | 79 | Some(mod_token) => mod_token.text_range(), |
67 | } else { | 80 | None => module_ast.syntax().text_range(), |
68 | module_ast.syntax().text_range().start() | 81 | } |
69 | }; | 82 | .start(); |
70 | 83 | ||
71 | builder.replace( | 84 | builder.replace( |
72 | TextRange::new(replacement_start, module_ast.syntax().text_range().end()), | 85 | TextRange::new(replacement_start, module_ast.syntax().text_range().end()), |
@@ -212,4 +225,30 @@ mod tests; | |||
212 | "#, | 225 | "#, |
213 | ); | 226 | ); |
214 | } | 227 | } |
228 | |||
229 | #[test] | ||
230 | fn extract_nested() { | ||
231 | check_assist( | ||
232 | move_module_to_file, | ||
233 | r#" | ||
234 | //- /lib.rs | ||
235 | mod foo; | ||
236 | //- /foo.rs | ||
237 | mod bar { | ||
238 | mod baz { | ||
239 | mod qux$0 {} | ||
240 | } | ||
241 | } | ||
242 | "#, | ||
243 | r#" | ||
244 | //- /foo.rs | ||
245 | mod bar { | ||
246 | mod baz { | ||
247 | mod qux; | ||
248 | } | ||
249 | } | ||
250 | //- /foo/bar/baz/qux.rs | ||
251 | "#, | ||
252 | ); | ||
253 | } | ||
215 | } | 254 | } |