aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/add_missing_impl_members.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/add_missing_impl_members.rs')
-rw-r--r--crates/ra_assists/src/add_missing_impl_members.rs30
1 files changed, 21 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 4926a9b24..0888268e4 100644
--- a/crates/ra_assists/src/add_missing_impl_members.rs
+++ b/crates/ra_assists/src/add_missing_impl_members.rs
@@ -90,15 +90,24 @@ pub(crate) fn add_missing_impl_members(mut ctx: AssistCtx<impl HirDatabase>) ->
90 let last_whitespace_node = 90 let last_whitespace_node =
91 impl_item_list.syntax().children().filter_map(ast::Whitespace::cast).last()?.syntax(); 91 impl_item_list.syntax().children().filter_map(ast::Whitespace::cast).last()?.syntax();
92 92
93 ctx.add_action(AssistId("add_impl_missing_members"), "add impl missing members", |edit| { 93 ctx.add_action(AssistId("add_impl_missing_members"), "add missing impl members", |edit| {
94 let func_bodies = missing_fns.into_iter().map(build_func_body).join("\n"); 94 let indent = {
95 // FIXME: Find a way to get the indent already used in the file.
96 // Now, we copy the indent of first item or indent with 4 spaces relative to impl block
97 const DEFAULT_INDENT: &str = " ";
98 let first_item = impl_item_list.impl_items().next();
99 let first_item_indent = first_item.and_then(|i| leading_indent(i.syntax()));
100 let impl_block_indent = || leading_indent(impl_node.syntax()).unwrap_or_default();
101
102 first_item_indent
103 .map(ToOwned::to_owned)
104 .unwrap_or_else(|| impl_block_indent().to_owned() + DEFAULT_INDENT)
105 };
106
107 let mut func_bodies = missing_fns.into_iter().map(build_func_body);
108 let func_bodies = func_bodies.join("\n");
95 let func_bodies = String::from("\n") + &func_bodies; 109 let func_bodies = String::from("\n") + &func_bodies;
96 110 let func_bodies = reindent(&func_bodies, &indent) + "\n";
97 let first_impl_item = impl_item_list.impl_items().next();
98 // FIXME: We should respect the indent of the first item from the item list or the indent of leading block + some default indent (4?)
99 // Another approach is to not indent at all if there are no items here
100 let indent = first_impl_item.and_then(|i| leading_indent(i.syntax())).unwrap_or_default();
101 let func_bodies = reindent(&func_bodies, indent) + "\n";
102 111
103 let changed_range = last_whitespace_node.range(); 112 let changed_range = last_whitespace_node.range();
104 let replaced_text_range = TextUnit::of_str(&func_bodies); 113 let replaced_text_range = TextUnit::of_str(&func_bodies);
@@ -123,6 +132,7 @@ mod tests {
123trait Foo { 132trait Foo {
124 fn foo(&self); 133 fn foo(&self);
125 fn bar(&self); 134 fn bar(&self);
135 fn baz(&self);
126} 136}
127 137
128struct S; 138struct S;
@@ -135,13 +145,15 @@ impl Foo for S {
135trait Foo { 145trait Foo {
136 fn foo(&self); 146 fn foo(&self);
137 fn bar(&self); 147 fn bar(&self);
148 fn baz(&self);
138} 149}
139 150
140struct S; 151struct S;
141 152
142impl Foo for S { 153impl Foo for S {
143 fn bar(&self) {} 154 fn bar(&self) {}
144 fn foo(&self) { unimplemented!() }<|> 155 fn foo(&self) { unimplemented!() }
156 fn baz(&self) { unimplemented!() }<|>
145}", 157}",
146 ); 158 );
147 } 159 }