about summary refs log tree commit diff
path: root/src/tools/rust-analyzer
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer')
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs89
1 files changed, 76 insertions, 13 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs
index 821783c2831..7b7dac9a3d6 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs
@@ -1,10 +1,22 @@
 use syntax::{
-    ast::{self, make, AstNode, HasName},
+    ast::{self, edit_in_place::Indent, make, AstNode, HasName},
     ted,
 };
 
 use crate::{utils, AssistContext, AssistId, AssistKind, Assists};
 
+fn insert_impl(impl_: ast::Impl, nominal: &ast::Adt) {
+    let indent = nominal.indent_level();
+    ted::insert_all_raw(
+        ted::Position::after(nominal.syntax()),
+        vec![
+            // Add a blank line after the ADT, and indentation for the impl to match the ADT
+            make::tokens::whitespace(&format!("\n\n{indent}")).into(),
+            impl_.syntax().clone().into(),
+        ],
+    );
+}
+
 // Assist: generate_impl
 //
 // Adds a new inherent impl for a type.
@@ -46,12 +58,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
                 }
             }
 
-            // Add the impl after the adt
-            let nominal = edit.make_mut(nominal);
-            ted::insert_all_raw(
-                ted::Position::after(nominal.syntax()),
-                vec![make::tokens::blank_line().into(), impl_.syntax().clone().into()],
-            );
+            insert_impl(impl_, &edit.make_mut(nominal));
         },
     )
 }
@@ -97,12 +104,7 @@ pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) ->
                 }
             }
 
-            // Add the impl after the adt
-            let nominal = edit.make_mut(nominal);
-            ted::insert_all_raw(
-                ted::Position::after(nominal.syntax()),
-                vec![make::tokens::blank_line().into(), impl_.syntax().clone().into()],
-            );
+            insert_impl(impl_, &edit.make_mut(nominal));
         },
     )
 }
@@ -418,4 +420,65 @@ mod tests {
             "/// Has a lifetime parameter\nstruct Foo<'a, T: Foo<'a>> {}",
         );
     }
+
+    #[test]
+    fn add_impl_with_indent() {
+        check_assist(
+            generate_impl,
+            r#"
+                mod foo {
+                    struct Bar$0 {}
+                }
+            "#,
+            r#"
+                mod foo {
+                    struct Bar {}
+
+                    impl Bar {$0}
+                }
+            "#,
+        );
+    }
+
+    #[test]
+    fn add_impl_with_multiple_indent() {
+        check_assist(
+            generate_impl,
+            r#"
+                mod foo {
+                    fn bar() {
+                        struct Baz$0 {}
+                    }
+                }
+            "#,
+            r#"
+                mod foo {
+                    fn bar() {
+                        struct Baz {}
+
+                        impl Baz {$0}
+                    }
+                }
+            "#,
+        );
+    }
+
+    #[test]
+    fn add_trait_impl_with_indent() {
+        check_assist(
+            generate_trait_impl,
+            r#"
+                mod foo {
+                    struct Bar$0 {}
+                }
+            "#,
+            r#"
+                mod foo {
+                    struct Bar {}
+
+                    impl ${0:_} for Bar {}
+                }
+            "#,
+        );
+    }
 }