diff options
-rw-r--r-- | crates/ra_assists/src/add_missing_impl_members.rs | 30 |
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 { | |||
123 | trait Foo { | 132 | trait 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 | ||
128 | struct S; | 138 | struct S; |
@@ -135,13 +145,15 @@ impl Foo for S { | |||
135 | trait Foo { | 145 | trait 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 | ||
140 | struct S; | 151 | struct S; |
141 | 152 | ||
142 | impl Foo for S { | 153 | impl 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 | } |