aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide_api/src/completion.rs14
-rw-r--r--crates/ra_ide_api/src/completion/complete_dot.rs45
-rw-r--r--crates/ra_ide_api/src/completion/complete_fn_param.rs13
-rw-r--r--crates/ra_ide_api/src/completion/complete_keyword.rs165
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs37
-rw-r--r--crates/ra_ide_api/src/completion/complete_scope.rs62
-rw-r--r--crates/ra_ide_api/src/completion/complete_snippet.rs37
-rw-r--r--crates/ra_ide_api/src/completion/completion_context.rs13
-rw-r--r--crates/ra_ide_api/src/completion/completion_item.rs165
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap34
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap47
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap47
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops1.snap111
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops2.snap81
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__completion_postfix.snap102
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__deeply_nested_use_tree.snap19
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__dont_add_semi_after_return_if_not_a_statement.snap81
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap32
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap19
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap34
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap36
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap36
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function1.snap81
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function2.snap111
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function3.snap81
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function4.snap81
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt1.snap49
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt2.snap34
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt3.snap34
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi1.snap81
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi2.snap81
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__method_completion.snap21
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap47
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap34
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__nested_use_tree.snap32
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__no_non_self_method.snap5
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__no_semi_after_break_continue_in_expr.snap111
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__no_struct_field_completion_for_method_call.snap5
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_last_param.snap19
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_nth_param.snap19
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_trait_param.snap19
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__reference_completion.snap32
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap34
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap19
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap36
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap38
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion.snap21
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion_autoderef.snap36
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion_self.snap36
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_crate.snap32
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_self.snap19
-rw-r--r--crates/ra_ide_api/src/lib.rs2
-rw-r--r--crates/ra_lsp_server/src/conv.rs38
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs6
54 files changed, 2206 insertions, 318 deletions
diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs
index b03ddd74c..855f5d964 100644
--- a/crates/ra_ide_api/src/completion.rs
+++ b/crates/ra_ide_api/src/completion.rs
@@ -19,7 +19,7 @@ use crate::{
19 }, 19 },
20}; 20};
21 21
22pub use crate::completion::completion_item::{CompletionItem, InsertText, CompletionItemKind}; 22pub use crate::completion::completion_item::{CompletionItem, CompletionItemKind, InsertTextFormat};
23 23
24/// Main entry point for completion. We run completion as a two-phase process. 24/// Main entry point for completion. We run completion as a two-phase process.
25/// 25///
@@ -60,15 +60,3 @@ pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Opti
60 60
61 Some(acc) 61 Some(acc)
62} 62}
63
64#[cfg(test)]
65fn check_completion(code: &str, expected_completions: &str, kind: CompletionKind) {
66 use crate::mock_analysis::{single_file_with_position, analysis_and_position};
67 let (analysis, position) = if code.contains("//-") {
68 analysis_and_position(code)
69 } else {
70 single_file_with_position(code)
71 };
72 let completions = completions(&analysis.db, position).unwrap();
73 completions.assert_match(expected_completions, kind);
74}
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs
index 76c2f8173..32fd497be 100644
--- a/crates/ra_ide_api/src/completion/complete_dot.rs
+++ b/crates/ra_ide_api/src/completion/complete_dot.rs
@@ -1,6 +1,7 @@
1use hir::{Ty, Def}; 1use hir::{Ty, Def};
2 2
3use crate::completion::{CompletionContext, Completions, CompletionKind, CompletionItem, CompletionItemKind}; 3use crate::completion::{CompletionContext, Completions, CompletionItem, CompletionItemKind};
4use crate::completion::completion_item::CompletionKind;
4 5
5/// Complete dot accesses, i.e. fields or methods (currently only fields). 6/// Complete dot accesses, i.e. fields or methods (currently only fields).
6pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { 7pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
@@ -32,6 +33,7 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
32 for field in s.fields(ctx.db) { 33 for field in s.fields(ctx.db) {
33 CompletionItem::new( 34 CompletionItem::new(
34 CompletionKind::Reference, 35 CompletionKind::Reference,
36 ctx.source_range(),
35 field.name().to_string(), 37 field.name().to_string(),
36 ) 38 )
37 .kind(CompletionItemKind::Field) 39 .kind(CompletionItemKind::Field)
@@ -45,9 +47,13 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
45 } 47 }
46 Ty::Tuple(fields) => { 48 Ty::Tuple(fields) => {
47 for (i, _ty) in fields.iter().enumerate() { 49 for (i, _ty) in fields.iter().enumerate() {
48 CompletionItem::new(CompletionKind::Reference, i.to_string()) 50 CompletionItem::new(
49 .kind(CompletionItemKind::Field) 51 CompletionKind::Reference,
50 .add_to(acc); 52 ctx.source_range(),
53 i.to_string(),
54 )
55 .kind(CompletionItemKind::Field)
56 .add_to(acc);
51 } 57 }
52 } 58 }
53 _ => {} 59 _ => {}
@@ -59,10 +65,14 @@ fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty
59 receiver.iterate_methods(ctx.db, |func| { 65 receiver.iterate_methods(ctx.db, |func| {
60 let sig = func.signature(ctx.db); 66 let sig = func.signature(ctx.db);
61 if sig.has_self_param() { 67 if sig.has_self_param() {
62 CompletionItem::new(CompletionKind::Reference, sig.name().to_string()) 68 CompletionItem::new(
63 .from_function(ctx, func) 69 CompletionKind::Reference,
64 .kind(CompletionItemKind::Method) 70 ctx.source_range(),
65 .add_to(acc); 71 sig.name().to_string(),
72 )
73 .from_function(ctx, func)
74 .kind(CompletionItemKind::Method)
75 .add_to(acc);
66 } 76 }
67 None::<()> 77 None::<()>
68 }); 78 });
@@ -71,27 +81,29 @@ fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty
71#[cfg(test)] 81#[cfg(test)]
72mod tests { 82mod tests {
73 use crate::completion::*; 83 use crate::completion::*;
84 use crate::completion::completion_item::check_completion;
74 85
75 fn check_ref_completion(code: &str, expected_completions: &str) { 86 fn check_ref_completion(name: &str, code: &str) {
76 check_completion(code, expected_completions, CompletionKind::Reference); 87 check_completion(name, code, CompletionKind::Reference);
77 } 88 }
78 89
79 #[test] 90 #[test]
80 fn test_struct_field_completion() { 91 fn test_struct_field_completion() {
81 check_ref_completion( 92 check_ref_completion(
93 "struct_field_completion",
82 r" 94 r"
83 struct A { the_field: u32 } 95 struct A { the_field: u32 }
84 fn foo(a: A) { 96 fn foo(a: A) {
85 a.<|> 97 a.<|>
86 } 98 }
87 ", 99 ",
88 r#"the_field "u32""#,
89 ); 100 );
90 } 101 }
91 102
92 #[test] 103 #[test]
93 fn test_struct_field_completion_self() { 104 fn test_struct_field_completion_self() {
94 check_ref_completion( 105 check_ref_completion(
106 "struct_field_completion_self",
95 r" 107 r"
96 struct A { the_field: (u32,) } 108 struct A { the_field: (u32,) }
97 impl A { 109 impl A {
@@ -100,14 +112,13 @@ mod tests {
100 } 112 }
101 } 113 }
102 ", 114 ",
103 r#"the_field "(u32,)"
104 foo "foo($0)""#,
105 ); 115 );
106 } 116 }
107 117
108 #[test] 118 #[test]
109 fn test_struct_field_completion_autoderef() { 119 fn test_struct_field_completion_autoderef() {
110 check_ref_completion( 120 check_ref_completion(
121 "struct_field_completion_autoderef",
111 r" 122 r"
112 struct A { the_field: (u32, i32) } 123 struct A { the_field: (u32, i32) }
113 impl A { 124 impl A {
@@ -116,27 +127,26 @@ mod tests {
116 } 127 }
117 } 128 }
118 ", 129 ",
119 r#"the_field "(u32, i32)"
120 foo "foo($0)""#,
121 ); 130 );
122 } 131 }
123 132
124 #[test] 133 #[test]
125 fn test_no_struct_field_completion_for_method_call() { 134 fn test_no_struct_field_completion_for_method_call() {
126 check_ref_completion( 135 check_ref_completion(
136 "no_struct_field_completion_for_method_call",
127 r" 137 r"
128 struct A { the_field: u32 } 138 struct A { the_field: u32 }
129 fn foo(a: A) { 139 fn foo(a: A) {
130 a.<|>() 140 a.<|>()
131 } 141 }
132 ", 142 ",
133 r#""#,
134 ); 143 );
135 } 144 }
136 145
137 #[test] 146 #[test]
138 fn test_method_completion() { 147 fn test_method_completion() {
139 check_ref_completion( 148 check_ref_completion(
149 "method_completion",
140 r" 150 r"
141 struct A {} 151 struct A {}
142 impl A { 152 impl A {
@@ -146,13 +156,13 @@ mod tests {
146 a.<|> 156 a.<|>
147 } 157 }
148 ", 158 ",
149 r#"the_method "the_method($0)""#,
150 ); 159 );
151 } 160 }
152 161
153 #[test] 162 #[test]
154 fn test_no_non_self_method() { 163 fn test_no_non_self_method() {
155 check_ref_completion( 164 check_ref_completion(
165 "no_non_self_method",
156 r" 166 r"
157 struct A {} 167 struct A {}
158 impl A { 168 impl A {
@@ -162,7 +172,6 @@ mod tests {
162 a.<|> 172 a.<|>
163 } 173 }
164 ", 174 ",
165 r#""#,
166 ); 175 );
167 } 176 }
168} 177}
diff --git a/crates/ra_ide_api/src/completion/complete_fn_param.rs b/crates/ra_ide_api/src/completion/complete_fn_param.rs
index c1739e47e..8d4df4ea1 100644
--- a/crates/ra_ide_api/src/completion/complete_fn_param.rs
+++ b/crates/ra_ide_api/src/completion/complete_fn_param.rs
@@ -34,7 +34,7 @@ pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext)
34 } 34 }
35 }) 35 })
36 .for_each(|(label, lookup)| { 36 .for_each(|(label, lookup)| {
37 CompletionItem::new(CompletionKind::Magic, label) 37 CompletionItem::new(CompletionKind::Magic, ctx.source_range(), label)
38 .lookup_by(lookup) 38 .lookup_by(lookup)
39 .add_to(acc) 39 .add_to(acc)
40 }); 40 });
@@ -56,38 +56,40 @@ pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext)
56#[cfg(test)] 56#[cfg(test)]
57mod tests { 57mod tests {
58 use crate::completion::*; 58 use crate::completion::*;
59 use crate::completion::completion_item::check_completion;
59 60
60 fn check_magic_completion(code: &str, expected_completions: &str) { 61 fn check_magic_completion(name: &str, code: &str) {
61 check_completion(code, expected_completions, CompletionKind::Magic); 62 check_completion(name, code, CompletionKind::Magic);
62 } 63 }
63 64
64 #[test] 65 #[test]
65 fn test_param_completion_last_param() { 66 fn test_param_completion_last_param() {
66 check_magic_completion( 67 check_magic_completion(
68 "param_completion_last_param",
67 r" 69 r"
68 fn foo(file_id: FileId) {} 70 fn foo(file_id: FileId) {}
69 fn bar(file_id: FileId) {} 71 fn bar(file_id: FileId) {}
70 fn baz(file<|>) {} 72 fn baz(file<|>) {}
71 ", 73 ",
72 r#"file_id "file_id: FileId""#,
73 ); 74 );
74 } 75 }
75 76
76 #[test] 77 #[test]
77 fn test_param_completion_nth_param() { 78 fn test_param_completion_nth_param() {
78 check_magic_completion( 79 check_magic_completion(
80 "param_completion_nth_param",
79 r" 81 r"
80 fn foo(file_id: FileId) {} 82 fn foo(file_id: FileId) {}
81 fn bar(file_id: FileId) {} 83 fn bar(file_id: FileId) {}
82 fn baz(file<|>, x: i32) {} 84 fn baz(file<|>, x: i32) {}
83 ", 85 ",
84 r#"file_id "file_id: FileId""#,
85 ); 86 );
86 } 87 }
87 88
88 #[test] 89 #[test]
89 fn test_param_completion_trait_param() { 90 fn test_param_completion_trait_param() {
90 check_magic_completion( 91 check_magic_completion(
92 "param_completion_trait_param",
91 r" 93 r"
92 pub(crate) trait SourceRoot { 94 pub(crate) trait SourceRoot {
93 pub fn contains(&self, file_id: FileId) -> bool; 95 pub fn contains(&self, file_id: FileId) -> bool;
@@ -96,7 +98,6 @@ mod tests {
96 pub fn syntax(&self, file<|>) 98 pub fn syntax(&self, file<|>)
97 } 99 }
98 ", 100 ",
99 r#"file_id "file_id: FileId""#,
100 ); 101 );
101 } 102 }
102} 103}
diff --git a/crates/ra_ide_api/src/completion/complete_keyword.rs b/crates/ra_ide_api/src/completion/complete_keyword.rs
index d350f06ce..10ae01bc5 100644
--- a/crates/ra_ide_api/src/completion/complete_keyword.rs
+++ b/crates/ra_ide_api/src/completion/complete_keyword.rs
@@ -9,38 +9,36 @@ use crate::completion::{CompletionContext, CompletionItem, Completions, Completi
9 9
10pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) { 10pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
11 // complete keyword "crate" in use stmt 11 // complete keyword "crate" in use stmt
12 let source_range = ctx.source_range();
12 match (ctx.use_item_syntax.as_ref(), ctx.path_prefix.as_ref()) { 13 match (ctx.use_item_syntax.as_ref(), ctx.path_prefix.as_ref()) {
13 (Some(_), None) => { 14 (Some(_), None) => {
14 CompletionItem::new(CompletionKind::Keyword, "crate") 15 CompletionItem::new(CompletionKind::Keyword, source_range, "crate")
15 .kind(CompletionItemKind::Keyword) 16 .kind(CompletionItemKind::Keyword)
16 .lookup_by("crate") 17 .insert_text("crate::")
17 .snippet("crate::")
18 .add_to(acc); 18 .add_to(acc);
19 CompletionItem::new(CompletionKind::Keyword, "self") 19 CompletionItem::new(CompletionKind::Keyword, source_range, "self")
20 .kind(CompletionItemKind::Keyword) 20 .kind(CompletionItemKind::Keyword)
21 .lookup_by("self")
22 .add_to(acc); 21 .add_to(acc);
23 CompletionItem::new(CompletionKind::Keyword, "super") 22 CompletionItem::new(CompletionKind::Keyword, source_range, "super")
24 .kind(CompletionItemKind::Keyword) 23 .kind(CompletionItemKind::Keyword)
25 .lookup_by("super") 24 .insert_text("super::")
26 .add_to(acc); 25 .add_to(acc);
27 } 26 }
28 (Some(_), Some(_)) => { 27 (Some(_), Some(_)) => {
29 CompletionItem::new(CompletionKind::Keyword, "self") 28 CompletionItem::new(CompletionKind::Keyword, source_range, "self")
30 .kind(CompletionItemKind::Keyword) 29 .kind(CompletionItemKind::Keyword)
31 .lookup_by("self")
32 .add_to(acc); 30 .add_to(acc);
33 CompletionItem::new(CompletionKind::Keyword, "super") 31 CompletionItem::new(CompletionKind::Keyword, source_range, "super")
34 .kind(CompletionItemKind::Keyword) 32 .kind(CompletionItemKind::Keyword)
35 .lookup_by("super") 33 .insert_text("super::")
36 .add_to(acc); 34 .add_to(acc);
37 } 35 }
38 _ => {} 36 _ => {}
39 } 37 }
40} 38}
41 39
42fn keyword(kw: &str, snippet: &str) -> CompletionItem { 40fn keyword(ctx: &CompletionContext, kw: &str, snippet: &str) -> CompletionItem {
43 CompletionItem::new(CompletionKind::Keyword, kw) 41 CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), kw)
44 .kind(CompletionItemKind::Keyword) 42 .kind(CompletionItemKind::Keyword)
45 .snippet(snippet) 43 .snippet(snippet)
46 .build() 44 .build()
@@ -55,25 +53,25 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
55 Some(it) => it, 53 Some(it) => it,
56 None => return, 54 None => return,
57 }; 55 };
58 acc.add(keyword("if", "if $0 {}")); 56 acc.add(keyword(ctx, "if", "if $0 {}"));
59 acc.add(keyword("match", "match $0 {}")); 57 acc.add(keyword(ctx, "match", "match $0 {}"));
60 acc.add(keyword("while", "while $0 {}")); 58 acc.add(keyword(ctx, "while", "while $0 {}"));
61 acc.add(keyword("loop", "loop {$0}")); 59 acc.add(keyword(ctx, "loop", "loop {$0}"));
62 60
63 if ctx.after_if { 61 if ctx.after_if {
64 acc.add(keyword("else", "else {$0}")); 62 acc.add(keyword(ctx, "else", "else {$0}"));
65 acc.add(keyword("else if", "else if $0 {}")); 63 acc.add(keyword(ctx, "else if", "else if $0 {}"));
66 } 64 }
67 if is_in_loop_body(ctx.leaf) { 65 if is_in_loop_body(ctx.leaf) {
68 if ctx.can_be_stmt { 66 if ctx.can_be_stmt {
69 acc.add(keyword("continue", "continue;")); 67 acc.add(keyword(ctx, "continue", "continue;"));
70 acc.add(keyword("break", "break;")); 68 acc.add(keyword(ctx, "break", "break;"));
71 } else { 69 } else {
72 acc.add(keyword("continue", "continue")); 70 acc.add(keyword(ctx, "continue", "continue"));
73 acc.add(keyword("break", "break")); 71 acc.add(keyword(ctx, "break", "break"));
74 } 72 }
75 } 73 }
76 acc.add_all(complete_return(fn_def, ctx.can_be_stmt)); 74 acc.add_all(complete_return(ctx, fn_def, ctx.can_be_stmt));
77} 75}
78 76
79fn is_in_loop_body(leaf: &SyntaxNode) -> bool { 77fn is_in_loop_body(leaf: &SyntaxNode) -> bool {
@@ -95,78 +93,69 @@ fn is_in_loop_body(leaf: &SyntaxNode) -> bool {
95 false 93 false
96} 94}
97 95
98fn complete_return(fn_def: &ast::FnDef, can_be_stmt: bool) -> Option<CompletionItem> { 96fn complete_return(
97 ctx: &CompletionContext,
98 fn_def: &ast::FnDef,
99 can_be_stmt: bool,
100) -> Option<CompletionItem> {
99 let snip = match (can_be_stmt, fn_def.ret_type().is_some()) { 101 let snip = match (can_be_stmt, fn_def.ret_type().is_some()) {
100 (true, true) => "return $0;", 102 (true, true) => "return $0;",
101 (true, false) => "return;", 103 (true, false) => "return;",
102 (false, true) => "return $0", 104 (false, true) => "return $0",
103 (false, false) => "return", 105 (false, false) => "return",
104 }; 106 };
105 Some(keyword("return", snip)) 107 Some(keyword(ctx, "return", snip))
106} 108}
107 109
108#[cfg(test)] 110#[cfg(test)]
109mod tests { 111mod tests {
110 use crate::completion::{CompletionKind, check_completion}; 112 use crate::completion::CompletionKind;
111 fn check_keyword_completion(code: &str, expected_completions: &str) { 113 use crate::completion::completion_item::check_completion;
112 check_completion(code, expected_completions, CompletionKind::Keyword); 114
115 fn check_keyword_completion(name: &str, code: &str) {
116 check_completion(name, code, CompletionKind::Keyword);
113 } 117 }
114 118
115 #[test] 119 #[test]
116 fn completes_keywords_in_use_stmt() { 120 fn completes_keywords_in_use_stmt() {
117 check_keyword_completion( 121 check_keyword_completion(
122 "keywords_in_use_stmt1",
118 r" 123 r"
119 use <|> 124 use <|>
120 ", 125 ",
121 r#"
122 crate "crate" "crate::"
123 self "self"
124 super "super"
125 "#,
126 ); 126 );
127 127
128 check_keyword_completion( 128 check_keyword_completion(
129 "keywords_in_use_stmt2",
129 r" 130 r"
130 use a::<|> 131 use a::<|>
131 ", 132 ",
132 r#"
133 self "self"
134 super "super"
135 "#,
136 ); 133 );
137 134
138 check_keyword_completion( 135 check_keyword_completion(
136 "keywords_in_use_stmt3",
139 r" 137 r"
140 use a::{b, <|>} 138 use a::{b, <|>}
141 ", 139 ",
142 r#"
143 self "self"
144 super "super"
145 "#,
146 ); 140 );
147 } 141 }
148 142
149 #[test] 143 #[test]
150 fn completes_various_keywords_in_function() { 144 fn completes_various_keywords_in_function() {
151 check_keyword_completion( 145 check_keyword_completion(
146 "keywords_in_function1",
152 r" 147 r"
153 fn quux() { 148 fn quux() {
154 <|> 149 <|>
155 } 150 }
156 ", 151 ",
157 r#"
158 if "if $0 {}"
159 match "match $0 {}"
160 while "while $0 {}"
161 loop "loop {$0}"
162 return "return;"
163 "#,
164 ); 152 );
165 } 153 }
166 154
167 #[test] 155 #[test]
168 fn completes_else_after_if() { 156 fn completes_else_after_if() {
169 check_keyword_completion( 157 check_keyword_completion(
158 "keywords_in_function2",
170 r" 159 r"
171 fn quux() { 160 fn quux() {
172 if true { 161 if true {
@@ -174,55 +163,35 @@ mod tests {
174 } <|> 163 } <|>
175 } 164 }
176 ", 165 ",
177 r#"
178 if "if $0 {}"
179 match "match $0 {}"
180 while "while $0 {}"
181 loop "loop {$0}"
182 else "else {$0}"
183 else if "else if $0 {}"
184 return "return;"
185 "#,
186 ); 166 );
187 } 167 }
188 168
189 #[test] 169 #[test]
190 fn test_completion_return_value() { 170 fn test_completion_return_value() {
191 check_keyword_completion( 171 check_keyword_completion(
172 "keywords_in_function3",
192 r" 173 r"
193 fn quux() -> i32 { 174 fn quux() -> i32 {
194 <|> 175 <|>
195 92 176 92
196 } 177 }
197 ", 178 ",
198 r#"
199 if "if $0 {}"
200 match "match $0 {}"
201 while "while $0 {}"
202 loop "loop {$0}"
203 return "return $0;"
204 "#,
205 ); 179 );
206 check_keyword_completion( 180 check_keyword_completion(
181 "keywords_in_function4",
207 r" 182 r"
208 fn quux() { 183 fn quux() {
209 <|> 184 <|>
210 92 185 92
211 } 186 }
212 ", 187 ",
213 r#"
214 if "if $0 {}"
215 match "match $0 {}"
216 while "while $0 {}"
217 loop "loop {$0}"
218 return "return;"
219 "#,
220 ); 188 );
221 } 189 }
222 190
223 #[test] 191 #[test]
224 fn dont_add_semi_after_return_if_not_a_statement() { 192 fn dont_add_semi_after_return_if_not_a_statement() {
225 check_keyword_completion( 193 check_keyword_completion(
194 "dont_add_semi_after_return_if_not_a_statement",
226 r" 195 r"
227 fn quux() -> i32 { 196 fn quux() -> i32 {
228 match () { 197 match () {
@@ -230,19 +199,13 @@ mod tests {
230 } 199 }
231 } 200 }
232 ", 201 ",
233 r#"
234 if "if $0 {}"
235 match "match $0 {}"
236 while "while $0 {}"
237 loop "loop {$0}"
238 return "return $0"
239 "#,
240 ); 202 );
241 } 203 }
242 204
243 #[test] 205 #[test]
244 fn last_return_in_block_has_semi() { 206 fn last_return_in_block_has_semi() {
245 check_keyword_completion( 207 check_keyword_completion(
208 "last_return_in_block_has_semi1",
246 r" 209 r"
247 fn quux() -> i32 { 210 fn quux() -> i32 {
248 if condition { 211 if condition {
@@ -250,15 +213,9 @@ mod tests {
250 } 213 }
251 } 214 }
252 ", 215 ",
253 r#"
254 if "if $0 {}"
255 match "match $0 {}"
256 while "while $0 {}"
257 loop "loop {$0}"
258 return "return $0;"
259 "#,
260 ); 216 );
261 check_keyword_completion( 217 check_keyword_completion(
218 "last_return_in_block_has_semi2",
262 r" 219 r"
263 fn quux() -> i32 { 220 fn quux() -> i32 {
264 if condition { 221 if condition {
@@ -268,54 +225,35 @@ mod tests {
268 x 225 x
269 } 226 }
270 ", 227 ",
271 r#"
272 if "if $0 {}"
273 match "match $0 {}"
274 while "while $0 {}"
275 loop "loop {$0}"
276 return "return $0;"
277 "#,
278 ); 228 );
279 } 229 }
280 230
281 #[test] 231 #[test]
282 fn completes_break_and_continue_in_loops() { 232 fn completes_break_and_continue_in_loops() {
283 check_keyword_completion( 233 check_keyword_completion(
234 "completes_break_and_continue_in_loops1",
284 r" 235 r"
285 fn quux() -> i32 { 236 fn quux() -> i32 {
286 loop { <|> } 237 loop { <|> }
287 } 238 }
288 ", 239 ",
289 r#"
290 if "if $0 {}"
291 match "match $0 {}"
292 while "while $0 {}"
293 loop "loop {$0}"
294 continue "continue;"
295 break "break;"
296 return "return $0;"
297 "#,
298 ); 240 );
241
299 // No completion: lambda isolates control flow 242 // No completion: lambda isolates control flow
300 check_keyword_completion( 243 check_keyword_completion(
244 "completes_break_and_continue_in_loops2",
301 r" 245 r"
302 fn quux() -> i32 { 246 fn quux() -> i32 {
303 loop { || { <|> } } 247 loop { || { <|> } }
304 } 248 }
305 ", 249 ",
306 r#"
307 if "if $0 {}"
308 match "match $0 {}"
309 while "while $0 {}"
310 loop "loop {$0}"
311 return "return $0;"
312 "#,
313 ); 250 );
314 } 251 }
315 252
316 #[test] 253 #[test]
317 fn no_semi_after_break_continue_in_expr() { 254 fn no_semi_after_break_continue_in_expr() {
318 check_keyword_completion( 255 check_keyword_completion(
256 "no_semi_after_break_continue_in_expr",
319 r" 257 r"
320 fn f() { 258 fn f() {
321 loop { 259 loop {
@@ -325,15 +263,6 @@ mod tests {
325 } 263 }
326 } 264 }
327 ", 265 ",
328 r#"
329 if "if $0 {}"
330 match "match $0 {}"
331 while "while $0 {}"
332 loop "loop {$0}"
333 continue "continue"
334 break "break"
335 return "return"
336 "#,
337 ) 266 )
338 } 267 }
339} 268}
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 1eded7658..804954ee1 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -15,18 +15,26 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
15 hir::Def::Module(module) => { 15 hir::Def::Module(module) => {
16 let module_scope = module.scope(ctx.db); 16 let module_scope = module.scope(ctx.db);
17 for (name, res) in module_scope.entries() { 17 for (name, res) in module_scope.entries() {
18 CompletionItem::new(CompletionKind::Reference, name.to_string()) 18 CompletionItem::new(
19 .from_resolution(ctx, res) 19 CompletionKind::Reference,
20 .add_to(acc); 20 ctx.source_range(),
21 name.to_string(),
22 )
23 .from_resolution(ctx, res)
24 .add_to(acc);
21 } 25 }
22 } 26 }
23 hir::Def::Enum(e) => { 27 hir::Def::Enum(e) => {
24 e.variants(ctx.db) 28 e.variants(ctx.db)
25 .into_iter() 29 .into_iter()
26 .for_each(|(variant_name, _variant)| { 30 .for_each(|(variant_name, _variant)| {
27 CompletionItem::new(CompletionKind::Reference, variant_name.to_string()) 31 CompletionItem::new(
28 .kind(CompletionItemKind::EnumVariant) 32 CompletionKind::Reference,
29 .add_to(acc) 33 ctx.source_range(),
34 variant_name.to_string(),
35 )
36 .kind(CompletionItemKind::EnumVariant)
37 .add_to(acc)
30 }); 38 });
31 } 39 }
32 _ => return, 40 _ => return,
@@ -35,7 +43,8 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
35 43
36#[cfg(test)] 44#[cfg(test)]
37mod tests { 45mod tests {
38 use crate::completion::{CompletionKind, check_completion}; 46 use crate::completion::CompletionKind;
47 use crate::completion::completion_item::check_completion;
39 48
40 fn check_reference_completion(code: &str, expected_completions: &str) { 49 fn check_reference_completion(code: &str, expected_completions: &str) {
41 check_completion(code, expected_completions, CompletionKind::Reference); 50 check_completion(code, expected_completions, CompletionKind::Reference);
@@ -44,6 +53,7 @@ mod tests {
44 #[test] 53 #[test]
45 fn completes_use_item_starting_with_self() { 54 fn completes_use_item_starting_with_self() {
46 check_reference_completion( 55 check_reference_completion(
56 "use_item_starting_with_self",
47 r" 57 r"
48 use self::m::<|>; 58 use self::m::<|>;
49 59
@@ -51,13 +61,13 @@ mod tests {
51 struct Bar; 61 struct Bar;
52 } 62 }
53 ", 63 ",
54 "Bar",
55 ); 64 );
56 } 65 }
57 66
58 #[test] 67 #[test]
59 fn completes_use_item_starting_with_crate() { 68 fn completes_use_item_starting_with_crate() {
60 check_reference_completion( 69 check_reference_completion(
70 "use_item_starting_with_crate",
61 " 71 "
62 //- /lib.rs 72 //- /lib.rs
63 mod foo; 73 mod foo;
@@ -65,13 +75,13 @@ mod tests {
65 //- /foo.rs 75 //- /foo.rs
66 use crate::Sp<|> 76 use crate::Sp<|>
67 ", 77 ",
68 "Spam;foo",
69 ); 78 );
70 } 79 }
71 80
72 #[test] 81 #[test]
73 fn completes_nested_use_tree() { 82 fn completes_nested_use_tree() {
74 check_reference_completion( 83 check_reference_completion(
84 "nested_use_tree",
75 " 85 "
76 //- /lib.rs 86 //- /lib.rs
77 mod foo; 87 mod foo;
@@ -79,13 +89,13 @@ mod tests {
79 //- /foo.rs 89 //- /foo.rs
80 use crate::{Sp<|>}; 90 use crate::{Sp<|>};
81 ", 91 ",
82 "Spam;foo",
83 ); 92 );
84 } 93 }
85 94
86 #[test] 95 #[test]
87 fn completes_deeply_nested_use_tree() { 96 fn completes_deeply_nested_use_tree() {
88 check_reference_completion( 97 check_reference_completion(
98 "deeply_nested_use_tree",
89 " 99 "
90 //- /lib.rs 100 //- /lib.rs
91 mod foo; 101 mod foo;
@@ -97,37 +107,37 @@ mod tests {
97 //- /foo.rs 107 //- /foo.rs
98 use crate::{bar::{baz::Sp<|>}}; 108 use crate::{bar::{baz::Sp<|>}};
99 ", 109 ",
100 "Spam",
101 ); 110 );
102 } 111 }
103 112
104 #[test] 113 #[test]
105 fn completes_enum_variant() { 114 fn completes_enum_variant() {
106 check_reference_completion( 115 check_reference_completion(
116 "reference_completion",
107 " 117 "
108 //- /lib.rs 118 //- /lib.rs
109 enum E { Foo, Bar(i32) } 119 enum E { Foo, Bar(i32) }
110 fn foo() { let _ = E::<|> } 120 fn foo() { let _ = E::<|> }
111 ", 121 ",
112 "Foo;Bar",
113 ); 122 );
114 } 123 }
115 124
116 #[test] 125 #[test]
117 fn dont_render_function_parens_in_use_item() { 126 fn dont_render_function_parens_in_use_item() {
118 check_reference_completion( 127 check_reference_completion(
128 "dont_render_function_parens_in_use_item",
119 " 129 "
120 //- /lib.rs 130 //- /lib.rs
121 mod m { pub fn foo() {} } 131 mod m { pub fn foo() {} }
122 use crate::m::f<|>; 132 use crate::m::f<|>;
123 ", 133 ",
124 "foo",
125 ) 134 )
126 } 135 }
127 136
128 #[test] 137 #[test]
129 fn dont_render_function_parens_if_already_call() { 138 fn dont_render_function_parens_if_already_call() {
130 check_reference_completion( 139 check_reference_completion(
140 "dont_render_function_parens_if_already_call",
131 " 141 "
132 //- /lib.rs 142 //- /lib.rs
133 fn frobnicate() {} 143 fn frobnicate() {}
@@ -135,7 +145,6 @@ mod tests {
135 frob<|>(); 145 frob<|>();
136 } 146 }
137 ", 147 ",
138 "main;frobnicate",
139 ) 148 )
140 } 149 }
141} 150}
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs
index 4276e47e8..20fc77f06 100644
--- a/crates/ra_ide_api/src/completion/complete_scope.rs
+++ b/crates/ra_ide_api/src/completion/complete_scope.rs
@@ -1,6 +1,5 @@
1use rustc_hash::FxHashSet; 1use rustc_hash::FxHashSet;
2use ra_syntax::{AstNode, TextUnit}; 2use ra_syntax::ast::AstNode;
3
4use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext}; 3use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext};
5 4
6pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { 5pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
@@ -13,7 +12,7 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
13 }; 12 };
14 if let Some(function) = &ctx.function { 13 if let Some(function) = &ctx.function {
15 let scopes = function.scopes(ctx.db); 14 let scopes = function.scopes(ctx.db);
16 complete_fn(acc, &scopes, ctx.offset); 15 complete_fn(acc, &scopes, ctx);
17 } 16 }
18 17
19 let module_scope = module.scope(ctx.db); 18 let module_scope = module.scope(ctx.db);
@@ -30,36 +29,50 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
30 } 29 }
31 }) 30 })
32 .for_each(|(name, res)| { 31 .for_each(|(name, res)| {
33 CompletionItem::new(CompletionKind::Reference, name.to_string()) 32 CompletionItem::new(
34 .from_resolution(ctx, res) 33 CompletionKind::Reference,
35 .add_to(acc) 34 ctx.source_range(),
35 name.to_string(),
36 )
37 .from_resolution(ctx, res)
38 .add_to(acc)
36 }); 39 });
37} 40}
38 41
39fn complete_fn(acc: &mut Completions, scopes: &hir::ScopesWithSyntaxMapping, offset: TextUnit) { 42fn complete_fn(
43 acc: &mut Completions,
44 scopes: &hir::ScopesWithSyntaxMapping,
45 ctx: &CompletionContext,
46) {
40 let mut shadowed = FxHashSet::default(); 47 let mut shadowed = FxHashSet::default();
41 scopes 48 scopes
42 .scope_chain_for_offset(offset) 49 .scope_chain_for_offset(ctx.offset)
43 .flat_map(|scope| scopes.scopes.entries(scope).iter()) 50 .flat_map(|scope| scopes.scopes.entries(scope).iter())
44 .filter(|entry| shadowed.insert(entry.name())) 51 .filter(|entry| shadowed.insert(entry.name()))
45 .for_each(|entry| { 52 .for_each(|entry| {
46 CompletionItem::new(CompletionKind::Reference, entry.name().to_string()) 53 CompletionItem::new(
47 .kind(CompletionItemKind::Binding) 54 CompletionKind::Reference,
48 .add_to(acc) 55 ctx.source_range(),
56 entry.name().to_string(),
57 )
58 .kind(CompletionItemKind::Binding)
59 .add_to(acc)
49 }); 60 });
50} 61}
51 62
52#[cfg(test)] 63#[cfg(test)]
53mod tests { 64mod tests {
54 use crate::completion::{CompletionKind, check_completion}; 65 use crate::completion::CompletionKind;
66 use crate::completion::completion_item::check_completion;
55 67
56 fn check_reference_completion(code: &str, expected_completions: &str) { 68 fn check_reference_completion(name: &str, code: &str) {
57 check_completion(code, expected_completions, CompletionKind::Reference); 69 check_completion(name, code, CompletionKind::Reference);
58 } 70 }
59 71
60 #[test] 72 #[test]
61 fn completes_bindings_from_let() { 73 fn completes_bindings_from_let() {
62 check_reference_completion( 74 check_reference_completion(
75 "bindings_from_let",
63 r" 76 r"
64 fn quux(x: i32) { 77 fn quux(x: i32) {
65 let y = 92; 78 let y = 92;
@@ -67,13 +80,13 @@ mod tests {
67 let z = (); 80 let z = ();
68 } 81 }
69 ", 82 ",
70 r#"y;x;quux "quux($0)""#,
71 ); 83 );
72 } 84 }
73 85
74 #[test] 86 #[test]
75 fn completes_bindings_from_if_let() { 87 fn completes_bindings_from_if_let() {
76 check_reference_completion( 88 check_reference_completion(
89 "bindings_from_if_let",
77 r" 90 r"
78 fn quux() { 91 fn quux() {
79 if let Some(x) = foo() { 92 if let Some(x) = foo() {
@@ -85,13 +98,13 @@ mod tests {
85 } 98 }
86 } 99 }
87 ", 100 ",
88 r#"b;a;quux "quux()$0""#,
89 ); 101 );
90 } 102 }
91 103
92 #[test] 104 #[test]
93 fn completes_bindings_from_for() { 105 fn completes_bindings_from_for() {
94 check_reference_completion( 106 check_reference_completion(
107 "bindings_from_for",
95 r" 108 r"
96 fn quux() { 109 fn quux() {
97 for x in &[1, 2, 3] { 110 for x in &[1, 2, 3] {
@@ -99,13 +112,13 @@ mod tests {
99 } 112 }
100 } 113 }
101 ", 114 ",
102 r#"x;quux "quux()$0""#,
103 ); 115 );
104 } 116 }
105 117
106 #[test] 118 #[test]
107 fn completes_module_items() { 119 fn completes_module_items() {
108 check_reference_completion( 120 check_reference_completion(
121 "module_items",
109 r" 122 r"
110 struct Foo; 123 struct Foo;
111 enum Baz {} 124 enum Baz {}
@@ -113,13 +126,13 @@ mod tests {
113 <|> 126 <|>
114 } 127 }
115 ", 128 ",
116 r#"quux "quux()$0";Foo;Baz"#,
117 ); 129 );
118 } 130 }
119 131
120 #[test] 132 #[test]
121 fn completes_module_items_in_nested_modules() { 133 fn completes_module_items_in_nested_modules() {
122 check_reference_completion( 134 check_reference_completion(
135 "module_items_in_nested_modules",
123 r" 136 r"
124 struct Foo; 137 struct Foo;
125 mod m { 138 mod m {
@@ -127,24 +140,24 @@ mod tests {
127 fn quux() { <|> } 140 fn quux() { <|> }
128 } 141 }
129 ", 142 ",
130 r#"quux "quux()$0";Bar"#,
131 ); 143 );
132 } 144 }
133 145
134 #[test] 146 #[test]
135 fn completes_return_type() { 147 fn completes_return_type() {
136 check_reference_completion( 148 check_reference_completion(
149 "return_type",
137 r" 150 r"
138 struct Foo; 151 struct Foo;
139 fn x() -> <|> 152 fn x() -> <|>
140 ", 153 ",
141 r#"Foo;x "x()$0""#,
142 ) 154 )
143 } 155 }
144 156
145 #[test] 157 #[test]
146 fn dont_show_both_completions_for_shadowing() { 158 fn dont_show_both_completions_for_shadowing() {
147 check_reference_completion( 159 check_reference_completion(
160 "dont_show_both_completions_for_shadowing",
148 r" 161 r"
149 fn foo() -> { 162 fn foo() -> {
150 let bar = 92; 163 let bar = 92;
@@ -154,32 +167,29 @@ mod tests {
154 } 167 }
155 } 168 }
156 ", 169 ",
157 r#"bar;foo "foo()$0""#,
158 ) 170 )
159 } 171 }
160 172
161 #[test] 173 #[test]
162 fn completes_self_in_methods() { 174 fn completes_self_in_methods() {
163 check_reference_completion(r"impl S { fn foo(&self) { <|> } }", "self") 175 check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }")
164 } 176 }
165 177
166 #[test] 178 #[test]
167 fn inserts_parens_for_function_calls() { 179 fn inserts_parens_for_function_calls() {
168 check_reference_completion( 180 check_reference_completion(
181 "inserts_parens_for_function_calls1",
169 r" 182 r"
170 fn no_args() {} 183 fn no_args() {}
171 fn main() { no_<|> } 184 fn main() { no_<|> }
172 ", 185 ",
173 r#"no_args "no_args()$0"
174 main "main()$0""#,
175 ); 186 );
176 check_reference_completion( 187 check_reference_completion(
188 "inserts_parens_for_function_calls2",
177 r" 189 r"
178 fn with_args(x: i32, y: String) {} 190 fn with_args(x: i32, y: String) {}
179 fn main() { with_<|> } 191 fn main() { with_<|> }
180 ", 192 ",
181 r#"main "main()$0"
182 with_args "with_args($0)""#,
183 ); 193 );
184 } 194 }
185} 195}
diff --git a/crates/ra_ide_api/src/completion/complete_snippet.rs b/crates/ra_ide_api/src/completion/complete_snippet.rs
index a495751dd..d3344b865 100644
--- a/crates/ra_ide_api/src/completion/complete_snippet.rs
+++ b/crates/ra_ide_api/src/completion/complete_snippet.rs
@@ -1,7 +1,7 @@
1use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionItemKind, CompletionContext, completion_item::Builder}; 1use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionItemKind, CompletionContext, completion_item::Builder};
2 2
3fn snippet(label: &str, snippet: &str) -> Builder { 3fn snippet(ctx: &CompletionContext, label: &str, snippet: &str) -> Builder {
4 CompletionItem::new(CompletionKind::Snippet, label) 4 CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), label)
5 .snippet(snippet) 5 .snippet(snippet)
6 .kind(CompletionItemKind::Snippet) 6 .kind(CompletionItemKind::Snippet)
7} 7}
@@ -10,8 +10,8 @@ pub(super) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionConte
10 if !(ctx.is_trivial_path && ctx.function_syntax.is_some()) { 10 if !(ctx.is_trivial_path && ctx.function_syntax.is_some()) {
11 return; 11 return;
12 } 12 }
13 snippet("pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc); 13 snippet(ctx, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc);
14 snippet("ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc); 14 snippet(ctx, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc);
15} 15}
16 16
17pub(super) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) { 17pub(super) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) {
@@ -19,6 +19,7 @@ pub(super) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionConte
19 return; 19 return;
20 } 20 }
21 snippet( 21 snippet(
22 ctx,
22 "Test function", 23 "Test function",
23 "\ 24 "\
24#[test] 25#[test]
@@ -29,45 +30,33 @@ fn ${1:feature}() {
29 .lookup_by("tfn") 30 .lookup_by("tfn")
30 .add_to(acc); 31 .add_to(acc);
31 32
32 snippet("pub(crate)", "pub(crate) $0").add_to(acc); 33 snippet(ctx, "pub(crate)", "pub(crate) $0").add_to(acc);
33} 34}
34 35
35#[cfg(test)] 36#[cfg(test)]
36mod tests { 37mod tests {
37 use crate::completion::{CompletionKind, check_completion}; 38 use crate::completion::CompletionKind;
38 fn check_snippet_completion(code: &str, expected_completions: &str) { 39 use crate::completion::completion_item::check_completion;
39 check_completion(code, expected_completions, CompletionKind::Snippet); 40
41 fn check_snippet_completion(name: &str, code: &str) {
42 check_completion(name, code, CompletionKind::Snippet);
40 } 43 }
41 44
42 #[test] 45 #[test]
43 fn completes_snippets_in_expressions() { 46 fn completes_snippets_in_expressions() {
44 check_snippet_completion( 47 check_snippet_completion("snippets_in_expressions", r"fn foo(x: i32) { <|> }");
45 r"fn foo(x: i32) { <|> }",
46 r##"
47 pd "eprintln!(\"$0 = {:?}\", $0);"
48 ppd "eprintln!(\"$0 = {:#?}\", $0);"
49 "##,
50 );
51 } 48 }
52 49
53 #[test] 50 #[test]
54 fn completes_snippets_in_items() { 51 fn completes_snippets_in_items() {
55 // check_snippet_completion(r"
56 // <|>
57 // ",
58 // r##"[CompletionItem { label: "Test function", lookup: None, snippet: Some("#[test]\nfn test_${1:feature}() {\n$0\n}"##,
59 // );
60 check_snippet_completion( 52 check_snippet_completion(
53 "snippets_in_items",
61 r" 54 r"
62 #[cfg(test)] 55 #[cfg(test)]
63 mod tests { 56 mod tests {
64 <|> 57 <|>
65 } 58 }
66 ", 59 ",
67 r##"
68 tfn "Test function" "#[test]\nfn ${1:feature}() {\n $0\n}"
69 pub(crate) "pub(crate) $0"
70 "##,
71 ); 60 );
72 } 61 }
73} 62}
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs
index e537e0082..b09c66c18 100644
--- a/crates/ra_ide_api/src/completion/completion_context.rs
+++ b/crates/ra_ide_api/src/completion/completion_context.rs
@@ -12,7 +12,7 @@ use crate::{db, FilePosition};
12/// `CompletionContext` is created early during completion to figure out, where 12/// `CompletionContext` is created early during completion to figure out, where
13/// exactly is the cursor, syntax-wise. 13/// exactly is the cursor, syntax-wise.
14#[derive(Debug)] 14#[derive(Debug)]
15pub(super) struct CompletionContext<'a> { 15pub(crate) struct CompletionContext<'a> {
16 pub(super) db: &'a db::RootDatabase, 16 pub(super) db: &'a db::RootDatabase,
17 pub(super) offset: TextUnit, 17 pub(super) offset: TextUnit,
18 pub(super) leaf: &'a SyntaxNode, 18 pub(super) leaf: &'a SyntaxNode,
@@ -65,6 +65,17 @@ impl<'a> CompletionContext<'a> {
65 Some(ctx) 65 Some(ctx)
66 } 66 }
67 67
68 // The range of the identifier that is being completed.
69 // This is purely advisory and can be used, for example, to highlight this range in the editor.
70 // Clients are expected to ignore this field.
71 pub(crate) fn source_range(&self) -> TextRange {
72 match self.leaf.kind() {
73 // workaroud when completion is triggered by trigger characters.
74 DOT | COLONCOLON => TextRange::from_to(self.offset, self.offset),
75 _ => self.leaf.range(),
76 }
77 }
78
68 fn fill(&mut self, original_file: &'a SourceFile, offset: TextUnit) { 79 fn fill(&mut self, original_file: &'a SourceFile, offset: TextUnit) {
69 // Insert a fake ident to get a valid parse tree. We will use this file 80 // Insert a fake ident to get a valid parse tree. We will use this file
70 // to determine context, though the original_file will be used for 81 // to determine context, though the original_file will be used for
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs
index 11d00f78c..f46d9e581 100644
--- a/crates/ra_ide_api/src/completion/completion_item.rs
+++ b/crates/ra_ide_api/src/completion/completion_item.rs
@@ -1,6 +1,8 @@
1use hir::PerNs; 1use hir::PerNs;
2 2
3use crate::completion::CompletionContext; 3use crate::completion::completion_context::CompletionContext;
4use ra_syntax::TextRange;
5use ra_text_edit::TextEdit;
4 6
5/// `CompletionItem` describes a single completion variant in the editor pop-up. 7/// `CompletionItem` describes a single completion variant in the editor pop-up.
6/// It is basically a POD with various properties. To construct a 8/// It is basically a POD with various properties. To construct a
@@ -11,15 +13,13 @@ pub struct CompletionItem {
11 /// completion. 13 /// completion.
12 completion_kind: CompletionKind, 14 completion_kind: CompletionKind,
13 label: String, 15 label: String,
16 kind: Option<CompletionItemKind>,
14 detail: Option<String>, 17 detail: Option<String>,
15 lookup: Option<String>, 18 lookup: Option<String>,
16 snippet: Option<String>, 19 insert_text: Option<String>,
17 kind: Option<CompletionItemKind>, 20 insert_text_format: InsertTextFormat,
18} 21 source_range: TextRange,
19 22 text_edit: Option<TextEdit>,
20pub enum InsertText {
21 PlainText { text: String },
22 Snippet { text: String },
23} 23}
24 24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)] 25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -40,7 +40,7 @@ pub enum CompletionItemKind {
40 Method, 40 Method,
41} 41}
42 42
43#[derive(Debug, PartialEq, Eq)] 43#[derive(Debug, PartialEq, Eq, Copy, Clone)]
44pub(crate) enum CompletionKind { 44pub(crate) enum CompletionKind {
45 /// Parser-based keyword completion. 45 /// Parser-based keyword completion.
46 Keyword, 46 Keyword,
@@ -51,16 +51,29 @@ pub(crate) enum CompletionKind {
51 Snippet, 51 Snippet,
52} 52}
53 53
54#[derive(Debug, PartialEq, Eq, Copy, Clone)]
55pub enum InsertTextFormat {
56 PlainText,
57 Snippet,
58}
59
54impl CompletionItem { 60impl CompletionItem {
55 pub(crate) fn new(completion_kind: CompletionKind, label: impl Into<String>) -> Builder { 61 pub(crate) fn new(
62 completion_kind: CompletionKind,
63 replace_range: TextRange,
64 label: impl Into<String>,
65 ) -> Builder {
56 let label = label.into(); 66 let label = label.into();
57 Builder { 67 Builder {
68 source_range: replace_range,
58 completion_kind, 69 completion_kind,
59 label, 70 label,
71 insert_text: None,
72 insert_text_format: InsertTextFormat::PlainText,
60 detail: None, 73 detail: None,
61 lookup: None, 74 lookup: None,
62 snippet: None,
63 kind: None, 75 kind: None,
76 text_edit: None,
64 } 77 }
65 } 78 }
66 /// What user sees in pop-up in the UI. 79 /// What user sees in pop-up in the UI.
@@ -78,30 +91,39 @@ impl CompletionItem {
78 .map(|it| it.as_str()) 91 .map(|it| it.as_str())
79 .unwrap_or(self.label()) 92 .unwrap_or(self.label())
80 } 93 }
81 /// What is inserted. 94
82 pub fn insert_text(&self) -> InsertText { 95 pub fn insert_text_format(&self) -> InsertTextFormat {
83 match &self.snippet { 96 self.insert_text_format.clone()
84 None => InsertText::PlainText { 97 }
85 text: self.label.clone(), 98 pub fn insert_text(&self) -> String {
86 }, 99 match &self.insert_text {
87 Some(it) => InsertText::Snippet { text: it.clone() }, 100 Some(t) => t.clone(),
101 None => self.label.clone(),
88 } 102 }
89 } 103 }
90
91 pub fn kind(&self) -> Option<CompletionItemKind> { 104 pub fn kind(&self) -> Option<CompletionItemKind> {
92 self.kind 105 self.kind
93 } 106 }
107 pub fn take_text_edit(&mut self) -> Option<TextEdit> {
108 self.text_edit.take()
109 }
110 pub fn source_range(&self) -> TextRange {
111 self.source_range
112 }
94} 113}
95 114
96/// A helper to make `CompletionItem`s. 115/// A helper to make `CompletionItem`s.
97#[must_use] 116#[must_use]
98pub(crate) struct Builder { 117pub(crate) struct Builder {
118 source_range: TextRange,
99 completion_kind: CompletionKind, 119 completion_kind: CompletionKind,
100 label: String, 120 label: String,
121 insert_text: Option<String>,
122 insert_text_format: InsertTextFormat,
101 detail: Option<String>, 123 detail: Option<String>,
102 lookup: Option<String>, 124 lookup: Option<String>,
103 snippet: Option<String>,
104 kind: Option<CompletionItemKind>, 125 kind: Option<CompletionItemKind>,
126 text_edit: Option<TextEdit>,
105} 127}
106 128
107impl Builder { 129impl Builder {
@@ -111,27 +133,44 @@ impl Builder {
111 133
112 pub(crate) fn build(self) -> CompletionItem { 134 pub(crate) fn build(self) -> CompletionItem {
113 CompletionItem { 135 CompletionItem {
136 source_range: self.source_range,
114 label: self.label, 137 label: self.label,
115 detail: self.detail, 138 detail: self.detail,
139 insert_text_format: self.insert_text_format,
116 lookup: self.lookup, 140 lookup: self.lookup,
117 snippet: self.snippet,
118 kind: self.kind, 141 kind: self.kind,
119 completion_kind: self.completion_kind, 142 completion_kind: self.completion_kind,
143 text_edit: self.text_edit,
144 insert_text: self.insert_text,
120 } 145 }
121 } 146 }
122 pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder { 147 pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder {
123 self.lookup = Some(lookup.into()); 148 self.lookup = Some(lookup.into());
124 self 149 self
125 } 150 }
126 pub(crate) fn snippet(mut self, snippet: impl Into<String>) -> Builder { 151 pub(crate) fn insert_text(mut self, insert_text: impl Into<String>) -> Builder {
127 self.snippet = Some(snippet.into()); 152 self.insert_text = Some(insert_text.into());
153 self
154 }
155 #[allow(unused)]
156 pub(crate) fn insert_text_format(mut self, insert_text_format: InsertTextFormat) -> Builder {
157 self.insert_text_format = insert_text_format;
128 self 158 self
129 } 159 }
160 pub(crate) fn snippet(mut self, snippet: impl Into<String>) -> Builder {
161 self.insert_text_format = InsertTextFormat::Snippet;
162 self.insert_text(snippet)
163 }
130 pub(crate) fn kind(mut self, kind: CompletionItemKind) -> Builder { 164 pub(crate) fn kind(mut self, kind: CompletionItemKind) -> Builder {
131 self.kind = Some(kind); 165 self.kind = Some(kind);
132 self 166 self
133 } 167 }
134 #[allow(unused)] 168 #[allow(unused)]
169 pub(crate) fn text_edit(mut self, edit: TextEdit) -> Builder {
170 self.text_edit = Some(edit);
171 self
172 }
173 #[allow(unused)]
135 pub(crate) fn detail(self, detail: impl Into<String>) -> Builder { 174 pub(crate) fn detail(self, detail: impl Into<String>) -> Builder {
136 self.set_detail(Some(detail)) 175 self.set_detail(Some(detail))
137 } 176 }
@@ -192,17 +231,18 @@ impl Builder {
192 // If not an import, add parenthesis automatically. 231 // If not an import, add parenthesis automatically.
193 if ctx.use_item_syntax.is_none() && !ctx.is_call { 232 if ctx.use_item_syntax.is_none() && !ctx.is_call {
194 if function.signature(ctx.db).params().is_empty() { 233 if function.signature(ctx.db).params().is_empty() {
195 self.snippet = Some(format!("{}()$0", self.label)); 234 self.insert_text = Some(format!("{}()$0", self.label));
196 } else { 235 } else {
197 self.snippet = Some(format!("{}($0)", self.label)); 236 self.insert_text = Some(format!("{}($0)", self.label));
198 } 237 }
238 self.insert_text_format = InsertTextFormat::Snippet;
199 } 239 }
200 self.kind = Some(CompletionItemKind::Function); 240 self.kind = Some(CompletionItemKind::Function);
201 self 241 self
202 } 242 }
203} 243}
204 244
205impl Into<CompletionItem> for Builder { 245impl<'a> Into<CompletionItem> for Builder {
206 fn into(self) -> CompletionItem { 246 fn into(self) -> CompletionItem {
207 self.build() 247 self.build()
208 } 248 }
@@ -225,60 +265,6 @@ impl Completions {
225 { 265 {
226 items.into_iter().for_each(|item| self.add(item.into())) 266 items.into_iter().for_each(|item| self.add(item.into()))
227 } 267 }
228
229 #[cfg(test)]
230 pub(crate) fn assert_match(&self, expected: &str, kind: CompletionKind) {
231 let expected = normalize(expected);
232 let actual = self.debug_render(kind);
233 test_utils::assert_eq_text!(expected.as_str(), actual.as_str(),);
234
235 /// Normalize the textual representation of `Completions`:
236 /// replace `;` with newlines, normalize whitespace
237 fn normalize(expected: &str) -> String {
238 use ra_syntax::{tokenize, TextUnit, TextRange, SyntaxKind::SEMI};
239 let mut res = String::new();
240 for line in expected.trim().lines() {
241 let line = line.trim();
242 let mut start_offset: TextUnit = 0.into();
243 // Yep, we use rust tokenize in completion tests :-)
244 for token in tokenize(line) {
245 let range = TextRange::offset_len(start_offset, token.len);
246 start_offset += token.len;
247 if token.kind == SEMI {
248 res.push('\n');
249 } else {
250 res.push_str(&line[range]);
251 }
252 }
253
254 res.push('\n');
255 }
256 res
257 }
258 }
259
260 #[cfg(test)]
261 fn debug_render(&self, kind: CompletionKind) -> String {
262 let mut res = String::new();
263 for c in self.buf.iter() {
264 if c.completion_kind == kind {
265 if let Some(lookup) = &c.lookup {
266 res.push_str(lookup);
267 res.push_str(&format!(" {:?}", c.label));
268 } else {
269 res.push_str(&c.label);
270 }
271 if let Some(detail) = &c.detail {
272 res.push_str(&format!(" {:?}", detail));
273 }
274 if let Some(snippet) = &c.snippet {
275 res.push_str(&format!(" {:?}", snippet));
276 }
277 res.push('\n');
278 }
279 }
280 res
281 }
282} 268}
283 269
284impl Into<Vec<CompletionItem>> for Completions { 270impl Into<Vec<CompletionItem>> for Completions {
@@ -286,3 +272,22 @@ impl Into<Vec<CompletionItem>> for Completions {
286 self.buf 272 self.buf
287 } 273 }
288} 274}
275
276#[cfg(test)]
277pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind) {
278 use crate::mock_analysis::{single_file_with_position, analysis_and_position};
279 use crate::completion::completions;
280 use insta::assert_debug_snapshot_matches;
281 let (analysis, position) = if code.contains("//-") {
282 analysis_and_position(code)
283 } else {
284 single_file_with_position(code)
285 };
286 let completions = completions(&analysis.db, position).unwrap();
287 let completion_items: Vec<CompletionItem> = completions.into();
288 let kind_completions: Vec<CompletionItem> = completion_items
289 .into_iter()
290 .filter(|c| c.completion_kind == kind)
291 .collect();
292 assert_debug_snapshot_matches!(test_name, kind_completions);
293}
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap
new file mode 100644
index 000000000..132048d9c
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_for.snap
@@ -0,0 +1,34 @@
1Created: 2019-01-20T04:00:48.241096+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "x",
9 kind: Some(
10 Binding
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [62; 100),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Reference,
21 label: "quux",
22 kind: Some(
23 Function
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: Some(
28 "quux()$0"
29 ),
30 insert_text_format: Snippet,
31 source_range: [62; 100),
32 text_edit: None
33 }
34]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap
new file mode 100644
index 000000000..e7b628f19
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_if_let.snap
@@ -0,0 +1,47 @@
1Created: 2019-01-20T04:00:48.242456+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "b",
9 kind: Some(
10 Binding
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [213; 231),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Reference,
21 label: "a",
22 kind: Some(
23 Binding
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: None,
28 insert_text_format: PlainText,
29 source_range: [213; 231),
30 text_edit: None
31 },
32 CompletionItem {
33 completion_kind: Reference,
34 label: "quux",
35 kind: Some(
36 Function
37 ),
38 detail: None,
39 lookup: None,
40 insert_text: Some(
41 "quux()$0"
42 ),
43 insert_text_format: Snippet,
44 source_range: [213; 231),
45 text_edit: None
46 }
47]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap
new file mode 100644
index 000000000..403fe0c4c
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__bindings_from_let.snap
@@ -0,0 +1,47 @@
1Created: 2019-01-20T04:00:48.243016+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "y",
9 kind: Some(
10 Binding
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [78; 79),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Reference,
21 label: "x",
22 kind: Some(
23 Binding
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: None,
28 insert_text_format: PlainText,
29 source_range: [78; 79),
30 text_edit: None
31 },
32 CompletionItem {
33 completion_kind: Reference,
34 label: "quux",
35 kind: Some(
36 Function
37 ),
38 detail: None,
39 lookup: None,
40 insert_text: Some(
41 "quux($0)"
42 ),
43 insert_text_format: Snippet,
44 source_range: [78; 79),
45 text_edit: None
46 }
47]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops1.snap
new file mode 100644
index 000000000..413960191
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops1.snap
@@ -0,0 +1,111 @@
1Created: 2019-01-20T04:00:48.206357+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "if",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "if $0 {}"
16 ),
17 insert_text_format: Snippet,
18 source_range: [54; 56),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "match",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "match $0 {}"
31 ),
32 insert_text_format: Snippet,
33 source_range: [54; 56),
34 text_edit: None
35 },
36 CompletionItem {
37 completion_kind: Keyword,
38 label: "while",
39 kind: Some(
40 Keyword
41 ),
42 detail: None,
43 lookup: None,
44 insert_text: Some(
45 "while $0 {}"
46 ),
47 insert_text_format: Snippet,
48 source_range: [54; 56),
49 text_edit: None
50 },
51 CompletionItem {
52 completion_kind: Keyword,
53 label: "loop",
54 kind: Some(
55 Keyword
56 ),
57 detail: None,
58 lookup: None,
59 insert_text: Some(
60 "loop {$0}"
61 ),
62 insert_text_format: Snippet,
63 source_range: [54; 56),
64 text_edit: None
65 },
66 CompletionItem {
67 completion_kind: Keyword,
68 label: "continue",
69 kind: Some(
70 Keyword
71 ),
72 detail: None,
73 lookup: None,
74 insert_text: Some(
75 "continue;"
76 ),
77 insert_text_format: Snippet,
78 source_range: [54; 56),
79 text_edit: None
80 },
81 CompletionItem {
82 completion_kind: Keyword,
83 label: "break",
84 kind: Some(
85 Keyword
86 ),
87 detail: None,
88 lookup: None,
89 insert_text: Some(
90 "break;"
91 ),
92 insert_text_format: Snippet,
93 source_range: [54; 56),
94 text_edit: None
95 },
96 CompletionItem {
97 completion_kind: Keyword,
98 label: "return",
99 kind: Some(
100 Keyword
101 ),
102 detail: None,
103 lookup: None,
104 insert_text: Some(
105 "return $0;"
106 ),
107 insert_text_format: Snippet,
108 source_range: [54; 56),
109 text_edit: None
110 }
111]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops2.snap
new file mode 100644
index 000000000..dc2fc95e3
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__completes_break_and_continue_in_loops2.snap
@@ -0,0 +1,81 @@
1Created: 2019-01-20T04:00:48.217822+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "if",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "if $0 {}"
16 ),
17 insert_text_format: Snippet,
18 source_range: [59; 61),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "match",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "match $0 {}"
31 ),
32 insert_text_format: Snippet,
33 source_range: [59; 61),
34 text_edit: None
35 },
36 CompletionItem {
37 completion_kind: Keyword,
38 label: "while",
39 kind: Some(
40 Keyword
41 ),
42 detail: None,
43 lookup: None,
44 insert_text: Some(
45 "while $0 {}"
46 ),
47 insert_text_format: Snippet,
48 source_range: [59; 61),
49 text_edit: None
50 },
51 CompletionItem {
52 completion_kind: Keyword,
53 label: "loop",
54 kind: Some(
55 Keyword
56 ),
57 detail: None,
58 lookup: None,
59 insert_text: Some(
60 "loop {$0}"
61 ),
62 insert_text_format: Snippet,
63 source_range: [59; 61),
64 text_edit: None
65 },
66 CompletionItem {
67 completion_kind: Keyword,
68 label: "return",
69 kind: Some(
70 Keyword
71 ),
72 detail: None,
73 lookup: None,
74 insert_text: Some(
75 "return $0;"
76 ),
77 insert_text_format: Snippet,
78 source_range: [59; 61),
79 text_edit: None
80 }
81]
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__completion_postfix.snap
new file mode 100644
index 000000000..60b5a7424
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__completion_postfix.snap
@@ -0,0 +1,102 @@
1Created: 2019-01-19T13:50:41.824939+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_format: Snippet,
13 text_edit: Some(
14 AtomTextEdit {
15 delete: [78; 78),
16 insert: "!not"
17 }
18 ),
19 additional_text_edits: Some(
20 TextEdit {
21 atoms: [
22 AtomTextEdit {
23 delete: [72; 78),
24 insert: ""
25 }
26 ]
27 }
28 )
29 },
30 CompletionItem {
31 completion_kind: Postfix,
32 label: "if",
33 kind: None,
34 detail: None,
35 lookup: None,
36 insert_text_format: Snippet,
37 text_edit: Some(
38 AtomTextEdit {
39 delete: [78; 78),
40 insert: "if bar {$0}"
41 }
42 ),
43 additional_text_edits: Some(
44 TextEdit {
45 atoms: [
46 AtomTextEdit {
47 delete: [72; 78),
48 insert: ""
49 }
50 ]
51 }
52 )
53 },
54 CompletionItem {
55 completion_kind: Postfix,
56 label: "match",
57 kind: None,
58 detail: None,
59 lookup: None,
60 insert_text_format: Snippet,
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 {
69 atoms: [
70 AtomTextEdit {
71 delete: [72; 78),
72 insert: ""
73 }
74 ]
75 }
76 )
77 },
78 CompletionItem {
79 completion_kind: Postfix,
80 label: "while",
81 kind: None,
82 detail: None,
83 lookup: None,
84 insert_text_format: Snippet,
85 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 {
93 atoms: [
94 AtomTextEdit {
95 delete: [72; 78),
96 insert: ""
97 }
98 ]
99 }
100 )
101 }
102]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__deeply_nested_use_tree.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__deeply_nested_use_tree.snap
new file mode 100644
index 000000000..26ca18933
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__deeply_nested_use_tree.snap
@@ -0,0 +1,19 @@
1Created: 2019-01-20T04:00:48.217724+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "Spam",
9 kind: Some(
10 Struct
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [23; 25),
17 text_edit: None
18 }
19]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_add_semi_after_return_if_not_a_statement.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_add_semi_after_return_if_not_a_statement.snap
new file mode 100644
index 000000000..f5ae8c29f
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_add_semi_after_return_if_not_a_statement.snap
@@ -0,0 +1,81 @@
1Created: 2019-01-20T04:00:48.208392+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "if",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "if $0 {}"
16 ),
17 insert_text_format: Snippet,
18 source_range: [84; 102),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "match",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "match $0 {}"
31 ),
32 insert_text_format: Snippet,
33 source_range: [84; 102),
34 text_edit: None
35 },
36 CompletionItem {
37 completion_kind: Keyword,
38 label: "while",
39 kind: Some(
40 Keyword
41 ),
42 detail: None,
43 lookup: None,
44 insert_text: Some(
45 "while $0 {}"
46 ),
47 insert_text_format: Snippet,
48 source_range: [84; 102),
49 text_edit: None
50 },
51 CompletionItem {
52 completion_kind: Keyword,
53 label: "loop",
54 kind: Some(
55 Keyword
56 ),
57 detail: None,
58 lookup: None,
59 insert_text: Some(
60 "loop {$0}"
61 ),
62 insert_text_format: Snippet,
63 source_range: [84; 102),
64 text_edit: None
65 },
66 CompletionItem {
67 completion_kind: Keyword,
68 label: "return",
69 kind: Some(
70 Keyword
71 ),
72 detail: None,
73 lookup: None,
74 insert_text: Some(
75 "return $0"
76 ),
77 insert_text_format: Snippet,
78 source_range: [84; 102),
79 text_edit: None
80 }
81]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap
new file mode 100644
index 000000000..88c9287fd
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_if_already_call.snap
@@ -0,0 +1,32 @@
1Created: 2019-01-20T04:00:48.239872+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "main",
9 kind: Some(
10 Function
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [35; 39),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Reference,
21 label: "frobnicate",
22 kind: Some(
23 Function
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: None,
28 insert_text_format: PlainText,
29 source_range: [35; 39),
30 text_edit: None
31 }
32]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap
new file mode 100644
index 000000000..33286e68b
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_render_function_parens_in_use_item.snap
@@ -0,0 +1,19 @@
1Created: 2019-01-20T04:00:48.239894+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "foo",
9 kind: Some(
10 Function
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [40; 41),
17 text_edit: None
18 }
19]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap
new file mode 100644
index 000000000..2db0eb755
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__dont_show_both_completions_for_shadowing.snap
@@ -0,0 +1,34 @@
1Created: 2019-01-20T04:00:48.248606+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "bar",
9 kind: Some(
10 Binding
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [108; 146),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Reference,
21 label: "foo",
22 kind: Some(
23 Function
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: Some(
28 "foo()$0"
29 ),
30 insert_text_format: Snippet,
31 source_range: [108; 146),
32 text_edit: None
33 }
34]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap
new file mode 100644
index 000000000..7ae216cd2
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls1.snap
@@ -0,0 +1,36 @@
1Created: 2019-01-20T04:00:48.249349+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "no_args",
9 kind: Some(
10 Function
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "no_args()$0"
16 ),
17 insert_text_format: Snippet,
18 source_range: [53; 56),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Reference,
23 label: "main",
24 kind: Some(
25 Function
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "main()$0"
31 ),
32 insert_text_format: Snippet,
33 source_range: [53; 56),
34 text_edit: None
35 }
36]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap
new file mode 100644
index 000000000..231d75d7a
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__inserts_parens_for_function_calls2.snap
@@ -0,0 +1,36 @@
1Created: 2019-01-20T04:00:48.255317+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "main",
9 kind: Some(
10 Function
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "main()$0"
16 ),
17 insert_text_format: Snippet,
18 source_range: [72; 77),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Reference,
23 label: "with_args",
24 kind: Some(
25 Function
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "with_args($0)"
31 ),
32 insert_text_format: Snippet,
33 source_range: [72; 77),
34 text_edit: None
35 }
36]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function1.snap
new file mode 100644
index 000000000..4d309b20e
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function1.snap
@@ -0,0 +1,81 @@
1Created: 2019-01-20T04:00:48.207728+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "if",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "if $0 {}"
16 ),
17 insert_text_format: Snippet,
18 source_range: [24; 54),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "match",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "match $0 {}"
31 ),
32 insert_text_format: Snippet,
33 source_range: [24; 54),
34 text_edit: None
35 },
36 CompletionItem {
37 completion_kind: Keyword,
38 label: "while",
39 kind: Some(
40 Keyword
41 ),
42 detail: None,
43 lookup: None,
44 insert_text: Some(
45 "while $0 {}"
46 ),
47 insert_text_format: Snippet,
48 source_range: [24; 54),
49 text_edit: None
50 },
51 CompletionItem {
52 completion_kind: Keyword,
53 label: "loop",
54 kind: Some(
55 Keyword
56 ),
57 detail: None,
58 lookup: None,
59 insert_text: Some(
60 "loop {$0}"
61 ),
62 insert_text_format: Snippet,
63 source_range: [24; 54),
64 text_edit: None
65 },
66 CompletionItem {
67 completion_kind: Keyword,
68 label: "return",
69 kind: Some(
70 Keyword
71 ),
72 detail: None,
73 lookup: None,
74 insert_text: Some(
75 "return;"
76 ),
77 insert_text_format: Snippet,
78 source_range: [24; 54),
79 text_edit: None
80 }
81]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function2.snap
new file mode 100644
index 000000000..0f1e66ac3
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function2.snap
@@ -0,0 +1,111 @@
1Created: 2019-01-20T04:00:48.207381+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "if",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "if $0 {}"
16 ),
17 insert_text_format: Snippet,
18 source_range: [91; 105),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "match",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "match $0 {}"
31 ),
32 insert_text_format: Snippet,
33 source_range: [91; 105),
34 text_edit: None
35 },
36 CompletionItem {
37 completion_kind: Keyword,
38 label: "while",
39 kind: Some(
40 Keyword
41 ),
42 detail: None,
43 lookup: None,
44 insert_text: Some(
45 "while $0 {}"
46 ),
47 insert_text_format: Snippet,
48 source_range: [91; 105),
49 text_edit: None
50 },
51 CompletionItem {
52 completion_kind: Keyword,
53 label: "loop",
54 kind: Some(
55 Keyword
56 ),
57 detail: None,
58 lookup: None,
59 insert_text: Some(
60 "loop {$0}"
61 ),
62 insert_text_format: Snippet,
63 source_range: [91; 105),
64 text_edit: None
65 },
66 CompletionItem {
67 completion_kind: Keyword,
68 label: "else",
69 kind: Some(
70 Keyword
71 ),
72 detail: None,
73 lookup: None,
74 insert_text: Some(
75 "else {$0}"
76 ),
77 insert_text_format: Snippet,
78 source_range: [91; 105),
79 text_edit: None
80 },
81 CompletionItem {
82 completion_kind: Keyword,
83 label: "else if",
84 kind: Some(
85 Keyword
86 ),
87 detail: None,
88 lookup: None,
89 insert_text: Some(
90 "else if $0 {}"
91 ),
92 insert_text_format: Snippet,
93 source_range: [91; 105),
94 text_edit: None
95 },
96 CompletionItem {
97 completion_kind: Keyword,
98 label: "return",
99 kind: Some(
100 Keyword
101 ),
102 detail: None,
103 lookup: None,
104 insert_text: Some(
105 "return;"
106 ),
107 insert_text_format: Snippet,
108 source_range: [91; 105),
109 text_edit: None
110 }
111]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function3.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function3.snap
new file mode 100644
index 000000000..25c29dc18
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function3.snap
@@ -0,0 +1,81 @@
1Created: 2019-01-20T04:00:48.211090+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "if",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "if $0 {}"
16 ),
17 insert_text_format: Snippet,
18 source_range: [31; 65),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "match",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "match $0 {}"
31 ),
32 insert_text_format: Snippet,
33 source_range: [31; 65),
34 text_edit: None
35 },
36 CompletionItem {
37 completion_kind: Keyword,
38 label: "while",
39 kind: Some(
40 Keyword
41 ),
42 detail: None,
43 lookup: None,
44 insert_text: Some(
45 "while $0 {}"
46 ),
47 insert_text_format: Snippet,
48 source_range: [31; 65),
49 text_edit: None
50 },
51 CompletionItem {
52 completion_kind: Keyword,
53 label: "loop",
54 kind: Some(
55 Keyword
56 ),
57 detail: None,
58 lookup: None,
59 insert_text: Some(
60 "loop {$0}"
61 ),
62 insert_text_format: Snippet,
63 source_range: [31; 65),
64 text_edit: None
65 },
66 CompletionItem {
67 completion_kind: Keyword,
68 label: "return",
69 kind: Some(
70 Keyword
71 ),
72 detail: None,
73 lookup: None,
74 insert_text: Some(
75 "return $0;"
76 ),
77 insert_text_format: Snippet,
78 source_range: [31; 65),
79 text_edit: None
80 }
81]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function4.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function4.snap
new file mode 100644
index 000000000..7e43be4b0
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_function4.snap
@@ -0,0 +1,81 @@
1Created: 2019-01-20T04:00:48.218272+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "if",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "if $0 {}"
16 ),
17 insert_text_format: Snippet,
18 source_range: [24; 58),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "match",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "match $0 {}"
31 ),
32 insert_text_format: Snippet,
33 source_range: [24; 58),
34 text_edit: None
35 },
36 CompletionItem {
37 completion_kind: Keyword,
38 label: "while",
39 kind: Some(
40 Keyword
41 ),
42 detail: None,
43 lookup: None,
44 insert_text: Some(
45 "while $0 {}"
46 ),
47 insert_text_format: Snippet,
48 source_range: [24; 58),
49 text_edit: None
50 },
51 CompletionItem {
52 completion_kind: Keyword,
53 label: "loop",
54 kind: Some(
55 Keyword
56 ),
57 detail: None,
58 lookup: None,
59 insert_text: Some(
60 "loop {$0}"
61 ),
62 insert_text_format: Snippet,
63 source_range: [24; 58),
64 text_edit: None
65 },
66 CompletionItem {
67 completion_kind: Keyword,
68 label: "return",
69 kind: Some(
70 Keyword
71 ),
72 detail: None,
73 lookup: None,
74 insert_text: Some(
75 "return;"
76 ),
77 insert_text_format: Snippet,
78 source_range: [24; 58),
79 text_edit: None
80 }
81]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt1.snap
new file mode 100644
index 000000000..7ed890b74
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt1.snap
@@ -0,0 +1,49 @@
1Created: 2019-01-20T04:00:48.207433+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "crate",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "crate::"
16 ),
17 insert_text_format: PlainText,
18 source_range: [16; 30),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "self",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: None,
30 insert_text_format: PlainText,
31 source_range: [16; 30),
32 text_edit: None
33 },
34 CompletionItem {
35 completion_kind: Keyword,
36 label: "super",
37 kind: Some(
38 Keyword
39 ),
40 detail: None,
41 lookup: None,
42 insert_text: Some(
43 "super::"
44 ),
45 insert_text_format: PlainText,
46 source_range: [16; 30),
47 text_edit: None
48 }
49]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt2.snap
new file mode 100644
index 000000000..4d4c7af50
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt2.snap
@@ -0,0 +1,34 @@
1Created: 2019-01-20T09:26:20.872623+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "self",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [20; 20),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Keyword,
21 label: "super",
22 kind: Some(
23 Keyword
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: Some(
28 "super::"
29 ),
30 insert_text_format: PlainText,
31 source_range: [20; 20),
32 text_edit: None
33 }
34]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt3.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt3.snap
new file mode 100644
index 000000000..66ab20f41
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__keywords_in_use_stmt3.snap
@@ -0,0 +1,34 @@
1Created: 2019-01-20T04:00:48.217815+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "self",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [23; 24),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Keyword,
21 label: "super",
22 kind: Some(
23 Keyword
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: Some(
28 "super::"
29 ),
30 insert_text_format: PlainText,
31 source_range: [23; 24),
32 text_edit: None
33 }
34]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi1.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi1.snap
new file mode 100644
index 000000000..2dc47e9b1
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi1.snap
@@ -0,0 +1,81 @@
1Created: 2019-01-20T04:00:48.208669+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "if",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "if $0 {}"
16 ),
17 insert_text_format: Snippet,
18 source_range: [62; 100),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "match",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "match $0 {}"
31 ),
32 insert_text_format: Snippet,
33 source_range: [62; 100),
34 text_edit: None
35 },
36 CompletionItem {
37 completion_kind: Keyword,
38 label: "while",
39 kind: Some(
40 Keyword
41 ),
42 detail: None,
43 lookup: None,
44 insert_text: Some(
45 "while $0 {}"
46 ),
47 insert_text_format: Snippet,
48 source_range: [62; 100),
49 text_edit: None
50 },
51 CompletionItem {
52 completion_kind: Keyword,
53 label: "loop",
54 kind: Some(
55 Keyword
56 ),
57 detail: None,
58 lookup: None,
59 insert_text: Some(
60 "loop {$0}"
61 ),
62 insert_text_format: Snippet,
63 source_range: [62; 100),
64 text_edit: None
65 },
66 CompletionItem {
67 completion_kind: Keyword,
68 label: "return",
69 kind: Some(
70 Keyword
71 ),
72 detail: None,
73 lookup: None,
74 insert_text: Some(
75 "return $0;"
76 ),
77 insert_text_format: Snippet,
78 source_range: [62; 100),
79 text_edit: None
80 }
81]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi2.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi2.snap
new file mode 100644
index 000000000..59e11c585
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__last_return_in_block_has_semi2.snap
@@ -0,0 +1,81 @@
1Created: 2019-01-20T04:00:48.221138+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "if",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "if $0 {}"
16 ),
17 insert_text_format: Snippet,
18 source_range: [62; 100),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "match",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "match $0 {}"
31 ),
32 insert_text_format: Snippet,
33 source_range: [62; 100),
34 text_edit: None
35 },
36 CompletionItem {
37 completion_kind: Keyword,
38 label: "while",
39 kind: Some(
40 Keyword
41 ),
42 detail: None,
43 lookup: None,
44 insert_text: Some(
45 "while $0 {}"
46 ),
47 insert_text_format: Snippet,
48 source_range: [62; 100),
49 text_edit: None
50 },
51 CompletionItem {
52 completion_kind: Keyword,
53 label: "loop",
54 kind: Some(
55 Keyword
56 ),
57 detail: None,
58 lookup: None,
59 insert_text: Some(
60 "loop {$0}"
61 ),
62 insert_text_format: Snippet,
63 source_range: [62; 100),
64 text_edit: None
65 },
66 CompletionItem {
67 completion_kind: Keyword,
68 label: "return",
69 kind: Some(
70 Keyword
71 ),
72 detail: None,
73 lookup: None,
74 insert_text: Some(
75 "return $0;"
76 ),
77 insert_text_format: Snippet,
78 source_range: [62; 100),
79 text_edit: None
80 }
81]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__method_completion.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__method_completion.snap
new file mode 100644
index 000000000..966148a36
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__method_completion.snap
@@ -0,0 +1,21 @@
1Created: 2019-01-20T09:26:20.868112+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "the_method",
9 kind: Some(
10 Method
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "the_method($0)"
16 ),
17 insert_text_format: Snippet,
18 source_range: [144; 144),
19 text_edit: None
20 }
21]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap
new file mode 100644
index 000000000..9ebb8a357
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items.snap
@@ -0,0 +1,47 @@
1Created: 2019-01-20T04:00:48.243581+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "quux",
9 kind: Some(
10 Function
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "quux()$0"
16 ),
17 insert_text_format: Snippet,
18 source_range: [72; 102),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Reference,
23 label: "Foo",
24 kind: Some(
25 Struct
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: None,
30 insert_text_format: PlainText,
31 source_range: [72; 102),
32 text_edit: None
33 },
34 CompletionItem {
35 completion_kind: Reference,
36 label: "Baz",
37 kind: Some(
38 Enum
39 ),
40 detail: None,
41 lookup: None,
42 insert_text: None,
43 insert_text_format: PlainText,
44 source_range: [72; 102),
45 text_edit: None
46 }
47]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap
new file mode 100644
index 000000000..9b7aa0540
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__module_items_in_nested_modules.snap
@@ -0,0 +1,34 @@
1Created: 2019-01-20T04:00:48.244757+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "quux",
9 kind: Some(
10 Function
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "quux()$0"
16 ),
17 insert_text_format: Snippet,
18 source_range: [100; 102),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Reference,
23 label: "Bar",
24 kind: Some(
25 Struct
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: None,
30 insert_text_format: PlainText,
31 source_range: [100; 102),
32 text_edit: None
33 }
34]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__nested_use_tree.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__nested_use_tree.snap
new file mode 100644
index 000000000..555f7acc6
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__nested_use_tree.snap
@@ -0,0 +1,32 @@
1Created: 2019-01-20T04:00:48.222109+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "Spam",
9 kind: Some(
10 Struct
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [12; 14),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Reference,
21 label: "foo",
22 kind: Some(
23 Module
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: None,
28 insert_text_format: PlainText,
29 source_range: [12; 14),
30 text_edit: None
31 }
32]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__no_non_self_method.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__no_non_self_method.snap
new file mode 100644
index 000000000..417b692dc
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__no_non_self_method.snap
@@ -0,0 +1,5 @@
1Created: 2019-01-19T11:34:11.702251+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__no_semi_after_break_continue_in_expr.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__no_semi_after_break_continue_in_expr.snap
new file mode 100644
index 000000000..fd56a6c8c
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__no_semi_after_break_continue_in_expr.snap
@@ -0,0 +1,111 @@
1Created: 2019-01-20T04:00:48.209867+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Keyword,
8 label: "if",
9 kind: Some(
10 Keyword
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "if $0 {}"
16 ),
17 insert_text_format: Snippet,
18 source_range: [106; 108),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Keyword,
23 label: "match",
24 kind: Some(
25 Keyword
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "match $0 {}"
31 ),
32 insert_text_format: Snippet,
33 source_range: [106; 108),
34 text_edit: None
35 },
36 CompletionItem {
37 completion_kind: Keyword,
38 label: "while",
39 kind: Some(
40 Keyword
41 ),
42 detail: None,
43 lookup: None,
44 insert_text: Some(
45 "while $0 {}"
46 ),
47 insert_text_format: Snippet,
48 source_range: [106; 108),
49 text_edit: None
50 },
51 CompletionItem {
52 completion_kind: Keyword,
53 label: "loop",
54 kind: Some(
55 Keyword
56 ),
57 detail: None,
58 lookup: None,
59 insert_text: Some(
60 "loop {$0}"
61 ),
62 insert_text_format: Snippet,
63 source_range: [106; 108),
64 text_edit: None
65 },
66 CompletionItem {
67 completion_kind: Keyword,
68 label: "continue",
69 kind: Some(
70 Keyword
71 ),
72 detail: None,
73 lookup: None,
74 insert_text: Some(
75 "continue"
76 ),
77 insert_text_format: Snippet,
78 source_range: [106; 108),
79 text_edit: None
80 },
81 CompletionItem {
82 completion_kind: Keyword,
83 label: "break",
84 kind: Some(
85 Keyword
86 ),
87 detail: None,
88 lookup: None,
89 insert_text: Some(
90 "break"
91 ),
92 insert_text_format: Snippet,
93 source_range: [106; 108),
94 text_edit: None
95 },
96 CompletionItem {
97 completion_kind: Keyword,
98 label: "return",
99 kind: Some(
100 Keyword
101 ),
102 detail: None,
103 lookup: None,
104 insert_text: Some(
105 "return"
106 ),
107 insert_text_format: Snippet,
108 source_range: [106; 108),
109 text_edit: None
110 }
111]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__no_struct_field_completion_for_method_call.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__no_struct_field_completion_for_method_call.snap
new file mode 100644
index 000000000..0948c9fe6
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__no_struct_field_completion_for_method_call.snap
@@ -0,0 +1,5 @@
1Created: 2019-01-19T11:34:11.702201+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_last_param.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_last_param.snap
new file mode 100644
index 000000000..e0e5929ff
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_last_param.snap
@@ -0,0 +1,19 @@
1Created: 2019-01-20T04:00:48.203211+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Magic,
8 label: "file_id: FileId",
9 kind: None,
10 detail: None,
11 lookup: Some(
12 "file_id"
13 ),
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [98; 102),
17 text_edit: None
18 }
19]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_nth_param.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_nth_param.snap
new file mode 100644
index 000000000..2899cf98e
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_nth_param.snap
@@ -0,0 +1,19 @@
1Created: 2019-01-20T04:00:48.203236+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Magic,
8 label: "file_id: FileId",
9 kind: None,
10 detail: None,
11 lookup: Some(
12 "file_id"
13 ),
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [98; 102),
17 text_edit: None
18 }
19]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_trait_param.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_trait_param.snap
new file mode 100644
index 000000000..8a4d9ef63
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__param_completion_trait_param.snap
@@ -0,0 +1,19 @@
1Created: 2019-01-20T04:00:48.206552+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Magic,
8 label: "file_id: FileId",
9 kind: None,
10 detail: None,
11 lookup: Some(
12 "file_id"
13 ),
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [269; 273),
17 text_edit: None
18 }
19]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__reference_completion.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__reference_completion.snap
new file mode 100644
index 000000000..632d9bbc7
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__reference_completion.snap
@@ -0,0 +1,32 @@
1Created: 2019-01-20T09:26:20.899262+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "Foo",
9 kind: Some(
10 EnumVariant
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [47; 47),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Reference,
21 label: "Bar",
22 kind: Some(
23 EnumVariant
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: None,
28 insert_text_format: PlainText,
29 source_range: [47; 47),
30 text_edit: None
31 }
32]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap
new file mode 100644
index 000000000..6bef3ed95
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__return_type.snap
@@ -0,0 +1,34 @@
1Created: 2019-01-20T04:00:48.245820+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "Foo",
9 kind: Some(
10 Struct
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [46; 60),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Reference,
21 label: "x",
22 kind: Some(
23 Function
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: Some(
28 "x()$0"
29 ),
30 insert_text_format: Snippet,
31 source_range: [46; 60),
32 text_edit: None
33 }
34]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap
new file mode 100644
index 000000000..56bfe1b0d
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap
@@ -0,0 +1,19 @@
1Created: 2019-01-20T04:00:48.244260+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "self",
9 kind: Some(
10 Binding
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [24; 26),
17 text_edit: None
18 }
19]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap
new file mode 100644
index 000000000..648d7f189
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_expressions.snap
@@ -0,0 +1,36 @@
1Created: 2019-01-20T04:00:48.252281+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Snippet,
8 label: "pd",
9 kind: Some(
10 Snippet
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: Some(
15 "eprintln!(\"$0 = {:?}\", $0);"
16 ),
17 insert_text_format: Snippet,
18 source_range: [16; 18),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Snippet,
23 label: "ppd",
24 kind: Some(
25 Snippet
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "eprintln!(\"$0 = {:#?}\", $0);"
31 ),
32 insert_text_format: Snippet,
33 source_range: [16; 18),
34 text_edit: None
35 }
36]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap
new file mode 100644
index 000000000..f5d0140ea
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__snippets_in_items.snap
@@ -0,0 +1,38 @@
1Created: 2019-01-20T04:00:48.253073+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Snippet,
8 label: "Test function",
9 kind: Some(
10 Snippet
11 ),
12 detail: None,
13 lookup: Some(
14 "tfn"
15 ),
16 insert_text: Some(
17 "#[test]\nfn ${1:feature}() {\n $0\n}"
18 ),
19 insert_text_format: Snippet,
20 source_range: [49; 79),
21 text_edit: None
22 },
23 CompletionItem {
24 completion_kind: Snippet,
25 label: "pub(crate)",
26 kind: Some(
27 Snippet
28 ),
29 detail: None,
30 lookup: None,
31 insert_text: Some(
32 "pub(crate) $0"
33 ),
34 insert_text_format: Snippet,
35 source_range: [49; 79),
36 text_edit: None
37 }
38]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion.snap
new file mode 100644
index 000000000..c88ddbc67
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion.snap
@@ -0,0 +1,21 @@
1Created: 2019-01-20T09:26:20.868146+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "the_field",
9 kind: Some(
10 Field
11 ),
12 detail: Some(
13 "u32"
14 ),
15 lookup: None,
16 insert_text: None,
17 insert_text_format: PlainText,
18 source_range: [85; 85),
19 text_edit: None
20 }
21]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion_autoderef.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion_autoderef.snap
new file mode 100644
index 000000000..f310f523d
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion_autoderef.snap
@@ -0,0 +1,36 @@
1Created: 2019-01-20T09:26:20.868561+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "the_field",
9 kind: Some(
10 Field
11 ),
12 detail: Some(
13 "(u32, i32)"
14 ),
15 lookup: None,
16 insert_text: None,
17 insert_text_format: PlainText,
18 source_range: [126; 126),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Reference,
23 label: "foo",
24 kind: Some(
25 Method
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "foo($0)"
31 ),
32 insert_text_format: Snippet,
33 source_range: [126; 126),
34 text_edit: None
35 }
36]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion_self.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion_self.snap
new file mode 100644
index 000000000..4eae65128
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__struct_field_completion_self.snap
@@ -0,0 +1,36 @@
1Created: 2019-01-20T09:26:20.868333+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "the_field",
9 kind: Some(
10 Field
11 ),
12 detail: Some(
13 "(u32,)"
14 ),
15 lookup: None,
16 insert_text: None,
17 insert_text_format: PlainText,
18 source_range: [121; 121),
19 text_edit: None
20 },
21 CompletionItem {
22 completion_kind: Reference,
23 label: "foo",
24 kind: Some(
25 Method
26 ),
27 detail: None,
28 lookup: None,
29 insert_text: Some(
30 "foo($0)"
31 ),
32 insert_text_format: Snippet,
33 source_range: [121; 121),
34 text_edit: None
35 }
36]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_crate.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_crate.snap
new file mode 100644
index 000000000..29f7f86f1
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_crate.snap
@@ -0,0 +1,32 @@
1Created: 2019-01-20T04:00:48.223130+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "Spam",
9 kind: Some(
10 Struct
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [11; 13),
17 text_edit: None
18 },
19 CompletionItem {
20 completion_kind: Reference,
21 label: "foo",
22 kind: Some(
23 Module
24 ),
25 detail: None,
26 lookup: None,
27 insert_text: None,
28 insert_text_format: PlainText,
29 source_range: [11; 13),
30 text_edit: None
31 }
32]
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_self.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_self.snap
new file mode 100644
index 000000000..1a3bd8034
--- /dev/null
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__use_item_starting_with_self.snap
@@ -0,0 +1,19 @@
1Created: 2019-01-20T09:26:20.899584+00:00
2Creator: [email protected]
3Source: crates/ra_ide_api/src/completion/completion_item.rs
4
5[
6 CompletionItem {
7 completion_kind: Reference,
8 label: "Bar",
9 kind: Some(
10 Struct
11 ),
12 detail: None,
13 lookup: None,
14 insert_text: None,
15 insert_text_format: PlainText,
16 source_range: [26; 26),
17 text_edit: None
18 }
19]
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index 919d248e2..a09a8f926 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -43,7 +43,7 @@ use crate::{
43}; 43};
44 44
45pub use crate::{ 45pub use crate::{
46 completion::{CompletionItem, CompletionItemKind, InsertText}, 46 completion::{CompletionItem, CompletionItemKind, InsertTextFormat},
47 runnables::{Runnable, RunnableKind}, 47 runnables::{Runnable, RunnableKind},
48 navigation_target::NavigationTarget, 48 navigation_target::NavigationTarget,
49}; 49};
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index 6e187d49e..23b226fac 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -1,13 +1,13 @@
1use lsp_types::{ 1use lsp_types::{
2 self, CreateFile, DocumentChangeOperation, DocumentChanges, InsertTextFormat, Location, LocationLink, 2 self, CreateFile, DocumentChangeOperation, DocumentChanges, Location, LocationLink,
3 Position, Range, RenameFile, ResourceOp, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, 3 Position, Range, RenameFile, ResourceOp, SymbolKind, TextDocumentEdit, TextDocumentIdentifier,
4 TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, 4 TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier,
5 WorkspaceEdit, 5 WorkspaceEdit,
6}; 6};
7use ra_ide_api::{ 7use ra_ide_api::{
8 CompletionItem, CompletionItemKind, FileId, FilePosition, FileRange, FileSystemEdit, 8 CompletionItem, CompletionItemKind, FileId, FilePosition, FileRange, FileSystemEdit,
9 InsertText, NavigationTarget, SourceChange, SourceFileEdit, RangeInfo, 9 NavigationTarget, SourceChange, SourceFileEdit, RangeInfo,
10 LineCol, LineIndex, translate_offset_with_edit 10 LineCol, LineIndex, translate_offset_with_edit, InsertTextFormat
11}; 11};
12use ra_syntax::{SyntaxKind, TextRange, TextUnit}; 12use ra_syntax::{SyntaxKind, TextRange, TextUnit};
13use ra_text_edit::{AtomTextEdit, TextEdit}; 13use ra_text_edit::{AtomTextEdit, TextEdit};
@@ -74,27 +74,33 @@ impl Conv for CompletionItemKind {
74 } 74 }
75} 75}
76 76
77impl Conv for CompletionItem { 77impl ConvWith for CompletionItem {
78 type Ctx = LineIndex;
78 type Output = ::lsp_types::CompletionItem; 79 type Output = ::lsp_types::CompletionItem;
79 80
80 fn conv(self) -> <Self as Conv>::Output { 81 fn conv_with(mut self, ctx: &LineIndex) -> ::lsp_types::CompletionItem {
81 let mut res = ::lsp_types::CompletionItem { 82 let atom_text_edit = AtomTextEdit::replace(self.source_range(), self.insert_text());
83 let text_edit = (&atom_text_edit).conv_with(ctx);
84 let additional_text_edits = if let Some(edit) = self.take_text_edit() {
85 Some(edit.conv_with(ctx))
86 } else {
87 None
88 };
89
90 let mut res = lsp_types::CompletionItem {
82 label: self.label().to_string(), 91 label: self.label().to_string(),
83 detail: self.detail().map(|it| it.to_string()), 92 detail: self.detail().map(|it| it.to_string()),
84 filter_text: Some(self.lookup().to_string()), 93 filter_text: Some(self.lookup().to_string()),
85 kind: self.kind().map(|it| it.conv()), 94 kind: self.kind().map(|it| it.conv()),
95 text_edit: Some(text_edit),
96 additional_text_edits,
86 ..Default::default() 97 ..Default::default()
87 }; 98 };
88 match self.insert_text() { 99 res.insert_text_format = Some(match self.insert_text_format() {
89 InsertText::PlainText { text } => { 100 InsertTextFormat::Snippet => lsp_types::InsertTextFormat::Snippet,
90 res.insert_text = Some(text); 101 InsertTextFormat::PlainText => lsp_types::InsertTextFormat::PlainText,
91 res.insert_text_format = Some(InsertTextFormat::PlainText); 102 });
92 } 103
93 InsertText::Snippet { text } => {
94 res.insert_text = Some(text);
95 res.insert_text_format = Some(InsertTextFormat::Snippet);
96 }
97 }
98 res 104 res
99 } 105 }
100} 106}
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 02393f728..497f819be 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -340,7 +340,11 @@ pub fn handle_completion(
340 None => return Ok(None), 340 None => return Ok(None),
341 Some(items) => items, 341 Some(items) => items,
342 }; 342 };
343 let items = items.into_iter().map(|item| item.conv()).collect(); 343 let line_index = world.analysis().file_line_index(position.file_id);
344 let items = items
345 .into_iter()
346 .map(|item| item.conv_with(&line_index))
347 .collect();
344 348
345 Ok(Some(req::CompletionResponse::Array(items))) 349 Ok(Some(req::CompletionResponse::Array(items)))
346} 350}