aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers/add_new.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers/add_new.rs')
-rw-r--r--crates/ra_assists/src/handlers/add_new.rs92
1 files changed, 49 insertions, 43 deletions
diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs
index e41b2aa06..4cd3ca264 100644
--- a/crates/ra_assists/src/handlers/add_new.rs
+++ b/crates/ra_assists/src/handlers/add_new.rs
@@ -7,7 +7,7 @@ use ra_syntax::{
7}; 7};
8use stdx::{format_to, SepBy}; 8use stdx::{format_to, SepBy};
9 9
10use crate::{AssistContext, AssistId, Assists}; 10use crate::{AssistContext, AssistId, AssistKind, Assists};
11 11
12// Assist: add_new 12// Assist: add_new
13// 13//
@@ -42,50 +42,56 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
42 let impl_def = find_struct_impl(&ctx, &strukt)?; 42 let impl_def = find_struct_impl(&ctx, &strukt)?;
43 43
44 let target = strukt.syntax().text_range(); 44 let target = strukt.syntax().text_range();
45 acc.add(AssistId("add_new"), "Add default constructor", target, |builder| { 45 acc.add(
46 let mut buf = String::with_capacity(512); 46 AssistId("add_new"),
47 47 AssistKind::Refactor,
48 if impl_def.is_some() { 48 "Add default constructor",
49 buf.push('\n'); 49 target,
50 } 50 |builder| {
51 51 let mut buf = String::with_capacity(512);
52 let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v)); 52
53 53 if impl_def.is_some() {
54 let params = field_list
55 .fields()
56 .filter_map(|f| {
57 Some(format!("{}: {}", f.name()?.syntax(), f.ascribed_type()?.syntax()))
58 })
59 .sep_by(", ");
60 let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", ");
61
62 format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields);
63
64 let start_offset = impl_def
65 .and_then(|impl_def| {
66 buf.push('\n'); 54 buf.push('\n');
67 let start = impl_def
68 .syntax()
69 .descendants_with_tokens()
70 .find(|t| t.kind() == T!['{'])?
71 .text_range()
72 .end();
73
74 Some(start)
75 })
76 .unwrap_or_else(|| {
77 buf = generate_impl_text(&strukt, &buf);
78 strukt.syntax().text_range().end()
79 });
80
81 match ctx.config.snippet_cap {
82 None => builder.insert(start_offset, buf),
83 Some(cap) => {
84 buf = buf.replace("fn new", "fn $0new");
85 builder.insert_snippet(cap, start_offset, buf);
86 } 55 }
87 } 56
88 }) 57 let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v));
58
59 let params = field_list
60 .fields()
61 .filter_map(|f| {
62 Some(format!("{}: {}", f.name()?.syntax(), f.ascribed_type()?.syntax()))
63 })
64 .sep_by(", ");
65 let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", ");
66
67 format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields);
68
69 let start_offset = impl_def
70 .and_then(|impl_def| {
71 buf.push('\n');
72 let start = impl_def
73 .syntax()
74 .descendants_with_tokens()
75 .find(|t| t.kind() == T!['{'])?
76 .text_range()
77 .end();
78
79 Some(start)
80 })
81 .unwrap_or_else(|| {
82 buf = generate_impl_text(&strukt, &buf);
83 strukt.syntax().text_range().end()
84 });
85
86 match ctx.config.snippet_cap {
87 None => builder.insert(start_offset, buf),
88 Some(cap) => {
89 buf = buf.replace("fn new", "fn $0new");
90 builder.insert_snippet(cap, start_offset, buf);
91 }
92 }
93 },
94 )
89} 95}
90 96
91// Generates the surrounding `impl Type { <code> }` including type and lifetime 97// Generates the surrounding `impl Type { <code> }` including type and lifetime