diff options
author | Galilée 'Bill' Enguehard <[email protected]> | 2020-05-21 22:27:38 +0100 |
---|---|---|
committer | Galilée 'Bill' Enguehard <[email protected]> | 2020-05-21 22:27:38 +0100 |
commit | 7fece3bdd2450c0807f7dd742239cae95f0cc65e (patch) | |
tree | 866c4db826c959e79c63a6727bdb9f2c61e6fc4f /crates/ra_assists/src/handlers/add_custom_impl.rs | |
parent | db926218b2082077750291f8426ddd28b284cd08 (diff) | |
parent | 59732df8d40dfadc6dcf5951265416576399712a (diff) |
Merge branch 'master' of github.com:rust-analyzer/rust-analyzer into modname_spacing
Diffstat (limited to 'crates/ra_assists/src/handlers/add_custom_impl.rs')
-rw-r--r-- | crates/ra_assists/src/handlers/add_custom_impl.rs | 65 |
1 files changed, 34 insertions, 31 deletions
diff --git a/crates/ra_assists/src/handlers/add_custom_impl.rs b/crates/ra_assists/src/handlers/add_custom_impl.rs index 4ea26a550..fa70c8496 100644 --- a/crates/ra_assists/src/handlers/add_custom_impl.rs +++ b/crates/ra_assists/src/handlers/add_custom_impl.rs | |||
@@ -6,7 +6,10 @@ use ra_syntax::{ | |||
6 | }; | 6 | }; |
7 | use stdx::SepBy; | 7 | use stdx::SepBy; |
8 | 8 | ||
9 | use crate::{Assist, AssistCtx, AssistId}; | 9 | use crate::{ |
10 | assist_context::{AssistContext, Assists}, | ||
11 | AssistId, | ||
12 | }; | ||
10 | 13 | ||
11 | // Assist: add_custom_impl | 14 | // Assist: add_custom_impl |
12 | // | 15 | // |
@@ -22,10 +25,10 @@ use crate::{Assist, AssistCtx, AssistId}; | |||
22 | // struct S; | 25 | // struct S; |
23 | // | 26 | // |
24 | // impl Debug for S { | 27 | // impl Debug for S { |
25 | // | 28 | // $0 |
26 | // } | 29 | // } |
27 | // ``` | 30 | // ``` |
28 | pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option<Assist> { | 31 | pub(crate) fn add_custom_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
29 | let input = ctx.find_node_at_offset::<ast::AttrInput>()?; | 32 | let input = ctx.find_node_at_offset::<ast::AttrInput>()?; |
30 | let attr = input.syntax().parent().and_then(ast::Attr::cast)?; | 33 | let attr = input.syntax().parent().and_then(ast::Attr::cast)?; |
31 | 34 | ||
@@ -46,11 +49,10 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option<Assist> { | |||
46 | let start_offset = annotated.syntax().parent()?.text_range().end(); | 49 | let start_offset = annotated.syntax().parent()?.text_range().end(); |
47 | 50 | ||
48 | let label = | 51 | let label = |
49 | format!("Add custom impl '{}' for '{}'", trait_token.text().as_str(), annotated_name); | 52 | format!("Add custom impl `{}` for `{}`", trait_token.text().as_str(), annotated_name); |
50 | |||
51 | ctx.add_assist(AssistId("add_custom_impl"), label, |edit| { | ||
52 | edit.target(attr.syntax().text_range()); | ||
53 | 53 | ||
54 | let target = attr.syntax().text_range(); | ||
55 | acc.add(AssistId("add_custom_impl"), label, target, |builder| { | ||
54 | let new_attr_input = input | 56 | let new_attr_input = input |
55 | .syntax() | 57 | .syntax() |
56 | .descendants_with_tokens() | 58 | .descendants_with_tokens() |
@@ -61,20 +63,11 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option<Assist> { | |||
61 | let has_more_derives = !new_attr_input.is_empty(); | 63 | let has_more_derives = !new_attr_input.is_empty(); |
62 | let new_attr_input = new_attr_input.iter().sep_by(", ").surround_with("(", ")").to_string(); | 64 | let new_attr_input = new_attr_input.iter().sep_by(", ").surround_with("(", ")").to_string(); |
63 | 65 | ||
64 | let mut buf = String::new(); | 66 | if has_more_derives { |
65 | buf.push_str("\n\nimpl "); | 67 | builder.replace(input.syntax().text_range(), new_attr_input); |
66 | buf.push_str(trait_token.text().as_str()); | ||
67 | buf.push_str(" for "); | ||
68 | buf.push_str(annotated_name.as_str()); | ||
69 | buf.push_str(" {\n"); | ||
70 | |||
71 | let cursor_delta = if has_more_derives { | ||
72 | let delta = input.syntax().text_range().len() - TextSize::of(&new_attr_input); | ||
73 | edit.replace(input.syntax().text_range(), new_attr_input); | ||
74 | delta | ||
75 | } else { | 68 | } else { |
76 | let attr_range = attr.syntax().text_range(); | 69 | let attr_range = attr.syntax().text_range(); |
77 | edit.delete(attr_range); | 70 | builder.delete(attr_range); |
78 | 71 | ||
79 | let line_break_range = attr | 72 | let line_break_range = attr |
80 | .syntax() | 73 | .syntax() |
@@ -82,20 +75,30 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option<Assist> { | |||
82 | .filter(|t| t.kind() == WHITESPACE) | 75 | .filter(|t| t.kind() == WHITESPACE) |
83 | .map(|t| t.text_range()) | 76 | .map(|t| t.text_range()) |
84 | .unwrap_or_else(|| TextRange::new(TextSize::from(0), TextSize::from(0))); | 77 | .unwrap_or_else(|| TextRange::new(TextSize::from(0), TextSize::from(0))); |
85 | edit.delete(line_break_range); | 78 | builder.delete(line_break_range); |
86 | 79 | } | |
87 | attr_range.len() + line_break_range.len() | 80 | |
88 | }; | 81 | match ctx.config.snippet_cap { |
89 | 82 | Some(cap) => { | |
90 | edit.set_cursor(start_offset + TextSize::of(&buf) - cursor_delta); | 83 | builder.insert_snippet( |
91 | buf.push_str("\n}"); | 84 | cap, |
92 | edit.insert(start_offset, buf); | 85 | start_offset, |
86 | format!("\n\nimpl {} for {} {{\n $0\n}}", trait_token, annotated_name), | ||
87 | ); | ||
88 | } | ||
89 | None => { | ||
90 | builder.insert( | ||
91 | start_offset, | ||
92 | format!("\n\nimpl {} for {} {{\n\n}}", trait_token, annotated_name), | ||
93 | ); | ||
94 | } | ||
95 | } | ||
93 | }) | 96 | }) |
94 | } | 97 | } |
95 | 98 | ||
96 | #[cfg(test)] | 99 | #[cfg(test)] |
97 | mod tests { | 100 | mod tests { |
98 | use crate::helpers::{check_assist, check_assist_not_applicable}; | 101 | use crate::tests::{check_assist, check_assist_not_applicable}; |
99 | 102 | ||
100 | use super::*; | 103 | use super::*; |
101 | 104 | ||
@@ -115,7 +118,7 @@ struct Foo { | |||
115 | } | 118 | } |
116 | 119 | ||
117 | impl Debug for Foo { | 120 | impl Debug for Foo { |
118 | <|> | 121 | $0 |
119 | } | 122 | } |
120 | ", | 123 | ", |
121 | ) | 124 | ) |
@@ -137,7 +140,7 @@ pub struct Foo { | |||
137 | } | 140 | } |
138 | 141 | ||
139 | impl Debug for Foo { | 142 | impl Debug for Foo { |
140 | <|> | 143 | $0 |
141 | } | 144 | } |
142 | ", | 145 | ", |
143 | ) | 146 | ) |
@@ -156,7 +159,7 @@ struct Foo {} | |||
156 | struct Foo {} | 159 | struct Foo {} |
157 | 160 | ||
158 | impl Debug for Foo { | 161 | impl Debug for Foo { |
159 | <|> | 162 | $0 |
160 | } | 163 | } |
161 | ", | 164 | ", |
162 | ) | 165 | ) |