diff --git a/crates/ra_assists/src/handlers/add_custom_impl.rs b/crates/ra_assists/src/handlers/add_custom_impl.rs index 2baeb8607f8..fa70c849684 100644 --- a/crates/ra_assists/src/handlers/add_custom_impl.rs +++ b/crates/ra_assists/src/handlers/add_custom_impl.rs @@ -25,7 +25,7 @@ // struct S; // // impl Debug for S { -// +// $0 // } // ``` pub(crate) fn add_custom_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { @@ -52,7 +52,7 @@ pub(crate) fn add_custom_impl(acc: &mut Assists, ctx: &AssistContext) -> Option< format!("Add custom impl `{}` for `{}`", trait_token.text().as_str(), annotated_name); let target = attr.syntax().text_range(); - acc.add(AssistId("add_custom_impl"), label, target, |edit| { + acc.add(AssistId("add_custom_impl"), label, target, |builder| { let new_attr_input = input .syntax() .descendants_with_tokens() @@ -63,20 +63,11 @@ pub(crate) fn add_custom_impl(acc: &mut Assists, ctx: &AssistContext) -> Option< let has_more_derives = !new_attr_input.is_empty(); let new_attr_input = new_attr_input.iter().sep_by(", ").surround_with("(", ")").to_string(); - let mut buf = String::new(); - buf.push_str("\n\nimpl "); - buf.push_str(trait_token.text().as_str()); - buf.push_str(" for "); - buf.push_str(annotated_name.as_str()); - buf.push_str(" {\n"); - - let cursor_delta = if has_more_derives { - let delta = input.syntax().text_range().len() - TextSize::of(&new_attr_input); - edit.replace(input.syntax().text_range(), new_attr_input); - delta + if has_more_derives { + builder.replace(input.syntax().text_range(), new_attr_input); } else { let attr_range = attr.syntax().text_range(); - edit.delete(attr_range); + builder.delete(attr_range); let line_break_range = attr .syntax() @@ -84,14 +75,24 @@ pub(crate) fn add_custom_impl(acc: &mut Assists, ctx: &AssistContext) -> Option< .filter(|t| t.kind() == WHITESPACE) .map(|t| t.text_range()) .unwrap_or_else(|| TextRange::new(TextSize::from(0), TextSize::from(0))); - edit.delete(line_break_range); + builder.delete(line_break_range); + } - attr_range.len() + line_break_range.len() - }; - - edit.set_cursor(start_offset + TextSize::of(&buf) - cursor_delta); - buf.push_str("\n}"); - edit.insert(start_offset, buf); + match ctx.config.snippet_cap { + Some(cap) => { + builder.insert_snippet( + cap, + start_offset, + format!("\n\nimpl {} for {} {{\n $0\n}}", trait_token, annotated_name), + ); + } + None => { + builder.insert( + start_offset, + format!("\n\nimpl {} for {} {{\n\n}}", trait_token, annotated_name), + ); + } + } }) } @@ -117,7 +118,7 @@ struct Foo { } impl Debug for Foo { -<|> + $0 } ", ) @@ -139,7 +140,7 @@ pub struct Foo { } impl Debug for Foo { -<|> + $0 } ", ) @@ -158,7 +159,7 @@ struct Foo {} struct Foo {} impl Debug for Foo { -<|> + $0 } ", ) diff --git a/crates/ra_assists/src/handlers/add_derive.rs b/crates/ra_assists/src/handlers/add_derive.rs index fb08c19e936..b123b84988c 100644 --- a/crates/ra_assists/src/handlers/add_derive.rs +++ b/crates/ra_assists/src/handlers/add_derive.rs @@ -18,31 +18,37 @@ // ``` // -> // ``` -// #[derive()] +// #[derive($0)] // struct Point { // x: u32, // y: u32, // } // ``` pub(crate) fn add_derive(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { + let cap = ctx.config.snippet_cap?; let nominal = ctx.find_node_at_offset::()?; let node_start = derive_insertion_offset(&nominal)?; let target = nominal.syntax().text_range(); - acc.add(AssistId("add_derive"), "Add `#[derive]`", target, |edit| { + acc.add(AssistId("add_derive"), "Add `#[derive]`", target, |builder| { let derive_attr = nominal .attrs() .filter_map(|x| x.as_simple_call()) .filter(|(name, _arg)| name == "derive") .map(|(_name, arg)| arg) .next(); - let offset = match derive_attr { + match derive_attr { None => { - edit.insert(node_start, "#[derive()]\n"); - node_start + TextSize::of("#[derive(") + builder.insert_snippet(cap, node_start, "#[derive($0)]\n"); + } + Some(tt) => { + // Just move the cursor. + builder.insert_snippet( + cap, + tt.syntax().text_range().end() - TextSize::of(')'), + "$0", + ) } - Some(tt) => tt.syntax().text_range().end() - TextSize::of(')'), }; - edit.set_cursor(offset) }) } @@ -66,12 +72,12 @@ fn add_derive_new() { check_assist( add_derive, "struct Foo { a: i32, <|>}", - "#[derive(<|>)]\nstruct Foo { a: i32, }", + "#[derive($0)]\nstruct Foo { a: i32, }", ); check_assist( add_derive, "struct Foo { <|> a: i32, }", - "#[derive(<|>)]\nstruct Foo { a: i32, }", + "#[derive($0)]\nstruct Foo { a: i32, }", ); } @@ -80,7 +86,7 @@ fn add_derive_existing() { check_assist( add_derive, "#[derive(Clone)]\nstruct Foo { a: i32<|>, }", - "#[derive(Clone<|>)]\nstruct Foo { a: i32, }", + "#[derive(Clone$0)]\nstruct Foo { a: i32, }", ); } @@ -96,7 +102,7 @@ struct Foo { a: i32<|>, } " /// `Foo` is a pretty important struct. /// It does stuff. -#[derive(<|>)] +#[derive($0)] struct Foo { a: i32, } ", ); diff --git a/crates/ra_assists/src/handlers/add_impl.rs b/crates/ra_assists/src/handlers/add_impl.rs index df114a0d84d..eceba7d0ae6 100644 --- a/crates/ra_assists/src/handlers/add_impl.rs +++ b/crates/ra_assists/src/handlers/add_impl.rs @@ -1,7 +1,4 @@ -use ra_syntax::{ - ast::{self, AstNode, NameOwner, TypeParamsOwner}, - TextSize, -}; +use ra_syntax::ast::{self, AstNode, NameOwner, TypeParamsOwner}; use stdx::{format_to, SepBy}; use crate::{AssistContext, AssistId, Assists}; @@ -12,17 +9,17 @@ // // ``` // struct Ctx { -// data: T,<|> +// data: T,<|> // } // ``` // -> // ``` // struct Ctx { -// data: T, +// data: T, // } // // impl Ctx { -// +// $0 // } // ``` pub(crate) fn add_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { @@ -50,30 +47,37 @@ pub(crate) fn add_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { let generic_params = lifetime_params.chain(type_params).sep_by(", "); format_to!(buf, "<{}>", generic_params) } - buf.push_str(" {\n"); - edit.set_cursor(start_offset + TextSize::of(&buf)); - buf.push_str("\n}"); - edit.insert(start_offset, buf); + match ctx.config.snippet_cap { + Some(cap) => { + buf.push_str(" {\n $0\n}"); + edit.insert_snippet(cap, start_offset, buf); + } + None => { + buf.push_str(" {\n}"); + edit.insert(start_offset, buf); + } + } }) } #[cfg(test)] mod tests { - use super::*; use crate::tests::{check_assist, check_assist_target}; + use super::*; + #[test] fn test_add_impl() { - check_assist(add_impl, "struct Foo {<|>}\n", "struct Foo {}\n\nimpl Foo {\n<|>\n}\n"); + check_assist(add_impl, "struct Foo {<|>}\n", "struct Foo {}\n\nimpl Foo {\n $0\n}\n"); check_assist( add_impl, "struct Foo {<|>}", - "struct Foo {}\n\nimpl Foo {\n<|>\n}", + "struct Foo {}\n\nimpl Foo {\n $0\n}", ); check_assist( add_impl, "struct Foo<'a, T: Foo<'a>> {<|>}", - "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n<|>\n}", + "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}", ); } diff --git a/crates/ra_assists/src/tests/generated.rs b/crates/ra_assists/src/tests/generated.rs index 972dbd251d6..9487c9239f0 100644 --- a/crates/ra_assists/src/tests/generated.rs +++ b/crates/ra_assists/src/tests/generated.rs @@ -15,7 +15,7 @@ fn doctest_add_custom_impl() { struct S; impl Debug for S { - + $0 } "#####, ) @@ -32,7 +32,7 @@ struct Point { } "#####, r#####" -#[derive()] +#[derive($0)] struct Point { x: u32, y: u32, @@ -108,16 +108,16 @@ fn doctest_add_impl() { "add_impl", r#####" struct Ctx { - data: T,<|> + data: T,<|> } "#####, r#####" struct Ctx { - data: T, + data: T, } impl Ctx { - + $0 } "#####, ) diff --git a/docs/user/assists.md b/docs/user/assists.md index 692fd4f52ba..41c5df5287c 100644 --- a/docs/user/assists.md +++ b/docs/user/assists.md @@ -17,7 +17,7 @@ struct S; struct S; impl Debug for S { - + $0 } ``` @@ -33,7 +33,7 @@ struct Point { } // AFTER -#[derive()] +#[derive($0)] struct Point { x: u32, y: u32, @@ -105,16 +105,16 @@ Adds a new inherent impl for a type. ```rust // BEFORE struct Ctx { - data: T,┃ + data: T,┃ } // AFTER struct Ctx { - data: T, + data: T, } impl Ctx { - + $0 } ```