aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/completion
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/completion')
-rw-r--r--crates/ra_ide_api/src/completion/complete_postfix.rs95
-rw-r--r--crates/ra_ide_api/src/completion/completion_item.rs6
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion1.snap (renamed from crates/ra_ide_api/src/completion/snapshots/completion_item__completion_postfix.snap)50
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion2.snap94
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion3.snap94
5 files changed, 310 insertions, 29 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs
new file mode 100644
index 000000000..cf0252a00
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/complete_postfix.rs
@@ -0,0 +1,95 @@
1use crate::{
2 completion::{
3 completion_item::{
4 Completions,
5 Builder,
6 CompletionKind,
7 },
8 completion_context::CompletionContext,
9 },
10 CompletionItem
11};
12use ra_syntax::{
13 ast::AstNode,
14 TextRange
15};
16use ra_text_edit::TextEditBuilder;
17
18fn postfix_snippet(ctx: &CompletionContext, label: &str, snippet: &str) -> Builder {
19 let replace_range = ctx.source_range();
20 let receiver_range = ctx
21 .dot_receiver
22 .expect("no receiver available")
23 .syntax()
24 .range();
25 let delete_range = TextRange::from_to(receiver_range.start(), replace_range.start());
26 let mut builder = TextEditBuilder::default();
27 builder.delete(delete_range);
28 CompletionItem::new(CompletionKind::Postfix, replace_range, label)
29 .snippet(snippet)
30 .text_edit(builder.finish())
31}
32
33pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
34 if let Some(dot_receiver) = ctx.dot_receiver {
35 let receiver_text = dot_receiver.syntax().text().to_string();
36 postfix_snippet(ctx, "not", "!not").add_to(acc);
37 postfix_snippet(ctx, "if", &format!("if {} {{$0}}", receiver_text)).add_to(acc);
38 postfix_snippet(
39 ctx,
40 "match",
41 &format!("match {} {{\n${{1:_}} => {{$0\\}},\n}}", receiver_text),
42 )
43 .add_to(acc);
44 postfix_snippet(ctx, "while", &format!("while {} {{\n$0\n}}", receiver_text)).add_to(acc);
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use crate::completion::completion_item::CompletionKind;
51 use crate::completion::completion_item::check_completion;
52
53 fn check_snippet_completion(code: &str, expected_completions: &str) {
54 check_completion(code, expected_completions, CompletionKind::Postfix);
55 }
56
57 #[test]
58 fn test_filter_postfix_completion1() {
59 check_snippet_completion(
60 "filter_postfix_completion1",
61 r#"
62 fn main() {
63 let bar = "a";
64 bar.<|>
65 }
66 "#,
67 );
68 }
69
70 #[test]
71 fn test_filter_postfix_completion2() {
72 check_snippet_completion(
73 "filter_postfix_completion2",
74 r#"
75 fn main() {
76 let bar = "a";
77 bar.i<|>
78 }
79 "#,
80 );
81 }
82
83 #[test]
84 fn test_filter_postfix_completion3() {
85 check_snippet_completion(
86 "filter_postfix_completion3",
87 r#"
88 fn main() {
89 let bar = "a";
90 bar.if<|>
91 }
92 "#,
93 );
94 }
95}
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs
index f46d9e581..c892ad846 100644
--- a/crates/ra_ide_api/src/completion/completion_item.rs
+++ b/crates/ra_ide_api/src/completion/completion_item.rs
@@ -18,7 +18,12 @@ pub struct CompletionItem {
18 lookup: Option<String>, 18 lookup: Option<String>,
19 insert_text: Option<String>, 19 insert_text: Option<String>,
20 insert_text_format: InsertTextFormat, 20 insert_text_format: InsertTextFormat,
21 /// Where completion occurs. `source_range` must contain the completion offset.
22 /// `insert_text` should start with what `source_range` points to, or VSCode
23 /// will filter out the completion silently.
21 source_range: TextRange, 24 source_range: TextRange,
25 /// Additional text edit, ranges in `text_edit` must never intersect with `source_range`.
26 /// Or VSCode will drop it silently.
22 text_edit: Option<TextEdit>, 27 text_edit: Option<TextEdit>,
23} 28}
24 29
@@ -49,6 +54,7 @@ pub(crate) enum CompletionKind {
49 /// "Secret sauce" completions. 54 /// "Secret sauce" completions.
50 Magic, 55 Magic,
51 Snippet, 56 Snippet,
57 Postfix,
52} 58}
53 59
54#[derive(Debug, PartialEq, Eq, Copy, Clone)] 60#[derive(Debug, PartialEq, Eq, Copy, Clone)]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__completion_postfix.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion1.snap
index 60b5a7424..a0abd00cc 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__completion_postfix.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion1.snap
@@ -1,4 +1,4 @@
1Created: 2019-01-19T13:50:41.824939+00:00 1Created: 2019-01-21T05:12:32.815475+00:00
2Creator: [email protected] 2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs 3Source: crates/ra_ide_api/src/completion/completion_item.rs
4 4
@@ -9,18 +9,16 @@ Source: crates/ra_ide_api/src/completion/completion_item.rs
9 kind: None, 9 kind: None,
10 detail: None, 10 detail: None,
11 lookup: None, 11 lookup: None,
12 insert_text: Some(
13 "!not"
14 ),
12 insert_text_format: Snippet, 15 insert_text_format: Snippet,
16 source_range: [76; 76),
13 text_edit: Some( 17 text_edit: Some(
14 AtomTextEdit {
15 delete: [78; 78),
16 insert: "!not"
17 }
18 ),
19 additional_text_edits: Some(
20 TextEdit { 18 TextEdit {
21 atoms: [ 19 atoms: [
22 AtomTextEdit { 20 AtomTextEdit {
23 delete: [72; 78), 21 delete: [72; 76),
24 insert: "" 22 insert: ""
25 } 23 }
26 ] 24 ]
@@ -33,18 +31,16 @@ Source: crates/ra_ide_api/src/completion/completion_item.rs
33 kind: None, 31 kind: None,
34 detail: None, 32 detail: None,
35 lookup: None, 33 lookup: None,
34 insert_text: Some(
35 "if bar {$0}"
36 ),
36 insert_text_format: Snippet, 37 insert_text_format: Snippet,
38 source_range: [76; 76),
37 text_edit: Some( 39 text_edit: Some(
38 AtomTextEdit {
39 delete: [78; 78),
40 insert: "if bar {$0}"
41 }
42 ),
43 additional_text_edits: Some(
44 TextEdit { 40 TextEdit {
45 atoms: [ 41 atoms: [
46 AtomTextEdit { 42 AtomTextEdit {
47 delete: [72; 78), 43 delete: [72; 76),
48 insert: "" 44 insert: ""
49 } 45 }
50 ] 46 ]
@@ -57,18 +53,16 @@ Source: crates/ra_ide_api/src/completion/completion_item.rs
57 kind: None, 53 kind: None,
58 detail: None, 54 detail: None,
59 lookup: None, 55 lookup: None,
56 insert_text: Some(
57 "match bar {\n${1:_} => {$0\\},\n}"
58 ),
60 insert_text_format: Snippet, 59 insert_text_format: Snippet,
60 source_range: [76; 76),
61 text_edit: Some( 61 text_edit: Some(
62 AtomTextEdit {
63 delete: [78; 78),
64 insert: "match bar {\n${1:_} => {$0\\},\n}"
65 }
66 ),
67 additional_text_edits: Some(
68 TextEdit { 62 TextEdit {
69 atoms: [ 63 atoms: [
70 AtomTextEdit { 64 AtomTextEdit {
71 delete: [72; 78), 65 delete: [72; 76),
72 insert: "" 66 insert: ""
73 } 67 }
74 ] 68 ]
@@ -81,18 +75,16 @@ Source: crates/ra_ide_api/src/completion/completion_item.rs
81 kind: None, 75 kind: None,
82 detail: None, 76 detail: None,
83 lookup: None, 77 lookup: None,
78 insert_text: Some(
79 "while bar {\n$0\n}"
80 ),
84 insert_text_format: Snippet, 81 insert_text_format: Snippet,
82 source_range: [76; 76),
85 text_edit: Some( 83 text_edit: Some(
86 AtomTextEdit {
87 delete: [78; 78),
88 insert: "while bar {\n$0\n}"
89 }
90 ),
91 additional_text_edits: Some(
92 TextEdit { 84 TextEdit {
93 atoms: [ 85 atoms: [
94 AtomTextEdit { 86 AtomTextEdit {
95 delete: [72; 78), 87 delete: [72; 76),
96 insert: "" 88 insert: ""
97 } 89 }
98 ] 90 ]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion2.snap
new file mode 100644
index 000000000..3b3ee8d43
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion2.snap
@@ -0,0 +1,94 @@
1Created: 2019-01-21T05:12:32.816092+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Postfix,
8 label: "not",
9 kind: None,
10 detail: None,
11 lookup: None,
12 insert_text: Some(
13 "!not"
14 ),
15 insert_text_format: Snippet,
16 source_range: [76; 77),
17 text_edit: Some(
18 TextEdit {
19 atoms: [
20 AtomTextEdit {
21 delete: [72; 76),
22 insert: ""
23 }
24 ]
25 }
26 )
27 },
28 CompletionItem {
29 completion_kind: Postfix,
30 label: "if",
31 kind: None,
32 detail: None,
33 lookup: None,
34 insert_text: Some(
35 "if bar {$0}"
36 ),
37 insert_text_format: Snippet,
38 source_range: [76; 77),
39 text_edit: Some(
40 TextEdit {
41 atoms: [
42 AtomTextEdit {
43 delete: [72; 76),
44 insert: ""
45 }
46 ]
47 }
48 )
49 },
50 CompletionItem {
51 completion_kind: Postfix,
52 label: "match",
53 kind: None,
54 detail: None,
55 lookup: None,
56 insert_text: Some(
57 "match bar {\n${1:_} => {$0\\},\n}"
58 ),
59 insert_text_format: Snippet,
60 source_range: [76; 77),
61 text_edit: Some(
62 TextEdit {
63 atoms: [
64 AtomTextEdit {
65 delete: [72; 76),
66 insert: ""
67 }
68 ]
69 }
70 )
71 },
72 CompletionItem {
73 completion_kind: Postfix,
74 label: "while",
75 kind: None,
76 detail: None,
77 lookup: None,
78 insert_text: Some(
79 "while bar {\n$0\n}"
80 ),
81 insert_text_format: Snippet,
82 source_range: [76; 77),
83 text_edit: Some(
84 TextEdit {
85 atoms: [
86 AtomTextEdit {
87 delete: [72; 76),
88 insert: ""
89 }
90 ]
91 }
92 )
93 }
94]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion3.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion3.snap
new file mode 100644
index 000000000..31e8f008c
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion3.snap
@@ -0,0 +1,94 @@
1Created: 2019-01-21T05:19:05.341730+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Postfix,
8 label: "not",
9 kind: None,
10 detail: None,
11 lookup: None,
12 insert_text: Some(
13 "!not"
14 ),
15 insert_text_format: Snippet,
16 source_range: [76; 78),
17 text_edit: Some(
18 TextEdit {
19 atoms: [
20 AtomTextEdit {
21 delete: [72; 76),
22 insert: ""
23 }
24 ]
25 }
26 )
27 },
28 CompletionItem {
29 completion_kind: Postfix,
30 label: "if",
31 kind: None,
32 detail: None,
33 lookup: None,
34 insert_text: Some(
35 "if bar {$0}"
36 ),
37 insert_text_format: Snippet,
38 source_range: [76; 78),
39 text_edit: Some(
40 TextEdit {
41 atoms: [
42 AtomTextEdit {
43 delete: [72; 76),
44 insert: ""
45 }
46 ]
47 }
48 )
49 },
50 CompletionItem {
51 completion_kind: Postfix,
52 label: "match",
53 kind: None,
54 detail: None,
55 lookup: None,
56 insert_text: Some(
57 "match bar {\n${1:_} => {$0\\},\n}"
58 ),
59 insert_text_format: Snippet,
60 source_range: [76; 78),
61 text_edit: Some(
62 TextEdit {
63 atoms: [
64 AtomTextEdit {
65 delete: [72; 76),
66 insert: ""
67 }
68 ]
69 }
70 )
71 },
72 CompletionItem {
73 completion_kind: Postfix,
74 label: "while",
75 kind: None,
76 detail: None,
77 lookup: None,
78 insert_text: Some(
79 "while bar {\n$0\n}"
80 ),
81 insert_text_format: Snippet,
82 source_range: [76; 78),
83 text_edit: Some(
84 TextEdit {
85 atoms: [
86 AtomTextEdit {
87 delete: [72; 76),
88 insert: ""
89 }
90 ]
91 }
92 )
93 }
94]