Skip to content

Commit a04caba

Browse files
committed
Use snippets in add_missing_members
1 parent e6fc0bd commit a04caba

File tree

6 files changed

+84
-45
lines changed

6 files changed

+84
-45
lines changed

crates/ra_assists/src/assist_context.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,20 +194,30 @@ impl AssistBuilder {
194194
pub(crate) fn insert(&mut self, offset: TextSize, text: impl Into<String>) {
195195
self.edit.insert(offset, text.into())
196196
}
197-
/// Append specified `text` at the given `offset`
197+
/// Append specified `snippet` at the given `offset`
198198
pub(crate) fn insert_snippet(
199199
&mut self,
200200
_cap: SnippetCap,
201201
offset: TextSize,
202-
text: impl Into<String>,
202+
snippet: impl Into<String>,
203203
) {
204204
self.is_snippet = true;
205-
self.edit.insert(offset, text.into())
205+
self.insert(offset, snippet);
206206
}
207207
/// Replaces specified `range` of text with a given string.
208208
pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
209209
self.edit.replace(range, replace_with.into())
210210
}
211+
/// Replaces specified `range` of text with a given `snippet`.
212+
pub(crate) fn replace_snippet(
213+
&mut self,
214+
_cap: SnippetCap,
215+
range: TextRange,
216+
snippet: impl Into<String>,
217+
) {
218+
self.is_snippet = true;
219+
self.replace(range, snippet);
220+
}
211221
pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
212222
algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
213223
}

crates/ra_assists/src/handlers/add_function.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ use ra_syntax::{
1010
};
1111
use rustc_hash::{FxHashMap, FxHashSet};
1212

13-
use crate::{assist_config::SnippetCap, utils::render_snippet, AssistContext, AssistId, Assists};
13+
use crate::{
14+
assist_config::SnippetCap,
15+
utils::{render_snippet, Cursor},
16+
AssistContext, AssistId, Assists,
17+
};
1418

1519
// Assist: add_function
1620
//
@@ -81,7 +85,11 @@ struct FunctionTemplate {
8185
impl FunctionTemplate {
8286
fn to_string(&self, cap: Option<SnippetCap>) -> String {
8387
let f = match cap {
84-
Some(cap) => render_snippet(cap, self.fn_def.syntax(), self.placeholder_expr.syntax()),
88+
Some(cap) => render_snippet(
89+
cap,
90+
self.fn_def.syntax(),
91+
Cursor::Replace(self.placeholder_expr.syntax()),
92+
),
8593
None => self.fn_def.to_string(),
8694
};
8795
format!("{}{}{}", self.leading_ws, f, self.trailing_ws)

crates/ra_assists/src/handlers/add_missing_impl_members.rs

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ra_syntax::{
1111
use crate::{
1212
assist_context::{AssistContext, Assists},
1313
ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams},
14-
utils::{get_missing_assoc_items, resolve_target_trait},
14+
utils::{get_missing_assoc_items, render_snippet, resolve_target_trait, Cursor},
1515
AssistId,
1616
};
1717

@@ -45,7 +45,7 @@ enum AddMissingImplMembersMode {
4545
// }
4646
//
4747
// impl Trait<u32> for () {
48-
// fn foo(&self) -> u32 {
48+
// $0fn foo(&self) -> u32 {
4949
// todo!()
5050
// }
5151
//
@@ -89,7 +89,7 @@ pub(crate) fn add_missing_impl_members(acc: &mut Assists, ctx: &AssistContext) -
8989
// impl Trait for () {
9090
// Type X = ();
9191
// fn foo(&self) {}
92-
// fn bar(&self) {}
92+
// $0fn bar(&self) {}
9393
//
9494
// }
9595
// ```
@@ -147,7 +147,7 @@ fn add_missing_impl_members_inner(
147147
}
148148

149149
let target = impl_def.syntax().text_range();
150-
acc.add(AssistId(assist_id), label, target, |edit| {
150+
acc.add(AssistId(assist_id), label, target, |builder| {
151151
let n_existing_items = impl_item_list.assoc_items().count();
152152
let source_scope = ctx.sema.scope_for_def(trait_);
153153
let target_scope = ctx.sema.scope(impl_item_list.syntax());
@@ -162,13 +162,21 @@ fn add_missing_impl_members_inner(
162162
})
163163
.map(|it| edit::remove_attrs_and_docs(&it));
164164
let new_impl_item_list = impl_item_list.append_items(items);
165-
let cursor_position = {
166-
let first_new_item = new_impl_item_list.assoc_items().nth(n_existing_items).unwrap();
167-
first_new_item.syntax().text_range().start()
165+
let first_new_item = new_impl_item_list.assoc_items().nth(n_existing_items).unwrap();
166+
167+
let original_range = impl_item_list.syntax().text_range();
168+
match ctx.config.snippet_cap {
169+
None => builder.replace(original_range, new_impl_item_list.to_string()),
170+
Some(cap) => builder.replace_snippet(
171+
cap,
172+
original_range,
173+
render_snippet(
174+
cap,
175+
new_impl_item_list.syntax(),
176+
Cursor::Before(first_new_item.syntax()),
177+
),
178+
),
168179
};
169-
170-
edit.replace_ast(impl_item_list, new_impl_item_list);
171-
edit.set_cursor(cursor_position);
172180
})
173181
}
174182

@@ -222,7 +230,7 @@ struct S;
222230
223231
impl Foo for S {
224232
fn bar(&self) {}
225-
<|>type Output;
233+
$0type Output;
226234
const CONST: usize = 42;
227235
fn foo(&self) {
228236
todo!()
@@ -263,7 +271,7 @@ struct S;
263271
264272
impl Foo for S {
265273
fn bar(&self) {}
266-
<|>fn foo(&self) {
274+
$0fn foo(&self) {
267275
todo!()
268276
}
269277
@@ -283,7 +291,7 @@ impl Foo for S { <|> }"#,
283291
trait Foo { fn foo(&self); }
284292
struct S;
285293
impl Foo for S {
286-
<|>fn foo(&self) {
294+
$0fn foo(&self) {
287295
todo!()
288296
}
289297
}"#,
@@ -302,7 +310,7 @@ impl Foo<u32> for S { <|> }"#,
302310
trait Foo<T> { fn foo(&self, t: T) -> &T; }
303311
struct S;
304312
impl Foo<u32> for S {
305-
<|>fn foo(&self, t: u32) -> &u32 {
313+
$0fn foo(&self, t: u32) -> &u32 {
306314
todo!()
307315
}
308316
}"#,
@@ -321,7 +329,7 @@ impl<U> Foo<U> for S { <|> }"#,
321329
trait Foo<T> { fn foo(&self, t: T) -> &T; }
322330
struct S;
323331
impl<U> Foo<U> for S {
324-
<|>fn foo(&self, t: U) -> &U {
332+
$0fn foo(&self, t: U) -> &U {
325333
todo!()
326334
}
327335
}"#,
@@ -340,7 +348,7 @@ impl Foo for S {}<|>"#,
340348
trait Foo { fn foo(&self); }
341349
struct S;
342350
impl Foo for S {
343-
<|>fn foo(&self) {
351+
$0fn foo(&self) {
344352
todo!()
345353
}
346354
}"#,
@@ -365,7 +373,7 @@ mod foo {
365373
}
366374
struct S;
367375
impl foo::Foo for S {
368-
<|>fn foo(&self, bar: foo::Bar) {
376+
$0fn foo(&self, bar: foo::Bar) {
369377
todo!()
370378
}
371379
}"#,
@@ -390,7 +398,7 @@ mod foo {
390398
}
391399
struct S;
392400
impl foo::Foo for S {
393-
<|>fn foo(&self, bar: foo::Bar<u32>) {
401+
$0fn foo(&self, bar: foo::Bar<u32>) {
394402
todo!()
395403
}
396404
}"#,
@@ -415,7 +423,7 @@ mod foo {
415423
}
416424
struct S;
417425
impl foo::Foo<u32> for S {
418-
<|>fn foo(&self, bar: foo::Bar<u32>) {
426+
$0fn foo(&self, bar: foo::Bar<u32>) {
419427
todo!()
420428
}
421429
}"#,
@@ -443,7 +451,7 @@ mod foo {
443451
struct Param;
444452
struct S;
445453
impl foo::Foo<Param> for S {
446-
<|>fn foo(&self, bar: Param) {
454+
$0fn foo(&self, bar: Param) {
447455
todo!()
448456
}
449457
}"#,
@@ -470,7 +478,7 @@ mod foo {
470478
}
471479
struct S;
472480
impl foo::Foo for S {
473-
<|>fn foo(&self, bar: foo::Bar<u32>::Assoc) {
481+
$0fn foo(&self, bar: foo::Bar<u32>::Assoc) {
474482
todo!()
475483
}
476484
}"#,
@@ -497,7 +505,7 @@ mod foo {
497505
}
498506
struct S;
499507
impl foo::Foo for S {
500-
<|>fn foo(&self, bar: foo::Bar<foo::Baz>) {
508+
$0fn foo(&self, bar: foo::Bar<foo::Baz>) {
501509
todo!()
502510
}
503511
}"#,
@@ -522,7 +530,7 @@ mod foo {
522530
}
523531
struct S;
524532
impl foo::Foo for S {
525-
<|>fn foo(&self, bar: dyn Fn(u32) -> i32) {
533+
$0fn foo(&self, bar: dyn Fn(u32) -> i32) {
526534
todo!()
527535
}
528536
}"#,
@@ -580,7 +588,7 @@ trait Foo {
580588
}
581589
struct S;
582590
impl Foo for S {
583-
<|>type Output;
591+
$0type Output;
584592
fn foo(&self) {
585593
todo!()
586594
}
@@ -614,7 +622,7 @@ trait Foo {
614622
}
615623
struct S;
616624
impl Foo for S {
617-
<|>fn valid(some: u32) -> bool { false }
625+
$0fn valid(some: u32) -> bool { false }
618626
}"#,
619627
)
620628
}
@@ -637,7 +645,7 @@ trait Foo<T = Self> {
637645
638646
struct S;
639647
impl Foo for S {
640-
<|>fn bar(&self, other: &Self) {
648+
$0fn bar(&self, other: &Self) {
641649
todo!()
642650
}
643651
}"#,
@@ -662,7 +670,7 @@ trait Foo<T1, T2 = Self> {
662670
663671
struct S<T>;
664672
impl Foo<T> for S<T> {
665-
<|>fn bar(&self, this: &T, that: &Self) {
673+
$0fn bar(&self, this: &T, that: &Self) {
666674
todo!()
667675
}
668676
}"#,

crates/ra_assists/src/tests/generated.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ trait Trait {
150150
impl Trait for () {
151151
Type X = ();
152152
fn foo(&self) {}
153-
fn bar(&self) {}
153+
$0fn bar(&self) {}
154154
155155
}
156156
"#####,
@@ -180,7 +180,7 @@ trait Trait<T> {
180180
}
181181
182182
impl Trait<u32> for () {
183-
fn foo(&self) -> u32 {
183+
$0fn foo(&self) -> u32 {
184184
todo!()
185185
}
186186

crates/ra_assists/src/utils.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,31 @@ use crate::assist_config::SnippetCap;
1515

1616
pub(crate) use insert_use::insert_use_statement;
1717

18-
pub(crate) fn render_snippet(
19-
_cap: SnippetCap,
20-
node: &SyntaxNode,
21-
placeholder: &SyntaxNode,
22-
) -> String {
23-
assert!(placeholder.ancestors().any(|it| it == *node));
24-
let range = placeholder.text_range() - node.text_range().start();
18+
#[derive(Clone, Copy, Debug)]
19+
pub(crate) enum Cursor<'a> {
20+
Replace(&'a SyntaxNode),
21+
Before(&'a SyntaxNode),
22+
}
23+
24+
impl<'a> Cursor<'a> {
25+
fn node(self) -> &'a SyntaxNode {
26+
match self {
27+
Cursor::Replace(node) | Cursor::Before(node) => node,
28+
}
29+
}
30+
}
31+
32+
pub(crate) fn render_snippet(_cap: SnippetCap, node: &SyntaxNode, cursor: Cursor) -> String {
33+
assert!(cursor.node().ancestors().any(|it| it == *node));
34+
let range = cursor.node().text_range() - node.text_range().start();
2535
let range: ops::Range<usize> = range.into();
2636

27-
let mut placeholder = placeholder.to_string();
37+
let mut placeholder = cursor.node().to_string();
2838
escape(&mut placeholder);
29-
let tab_stop = format!("${{0:{}}}", placeholder);
39+
let tab_stop = match cursor {
40+
Cursor::Replace(placeholder) => format!("${{0:{}}}", placeholder),
41+
Cursor::Before(placeholder) => format!("$0{}", placeholder),
42+
};
3043

3144
let mut buf = node.to_string();
3245
buf.replace_range(range, &tab_stop);

docs/user/assists.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ trait Trait {
146146
impl Trait for () {
147147
Type X = ();
148148
fn foo(&self) {}
149-
fn bar(&self) {}
149+
$0fn bar(&self) {}
150150

151151
}
152152
```
@@ -175,7 +175,7 @@ trait Trait<T> {
175175
}
176176

177177
impl Trait<u32> for () {
178-
fn foo(&self) -> u32 {
178+
$0fn foo(&self) -> u32 {
179179
todo!()
180180
}
181181

0 commit comments

Comments
 (0)