aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/add_missing_impl_members.rs50
1 files changed, 41 insertions, 9 deletions
diff --git a/crates/ra_assists/src/add_missing_impl_members.rs b/crates/ra_assists/src/add_missing_impl_members.rs
index e682ca055..8e8520c59 100644
--- a/crates/ra_assists/src/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/add_missing_impl_members.rs
@@ -74,22 +74,25 @@ pub(crate) fn add_missing_impl_members(mut ctx: AssistCtx<impl HirDatabase>) ->
74 } 74 }
75 75
76 ctx.add_action(AssistId("add_impl_missing_members"), "add missing impl members", |edit| { 76 ctx.add_action(AssistId("add_impl_missing_members"), "add missing impl members", |edit| {
77 let indent = { 77 let (parent_indent, indent) = {
78 // FIXME: Find a way to get the indent already used in the file. 78 // FIXME: Find a way to get the indent already used in the file.
79 // Now, we copy the indent of first item or indent with 4 spaces relative to impl block 79 // Now, we copy the indent of first item or indent with 4 spaces relative to impl block
80 const DEFAULT_INDENT: &str = " "; 80 const DEFAULT_INDENT: &str = " ";
81 let first_item = impl_item_list.impl_items().next(); 81 let first_item = impl_item_list.impl_items().next();
82 let first_item_indent = first_item.and_then(|i| leading_indent(i.syntax())); 82 let first_item_indent =
83 let impl_block_indent = || leading_indent(impl_node.syntax()).unwrap_or_default(); 83 first_item.and_then(|i| leading_indent(i.syntax())).map(ToOwned::to_owned);
84 84 let impl_block_indent = leading_indent(impl_node.syntax()).unwrap_or_default();
85 first_item_indent 85
86 .map(ToOwned::to_owned) 86 (
87 .unwrap_or_else(|| impl_block_indent().to_owned() + DEFAULT_INDENT) 87 impl_block_indent.to_owned(),
88 first_item_indent.unwrap_or_else(|| impl_block_indent.to_owned() + DEFAULT_INDENT),
89 )
88 }; 90 };
89 91
90 let func_bodies = missing_fns.into_iter().map(build_func_body).join("\n"); 92 let func_bodies = missing_fns.into_iter().map(build_func_body).join("\n");
91 let func_bodies = String::from("\n") + &func_bodies; 93 let func_bodies = String::from("\n") + &func_bodies;
92 let func_bodies = reindent(&func_bodies, &indent) + "\n"; 94 let trailing_whitespace = format!("\n{}", parent_indent);
95 let func_bodies = reindent(&func_bodies, &indent) + &trailing_whitespace;
93 96
94 let changed_range = { 97 let changed_range = {
95 let last_whitespace = impl_item_list.syntax().children(); 98 let last_whitespace = impl_item_list.syntax().children();
@@ -104,7 +107,9 @@ pub(crate) fn add_missing_impl_members(mut ctx: AssistCtx<impl HirDatabase>) ->
104 let replaced_text_range = TextUnit::of_str(&func_bodies); 107 let replaced_text_range = TextUnit::of_str(&func_bodies);
105 108
106 edit.replace(changed_range, func_bodies); 109 edit.replace(changed_range, func_bodies);
107 edit.set_cursor(changed_range.start() + replaced_text_range - TextUnit::of_str("\n")); 110 edit.set_cursor(
111 changed_range.start() + replaced_text_range - TextUnit::of_str(&trailing_whitespace),
112 );
108 }); 113 });
109 114
110 ctx.build() 115 ctx.build()
@@ -244,4 +249,31 @@ impl Foo for S {
244}", 249}",
245 ) 250 )
246 } 251 }
252
253 #[test]
254 fn test_indented_impl_block() {
255 check_assist(
256 add_missing_impl_members,
257 "
258trait Foo {
259 fn valid(some: u32) -> bool { false }
260}
261struct S;
262
263mod my_mod {
264 impl crate::Foo for S { <|> }
265}",
266 "
267trait Foo {
268 fn valid(some: u32) -> bool { false }
269}
270struct S;
271
272mod my_mod {
273 impl crate::Foo for S {
274 fn valid(some: u32) -> bool { false }<|>
275 }
276}",
277 )
278 }
247} 279}