diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/src/assist_config.rs | 27 | ||||
-rw-r--r-- | crates/ra_assists/src/assist_context.rs | 51 | ||||
-rw-r--r-- | crates/ra_assists/src/lib.rs | 15 | ||||
-rw-r--r-- | crates/ra_assists/src/tests.rs | 38 | ||||
-rw-r--r-- | crates/ra_ide/src/completion.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/test_utils.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/diagnostics.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/ra_ide/src/references/rename.rs | 3 | ||||
-rw-r--r-- | crates/ra_ide_db/src/source_change.rs | 5 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/analysis_bench.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 5 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop/handlers.rs | 6 |
13 files changed, 129 insertions, 39 deletions
diff --git a/crates/ra_assists/src/assist_config.rs b/crates/ra_assists/src/assist_config.rs new file mode 100644 index 000000000..c0a0226fb --- /dev/null +++ b/crates/ra_assists/src/assist_config.rs | |||
@@ -0,0 +1,27 @@ | |||
1 | //! Settings for tweaking assists. | ||
2 | //! | ||
3 | //! The fun thing here is `SnippetCap` -- this type can only be created in this | ||
4 | //! module, and we use to statically check that we only produce snippet | ||
5 | //! assists if we are allowed to. | ||
6 | |||
7 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
8 | pub struct AssistConfig { | ||
9 | pub snippet_cap: Option<SnippetCap>, | ||
10 | } | ||
11 | |||
12 | impl AssistConfig { | ||
13 | pub fn allow_snippets(&mut self, yes: bool) { | ||
14 | self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None } | ||
15 | } | ||
16 | } | ||
17 | |||
18 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] | ||
19 | pub struct SnippetCap { | ||
20 | _private: (), | ||
21 | } | ||
22 | |||
23 | impl Default for AssistConfig { | ||
24 | fn default() -> Self { | ||
25 | AssistConfig { snippet_cap: Some(SnippetCap { _private: () }) } | ||
26 | } | ||
27 | } | ||
diff --git a/crates/ra_assists/src/assist_context.rs b/crates/ra_assists/src/assist_context.rs index a680f752b..b90bbf8b2 100644 --- a/crates/ra_assists/src/assist_context.rs +++ b/crates/ra_assists/src/assist_context.rs | |||
@@ -15,7 +15,10 @@ use ra_syntax::{ | |||
15 | }; | 15 | }; |
16 | use ra_text_edit::TextEditBuilder; | 16 | use ra_text_edit::TextEditBuilder; |
17 | 17 | ||
18 | use crate::{Assist, AssistId, GroupLabel, ResolvedAssist}; | 18 | use crate::{ |
19 | assist_config::{AssistConfig, SnippetCap}, | ||
20 | Assist, AssistId, GroupLabel, ResolvedAssist, | ||
21 | }; | ||
19 | 22 | ||
20 | /// `AssistContext` allows to apply an assist or check if it could be applied. | 23 | /// `AssistContext` allows to apply an assist or check if it could be applied. |
21 | /// | 24 | /// |
@@ -48,6 +51,7 @@ use crate::{Assist, AssistId, GroupLabel, ResolvedAssist}; | |||
48 | /// moment, because the LSP API is pretty awkward in this place, and it's much | 51 | /// moment, because the LSP API is pretty awkward in this place, and it's much |
49 | /// easier to just compute the edit eagerly :-) | 52 | /// easier to just compute the edit eagerly :-) |
50 | pub(crate) struct AssistContext<'a> { | 53 | pub(crate) struct AssistContext<'a> { |
54 | pub(crate) config: &'a AssistConfig, | ||
51 | pub(crate) sema: Semantics<'a, RootDatabase>, | 55 | pub(crate) sema: Semantics<'a, RootDatabase>, |
52 | pub(crate) db: &'a RootDatabase, | 56 | pub(crate) db: &'a RootDatabase, |
53 | pub(crate) frange: FileRange, | 57 | pub(crate) frange: FileRange, |
@@ -55,10 +59,14 @@ pub(crate) struct AssistContext<'a> { | |||
55 | } | 59 | } |
56 | 60 | ||
57 | impl<'a> AssistContext<'a> { | 61 | impl<'a> AssistContext<'a> { |
58 | pub fn new(sema: Semantics<'a, RootDatabase>, frange: FileRange) -> AssistContext<'a> { | 62 | pub(crate) fn new( |
63 | sema: Semantics<'a, RootDatabase>, | ||
64 | config: &'a AssistConfig, | ||
65 | frange: FileRange, | ||
66 | ) -> AssistContext<'a> { | ||
59 | let source_file = sema.parse(frange.file_id); | 67 | let source_file = sema.parse(frange.file_id); |
60 | let db = sema.db; | 68 | let db = sema.db; |
61 | AssistContext { sema, db, frange, source_file } | 69 | AssistContext { config, sema, db, frange, source_file } |
62 | } | 70 | } |
63 | 71 | ||
64 | // NB, this ignores active selection. | 72 | // NB, this ignores active selection. |
@@ -165,11 +173,17 @@ pub(crate) struct AssistBuilder { | |||
165 | edit: TextEditBuilder, | 173 | edit: TextEditBuilder, |
166 | cursor_position: Option<TextSize>, | 174 | cursor_position: Option<TextSize>, |
167 | file: FileId, | 175 | file: FileId, |
176 | is_snippet: bool, | ||
168 | } | 177 | } |
169 | 178 | ||
170 | impl AssistBuilder { | 179 | impl AssistBuilder { |
171 | pub(crate) fn new(file: FileId) -> AssistBuilder { | 180 | pub(crate) fn new(file: FileId) -> AssistBuilder { |
172 | AssistBuilder { edit: TextEditBuilder::default(), cursor_position: None, file } | 181 | AssistBuilder { |
182 | edit: TextEditBuilder::default(), | ||
183 | cursor_position: None, | ||
184 | file, | ||
185 | is_snippet: false, | ||
186 | } | ||
173 | } | 187 | } |
174 | 188 | ||
175 | /// Remove specified `range` of text. | 189 | /// Remove specified `range` of text. |
@@ -180,10 +194,30 @@ impl AssistBuilder { | |||
180 | pub(crate) fn insert(&mut self, offset: TextSize, text: impl Into<String>) { | 194 | pub(crate) fn insert(&mut self, offset: TextSize, text: impl Into<String>) { |
181 | self.edit.insert(offset, text.into()) | 195 | self.edit.insert(offset, text.into()) |
182 | } | 196 | } |
197 | /// Append specified `text` at the given `offset` | ||
198 | pub(crate) fn insert_snippet( | ||
199 | &mut self, | ||
200 | _cap: SnippetCap, | ||
201 | offset: TextSize, | ||
202 | text: impl Into<String>, | ||
203 | ) { | ||
204 | self.is_snippet = true; | ||
205 | self.edit.insert(offset, text.into()) | ||
206 | } | ||
183 | /// Replaces specified `range` of text with a given string. | 207 | /// Replaces specified `range` of text with a given string. |
184 | pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) { | 208 | pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) { |
185 | self.edit.replace(range, replace_with.into()) | 209 | self.edit.replace(range, replace_with.into()) |
186 | } | 210 | } |
211 | /// Append specified `text` at the given `offset` | ||
212 | pub(crate) fn replace_snippet( | ||
213 | &mut self, | ||
214 | _cap: SnippetCap, | ||
215 | range: TextRange, | ||
216 | replace_with: impl Into<String>, | ||
217 | ) { | ||
218 | self.is_snippet = true; | ||
219 | self.edit.replace(range, replace_with.into()) | ||
220 | } | ||
187 | pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) { | 221 | pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) { |
188 | algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit) | 222 | algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit) |
189 | } | 223 | } |
@@ -227,7 +261,12 @@ impl AssistBuilder { | |||
227 | if edit.is_empty() && self.cursor_position.is_none() { | 261 | if edit.is_empty() && self.cursor_position.is_none() { |
228 | panic!("Only call `add_assist` if the assist can be applied") | 262 | panic!("Only call `add_assist` if the assist can be applied") |
229 | } | 263 | } |
230 | SingleFileChange { label: change_label, edit, cursor_position: self.cursor_position } | 264 | let mut res = |
231 | .into_source_change(self.file) | 265 | SingleFileChange { label: change_label, edit, cursor_position: self.cursor_position } |
266 | .into_source_change(self.file); | ||
267 | if self.is_snippet { | ||
268 | res.is_snippet = true; | ||
269 | } | ||
270 | res | ||
232 | } | 271 | } |
233 | } | 272 | } |
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs index b6dc7cb1b..7f0a723c9 100644 --- a/crates/ra_assists/src/lib.rs +++ b/crates/ra_assists/src/lib.rs | |||
@@ -10,6 +10,7 @@ macro_rules! eprintln { | |||
10 | ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; | 10 | ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; |
11 | } | 11 | } |
12 | 12 | ||
13 | mod assist_config; | ||
13 | mod assist_context; | 14 | mod assist_context; |
14 | mod marks; | 15 | mod marks; |
15 | #[cfg(test)] | 16 | #[cfg(test)] |
@@ -24,6 +25,8 @@ use ra_syntax::TextRange; | |||
24 | 25 | ||
25 | pub(crate) use crate::assist_context::{AssistContext, Assists}; | 26 | pub(crate) use crate::assist_context::{AssistContext, Assists}; |
26 | 27 | ||
28 | pub use assist_config::AssistConfig; | ||
29 | |||
27 | /// Unique identifier of the assist, should not be shown to the user | 30 | /// Unique identifier of the assist, should not be shown to the user |
28 | /// directly. | 31 | /// directly. |
29 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 32 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
@@ -54,9 +57,9 @@ impl Assist { | |||
54 | /// | 57 | /// |
55 | /// Assists are returned in the "unresolved" state, that is only labels are | 58 | /// Assists are returned in the "unresolved" state, that is only labels are |
56 | /// returned, without actual edits. | 59 | /// returned, without actual edits. |
57 | pub fn unresolved(db: &RootDatabase, range: FileRange) -> Vec<Assist> { | 60 | pub fn unresolved(db: &RootDatabase, config: &AssistConfig, range: FileRange) -> Vec<Assist> { |
58 | let sema = Semantics::new(db); | 61 | let sema = Semantics::new(db); |
59 | let ctx = AssistContext::new(sema, range); | 62 | let ctx = AssistContext::new(sema, config, range); |
60 | let mut acc = Assists::new_unresolved(&ctx); | 63 | let mut acc = Assists::new_unresolved(&ctx); |
61 | handlers::all().iter().for_each(|handler| { | 64 | handlers::all().iter().for_each(|handler| { |
62 | handler(&mut acc, &ctx); | 65 | handler(&mut acc, &ctx); |
@@ -68,9 +71,13 @@ impl Assist { | |||
68 | /// | 71 | /// |
69 | /// Assists are returned in the "resolved" state, that is with edit fully | 72 | /// Assists are returned in the "resolved" state, that is with edit fully |
70 | /// computed. | 73 | /// computed. |
71 | pub fn resolved(db: &RootDatabase, range: FileRange) -> Vec<ResolvedAssist> { | 74 | pub fn resolved( |
75 | db: &RootDatabase, | ||
76 | config: &AssistConfig, | ||
77 | range: FileRange, | ||
78 | ) -> Vec<ResolvedAssist> { | ||
72 | let sema = Semantics::new(db); | 79 | let sema = Semantics::new(db); |
73 | let ctx = AssistContext::new(sema, range); | 80 | let ctx = AssistContext::new(sema, config, range); |
74 | let mut acc = Assists::new_resolved(&ctx); | 81 | let mut acc = Assists::new_resolved(&ctx); |
75 | handlers::all().iter().for_each(|handler| { | 82 | handlers::all().iter().for_each(|handler| { |
76 | handler(&mut acc, &ctx); | 83 | handler(&mut acc, &ctx); |
diff --git a/crates/ra_assists/src/tests.rs b/crates/ra_assists/src/tests.rs index a3eacb8f1..9ba3da786 100644 --- a/crates/ra_assists/src/tests.rs +++ b/crates/ra_assists/src/tests.rs | |||
@@ -11,7 +11,7 @@ use test_utils::{ | |||
11 | RangeOrOffset, | 11 | RangeOrOffset, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | use crate::{handlers::Handler, Assist, AssistContext, Assists}; | 14 | use crate::{handlers::Handler, Assist, AssistConfig, AssistContext, Assists}; |
15 | 15 | ||
16 | pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) { | 16 | pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) { |
17 | let (mut db, file_id) = RootDatabase::with_single_file(text); | 17 | let (mut db, file_id) = RootDatabase::with_single_file(text); |
@@ -41,14 +41,14 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) { | |||
41 | let (db, file_id) = crate::tests::with_single_file(&before); | 41 | let (db, file_id) = crate::tests::with_single_file(&before); |
42 | let frange = FileRange { file_id, range: selection.into() }; | 42 | let frange = FileRange { file_id, range: selection.into() }; |
43 | 43 | ||
44 | let mut assist = Assist::resolved(&db, frange) | 44 | let mut assist = Assist::resolved(&db, &AssistConfig::default(), frange) |
45 | .into_iter() | 45 | .into_iter() |
46 | .find(|assist| assist.assist.id.0 == assist_id) | 46 | .find(|assist| assist.assist.id.0 == assist_id) |
47 | .unwrap_or_else(|| { | 47 | .unwrap_or_else(|| { |
48 | panic!( | 48 | panic!( |
49 | "\n\nAssist is not applicable: {}\nAvailable assists: {}", | 49 | "\n\nAssist is not applicable: {}\nAvailable assists: {}", |
50 | assist_id, | 50 | assist_id, |
51 | Assist::resolved(&db, frange) | 51 | Assist::resolved(&db, &AssistConfig::default(), frange) |
52 | .into_iter() | 52 | .into_iter() |
53 | .map(|assist| assist.assist.id.0) | 53 | .map(|assist| assist.assist.id.0) |
54 | .collect::<Vec<_>>() | 54 | .collect::<Vec<_>>() |
@@ -90,7 +90,8 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult) { | |||
90 | let frange = FileRange { file_id: file_with_caret_id, range: range_or_offset.into() }; | 90 | let frange = FileRange { file_id: file_with_caret_id, range: range_or_offset.into() }; |
91 | 91 | ||
92 | let sema = Semantics::new(&db); | 92 | let sema = Semantics::new(&db); |
93 | let ctx = AssistContext::new(sema, frange); | 93 | let config = AssistConfig::default(); |
94 | let ctx = AssistContext::new(sema, &config, frange); | ||
94 | let mut acc = Assists::new_resolved(&ctx); | 95 | let mut acc = Assists::new_resolved(&ctx); |
95 | handler(&mut acc, &ctx); | 96 | handler(&mut acc, &ctx); |
96 | let mut res = acc.finish_resolved(); | 97 | let mut res = acc.finish_resolved(); |
@@ -103,19 +104,20 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult) { | |||
103 | let mut actual = db.file_text(change.file_id).as_ref().to_owned(); | 104 | let mut actual = db.file_text(change.file_id).as_ref().to_owned(); |
104 | change.edit.apply(&mut actual); | 105 | change.edit.apply(&mut actual); |
105 | 106 | ||
106 | match source_change.cursor_position { | 107 | if !source_change.is_snippet { |
107 | None => { | 108 | match source_change.cursor_position { |
108 | if let RangeOrOffset::Offset(before_cursor_pos) = range_or_offset { | 109 | None => { |
109 | let off = change | 110 | if let RangeOrOffset::Offset(before_cursor_pos) = range_or_offset { |
110 | .edit | 111 | let off = change |
111 | .apply_to_offset(before_cursor_pos) | 112 | .edit |
112 | .expect("cursor position is affected by the edit"); | 113 | .apply_to_offset(before_cursor_pos) |
113 | actual = add_cursor(&actual, off) | 114 | .expect("cursor position is affected by the edit"); |
115 | actual = add_cursor(&actual, off) | ||
116 | } | ||
114 | } | 117 | } |
115 | } | 118 | Some(off) => actual = add_cursor(&actual, off.offset), |
116 | Some(off) => actual = add_cursor(&actual, off.offset), | 119 | }; |
117 | }; | 120 | } |
118 | |||
119 | assert_eq_text!(after, &actual); | 121 | assert_eq_text!(after, &actual); |
120 | } | 122 | } |
121 | (Some(assist), ExpectedResult::Target(target)) => { | 123 | (Some(assist), ExpectedResult::Target(target)) => { |
@@ -136,7 +138,7 @@ fn assist_order_field_struct() { | |||
136 | let (before_cursor_pos, before) = extract_offset(before); | 138 | let (before_cursor_pos, before) = extract_offset(before); |
137 | let (db, file_id) = with_single_file(&before); | 139 | let (db, file_id) = with_single_file(&before); |
138 | let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) }; | 140 | let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) }; |
139 | let assists = Assist::resolved(&db, frange); | 141 | let assists = Assist::resolved(&db, &AssistConfig::default(), frange); |
140 | let mut assists = assists.iter(); | 142 | let mut assists = assists.iter(); |
141 | 143 | ||
142 | assert_eq!( | 144 | assert_eq!( |
@@ -159,7 +161,7 @@ fn assist_order_if_expr() { | |||
159 | let (range, before) = extract_range(before); | 161 | let (range, before) = extract_range(before); |
160 | let (db, file_id) = with_single_file(&before); | 162 | let (db, file_id) = with_single_file(&before); |
161 | let frange = FileRange { file_id, range }; | 163 | let frange = FileRange { file_id, range }; |
162 | let assists = Assist::resolved(&db, frange); | 164 | let assists = Assist::resolved(&db, &AssistConfig::default(), frange); |
163 | let mut assists = assists.iter(); | 165 | let mut assists = assists.iter(); |
164 | 166 | ||
165 | assert_eq!(assists.next().expect("expected assist").assist.label, "Extract into variable"); | 167 | assert_eq!(assists.next().expect("expected assist").assist.label, "Extract into variable"); |
diff --git a/crates/ra_ide/src/completion.rs b/crates/ra_ide/src/completion.rs index 8bdc43b1a..191300704 100644 --- a/crates/ra_ide/src/completion.rs +++ b/crates/ra_ide/src/completion.rs | |||
@@ -59,8 +59,8 @@ pub use crate::completion::{ | |||
59 | /// with ordering of completions (currently this is done by the client). | 59 | /// with ordering of completions (currently this is done by the client). |
60 | pub(crate) fn completions( | 60 | pub(crate) fn completions( |
61 | db: &RootDatabase, | 61 | db: &RootDatabase, |
62 | position: FilePosition, | ||
63 | config: &CompletionConfig, | 62 | config: &CompletionConfig, |
63 | position: FilePosition, | ||
64 | ) -> Option<Completions> { | 64 | ) -> Option<Completions> { |
65 | let ctx = CompletionContext::new(db, position, config)?; | 65 | let ctx = CompletionContext::new(db, position, config)?; |
66 | 66 | ||
diff --git a/crates/ra_ide/src/completion/test_utils.rs b/crates/ra_ide/src/completion/test_utils.rs index eb90b5279..bf22452a2 100644 --- a/crates/ra_ide/src/completion/test_utils.rs +++ b/crates/ra_ide/src/completion/test_utils.rs | |||
@@ -20,7 +20,7 @@ pub(crate) fn do_completion_with_options( | |||
20 | } else { | 20 | } else { |
21 | single_file_with_position(code) | 21 | single_file_with_position(code) |
22 | }; | 22 | }; |
23 | let completions = analysis.completions(position, options).unwrap().unwrap(); | 23 | let completions = analysis.completions(options, position).unwrap().unwrap(); |
24 | let completion_items: Vec<CompletionItem> = completions.into(); | 24 | let completion_items: Vec<CompletionItem> = completions.into(); |
25 | let mut kind_completions: Vec<CompletionItem> = | 25 | let mut kind_completions: Vec<CompletionItem> = |
26 | completion_items.into_iter().filter(|c| c.completion_kind == kind).collect(); | 26 | completion_items.into_iter().filter(|c| c.completion_kind == kind).collect(); |
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs index 87a0b80f1..54c2bcc09 100644 --- a/crates/ra_ide/src/diagnostics.rs +++ b/crates/ra_ide/src/diagnostics.rs | |||
@@ -629,6 +629,7 @@ mod tests { | |||
629 | }, | 629 | }, |
630 | ], | 630 | ], |
631 | cursor_position: None, | 631 | cursor_position: None, |
632 | is_snippet: false, | ||
632 | }, | 633 | }, |
633 | ), | 634 | ), |
634 | severity: Error, | 635 | severity: Error, |
@@ -685,6 +686,7 @@ mod tests { | |||
685 | ], | 686 | ], |
686 | file_system_edits: [], | 687 | file_system_edits: [], |
687 | cursor_position: None, | 688 | cursor_position: None, |
689 | is_snippet: false, | ||
688 | }, | 690 | }, |
689 | ), | 691 | ), |
690 | severity: Error, | 692 | severity: Error, |
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index 78149ddfc..66125f2f5 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs | |||
@@ -82,7 +82,7 @@ pub use crate::{ | |||
82 | }; | 82 | }; |
83 | 83 | ||
84 | pub use hir::Documentation; | 84 | pub use hir::Documentation; |
85 | pub use ra_assists::AssistId; | 85 | pub use ra_assists::{AssistConfig, AssistId}; |
86 | pub use ra_db::{ | 86 | pub use ra_db::{ |
87 | Canceled, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRootId, | 87 | Canceled, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRootId, |
88 | }; | 88 | }; |
@@ -458,17 +458,17 @@ impl Analysis { | |||
458 | /// Computes completions at the given position. | 458 | /// Computes completions at the given position. |
459 | pub fn completions( | 459 | pub fn completions( |
460 | &self, | 460 | &self, |
461 | position: FilePosition, | ||
462 | config: &CompletionConfig, | 461 | config: &CompletionConfig, |
462 | position: FilePosition, | ||
463 | ) -> Cancelable<Option<Vec<CompletionItem>>> { | 463 | ) -> Cancelable<Option<Vec<CompletionItem>>> { |
464 | self.with_db(|db| completion::completions(db, position, config).map(Into::into)) | 464 | self.with_db(|db| completion::completions(db, config, position).map(Into::into)) |
465 | } | 465 | } |
466 | 466 | ||
467 | /// Computes assists (aka code actions aka intentions) for the given | 467 | /// Computes assists (aka code actions aka intentions) for the given |
468 | /// position. | 468 | /// position. |
469 | pub fn assists(&self, frange: FileRange) -> Cancelable<Vec<Assist>> { | 469 | pub fn assists(&self, config: &AssistConfig, frange: FileRange) -> Cancelable<Vec<Assist>> { |
470 | self.with_db(|db| { | 470 | self.with_db(|db| { |
471 | ra_assists::Assist::resolved(db, frange) | 471 | ra_assists::Assist::resolved(db, config, frange) |
472 | .into_iter() | 472 | .into_iter() |
473 | .map(|assist| Assist { | 473 | .map(|assist| Assist { |
474 | id: assist.assist.id, | 474 | id: assist.assist.id, |
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 410dae75c..68a53ad4b 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs | |||
@@ -670,6 +670,7 @@ mod tests { | |||
670 | }, | 670 | }, |
671 | ], | 671 | ], |
672 | cursor_position: None, | 672 | cursor_position: None, |
673 | is_snippet: false, | ||
673 | }, | 674 | }, |
674 | }, | 675 | }, |
675 | ) | 676 | ) |
@@ -722,6 +723,7 @@ mod tests { | |||
722 | }, | 723 | }, |
723 | ], | 724 | ], |
724 | cursor_position: None, | 725 | cursor_position: None, |
726 | is_snippet: false, | ||
725 | }, | 727 | }, |
726 | }, | 728 | }, |
727 | ) | 729 | ) |
@@ -818,6 +820,7 @@ mod tests { | |||
818 | }, | 820 | }, |
819 | ], | 821 | ], |
820 | cursor_position: None, | 822 | cursor_position: None, |
823 | is_snippet: false, | ||
821 | }, | 824 | }, |
822 | }, | 825 | }, |
823 | ) | 826 | ) |
diff --git a/crates/ra_ide_db/src/source_change.rs b/crates/ra_ide_db/src/source_change.rs index af81a91a4..c64165f3a 100644 --- a/crates/ra_ide_db/src/source_change.rs +++ b/crates/ra_ide_db/src/source_change.rs | |||
@@ -13,6 +13,7 @@ pub struct SourceChange { | |||
13 | pub source_file_edits: Vec<SourceFileEdit>, | 13 | pub source_file_edits: Vec<SourceFileEdit>, |
14 | pub file_system_edits: Vec<FileSystemEdit>, | 14 | pub file_system_edits: Vec<FileSystemEdit>, |
15 | pub cursor_position: Option<FilePosition>, | 15 | pub cursor_position: Option<FilePosition>, |
16 | pub is_snippet: bool, | ||
16 | } | 17 | } |
17 | 18 | ||
18 | impl SourceChange { | 19 | impl SourceChange { |
@@ -28,6 +29,7 @@ impl SourceChange { | |||
28 | source_file_edits, | 29 | source_file_edits, |
29 | file_system_edits, | 30 | file_system_edits, |
30 | cursor_position: None, | 31 | cursor_position: None, |
32 | is_snippet: false, | ||
31 | } | 33 | } |
32 | } | 34 | } |
33 | 35 | ||
@@ -41,6 +43,7 @@ impl SourceChange { | |||
41 | source_file_edits: edits, | 43 | source_file_edits: edits, |
42 | file_system_edits: vec![], | 44 | file_system_edits: vec![], |
43 | cursor_position: None, | 45 | cursor_position: None, |
46 | is_snippet: false, | ||
44 | } | 47 | } |
45 | } | 48 | } |
46 | 49 | ||
@@ -52,6 +55,7 @@ impl SourceChange { | |||
52 | source_file_edits: vec![], | 55 | source_file_edits: vec![], |
53 | file_system_edits: edits, | 56 | file_system_edits: edits, |
54 | cursor_position: None, | 57 | cursor_position: None, |
58 | is_snippet: false, | ||
55 | } | 59 | } |
56 | } | 60 | } |
57 | 61 | ||
@@ -115,6 +119,7 @@ impl SingleFileChange { | |||
115 | source_file_edits: vec![SourceFileEdit { file_id, edit: self.edit }], | 119 | source_file_edits: vec![SourceFileEdit { file_id, edit: self.edit }], |
116 | file_system_edits: Vec::new(), | 120 | file_system_edits: Vec::new(), |
117 | cursor_position: self.cursor_position.map(|offset| FilePosition { file_id, offset }), | 121 | cursor_position: self.cursor_position.map(|offset| FilePosition { file_id, offset }), |
122 | is_snippet: false, | ||
118 | } | 123 | } |
119 | } | 124 | } |
120 | } | 125 | } |
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index 6147ae207..b20efe98d 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs | |||
@@ -105,7 +105,7 @@ pub fn analysis_bench( | |||
105 | if is_completion { | 105 | if is_completion { |
106 | let options = CompletionConfig::default(); | 106 | let options = CompletionConfig::default(); |
107 | let res = do_work(&mut host, file_id, |analysis| { | 107 | let res = do_work(&mut host, file_id, |analysis| { |
108 | analysis.completions(file_position, &options) | 108 | analysis.completions(&options, file_position) |
109 | }); | 109 | }); |
110 | if verbosity.is_verbose() { | 110 | if verbosity.is_verbose() { |
111 | println!("\n{:#?}", res); | 111 | println!("\n{:#?}", res); |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index b5dc6f0fa..063b1b316 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -11,7 +11,7 @@ use std::{ffi::OsString, path::PathBuf}; | |||
11 | 11 | ||
12 | use lsp_types::ClientCapabilities; | 12 | use lsp_types::ClientCapabilities; |
13 | use ra_flycheck::FlycheckConfig; | 13 | use ra_flycheck::FlycheckConfig; |
14 | use ra_ide::{CompletionConfig, InlayHintsConfig}; | 14 | use ra_ide::{AssistConfig, CompletionConfig, InlayHintsConfig}; |
15 | use ra_project_model::CargoConfig; | 15 | use ra_project_model::CargoConfig; |
16 | use serde::Deserialize; | 16 | use serde::Deserialize; |
17 | 17 | ||
@@ -32,6 +32,7 @@ pub struct Config { | |||
32 | 32 | ||
33 | pub inlay_hints: InlayHintsConfig, | 33 | pub inlay_hints: InlayHintsConfig, |
34 | pub completion: CompletionConfig, | 34 | pub completion: CompletionConfig, |
35 | pub assist: AssistConfig, | ||
35 | pub call_info_full: bool, | 36 | pub call_info_full: bool, |
36 | pub lens: LensConfig, | 37 | pub lens: LensConfig, |
37 | } | 38 | } |
@@ -136,6 +137,7 @@ impl Default for Config { | |||
136 | add_call_argument_snippets: true, | 137 | add_call_argument_snippets: true, |
137 | ..CompletionConfig::default() | 138 | ..CompletionConfig::default() |
138 | }, | 139 | }, |
140 | assist: AssistConfig::default(), | ||
139 | call_info_full: true, | 141 | call_info_full: true, |
140 | lens: LensConfig::default(), | 142 | lens: LensConfig::default(), |
141 | } | 143 | } |
@@ -281,6 +283,7 @@ impl Config { | |||
281 | } | 283 | } |
282 | } | 284 | } |
283 | } | 285 | } |
286 | self.assist.allow_snippets(false); | ||
284 | } | 287 | } |
285 | 288 | ||
286 | if let Some(window_caps) = caps.window.as_ref() { | 289 | if let Some(window_caps) = caps.window.as_ref() { |
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index e67556752..13ae061fa 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs | |||
@@ -476,7 +476,7 @@ pub fn handle_completion( | |||
476 | return Ok(None); | 476 | return Ok(None); |
477 | } | 477 | } |
478 | 478 | ||
479 | let items = match world.analysis().completions(position, &world.config.completion)? { | 479 | let items = match world.analysis().completions(&world.config.completion, position)? { |
480 | None => return Ok(None), | 480 | None => return Ok(None), |
481 | Some(items) => items, | 481 | Some(items) => items, |
482 | }; | 482 | }; |
@@ -740,7 +740,9 @@ pub fn handle_code_action( | |||
740 | } | 740 | } |
741 | 741 | ||
742 | let mut grouped_assists: FxHashMap<String, (usize, Vec<Assist>)> = FxHashMap::default(); | 742 | let mut grouped_assists: FxHashMap<String, (usize, Vec<Assist>)> = FxHashMap::default(); |
743 | for assist in world.analysis().assists(FileRange { file_id, range })?.into_iter() { | 743 | for assist in |
744 | world.analysis().assists(&world.config.assist, FileRange { file_id, range })?.into_iter() | ||
745 | { | ||
744 | match &assist.group_label { | 746 | match &assist.group_label { |
745 | Some(label) => grouped_assists | 747 | Some(label) => grouped_assists |
746 | .entry(label.to_owned()) | 748 | .entry(label.to_owned()) |