diff options
-rw-r--r-- | crates/ra_ide_api/src/completion.rs | 3 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_postfix.rs | 95 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/completion_item.rs | 6 | ||||
-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.snap | 94 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/snapshots/completion_item__filter_postfix_completion3.snap | 94 |
6 files changed, 312 insertions, 30 deletions
diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs index 855f5d964..565d57c37 100644 --- a/crates/ra_ide_api/src/completion.rs +++ b/crates/ra_ide_api/src/completion.rs | |||
@@ -7,6 +7,7 @@ mod complete_keyword; | |||
7 | mod complete_snippet; | 7 | mod complete_snippet; |
8 | mod complete_path; | 8 | mod complete_path; |
9 | mod complete_scope; | 9 | mod complete_scope; |
10 | mod complete_postfix; | ||
10 | 11 | ||
11 | use ra_db::SyntaxDatabase; | 12 | use ra_db::SyntaxDatabase; |
12 | 13 | ||
@@ -57,6 +58,6 @@ pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Opti | |||
57 | complete_path::complete_path(&mut acc, &ctx); | 58 | complete_path::complete_path(&mut acc, &ctx); |
58 | complete_scope::complete_scope(&mut acc, &ctx); | 59 | complete_scope::complete_scope(&mut acc, &ctx); |
59 | complete_dot::complete_dot(&mut acc, &ctx); | 60 | complete_dot::complete_dot(&mut acc, &ctx); |
60 | 61 | complete_postfix::complete_postfix(&mut acc, &ctx); | |
61 | Some(acc) | 62 | Some(acc) |
62 | } | 63 | } |
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 @@ | |||
1 | use crate::{ | ||
2 | completion::{ | ||
3 | completion_item::{ | ||
4 | Completions, | ||
5 | Builder, | ||
6 | CompletionKind, | ||
7 | }, | ||
8 | completion_context::CompletionContext, | ||
9 | }, | ||
10 | CompletionItem | ||
11 | }; | ||
12 | use ra_syntax::{ | ||
13 | ast::AstNode, | ||
14 | TextRange | ||
15 | }; | ||
16 | use ra_text_edit::TextEditBuilder; | ||
17 | |||
18 | fn 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 | |||
33 | pub(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)] | ||
49 | mod 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 @@ | |||
1 | Created: 2019-01-19T13:50:41.824939+00:00 | 1 | Created: 2019-01-21T05:12:32.815475+00:00 |
2 | Creator: [email protected] | 2 | Creator: [email protected] |
3 | Source: crates/ra_ide_api/src/completion/completion_item.rs | 3 | Source: 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 @@ | |||
1 | Created: 2019-01-21T05:12:32.816092+00:00 | ||
2 | Creator: [email protected] | ||
3 | Source: 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 @@ | |||
1 | Created: 2019-01-21T05:19:05.341730+00:00 | ||
2 | Creator: [email protected] | ||
3 | Source: 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 | ] | ||