diff options
Diffstat (limited to 'crates/ra_assists/src/assist_context.rs')
-rw-r--r-- | crates/ra_assists/src/assist_context.rs | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/crates/ra_assists/src/assist_context.rs b/crates/ra_assists/src/assist_context.rs index 3640bb4d2..3407df856 100644 --- a/crates/ra_assists/src/assist_context.rs +++ b/crates/ra_assists/src/assist_context.rs | |||
@@ -19,7 +19,7 @@ use ra_text_edit::TextEditBuilder; | |||
19 | 19 | ||
20 | use crate::{ | 20 | use crate::{ |
21 | assist_config::{AssistConfig, SnippetCap}, | 21 | assist_config::{AssistConfig, SnippetCap}, |
22 | Assist, AssistId, GroupLabel, ResolvedAssist, | 22 | Assist, AssistId, AssistKind, GroupLabel, ResolvedAssist, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | /// `AssistContext` allows to apply an assist or check if it could be applied. | 25 | /// `AssistContext` allows to apply an assist or check if it could be applied. |
@@ -103,14 +103,26 @@ pub(crate) struct Assists { | |||
103 | resolve: bool, | 103 | resolve: bool, |
104 | file: FileId, | 104 | file: FileId, |
105 | buf: Vec<(Assist, Option<SourceChange>)>, | 105 | buf: Vec<(Assist, Option<SourceChange>)>, |
106 | allowed: Option<Vec<AssistKind>>, | ||
106 | } | 107 | } |
107 | 108 | ||
108 | impl Assists { | 109 | impl Assists { |
109 | pub(crate) fn new_resolved(ctx: &AssistContext) -> Assists { | 110 | pub(crate) fn new_resolved(ctx: &AssistContext) -> Assists { |
110 | Assists { resolve: true, file: ctx.frange.file_id, buf: Vec::new() } | 111 | Assists { |
112 | resolve: true, | ||
113 | file: ctx.frange.file_id, | ||
114 | buf: Vec::new(), | ||
115 | allowed: ctx.config.allowed.clone(), | ||
116 | } | ||
111 | } | 117 | } |
118 | |||
112 | pub(crate) fn new_unresolved(ctx: &AssistContext) -> Assists { | 119 | pub(crate) fn new_unresolved(ctx: &AssistContext) -> Assists { |
113 | Assists { resolve: false, file: ctx.frange.file_id, buf: Vec::new() } | 120 | Assists { |
121 | resolve: false, | ||
122 | file: ctx.frange.file_id, | ||
123 | buf: Vec::new(), | ||
124 | allowed: ctx.config.allowed.clone(), | ||
125 | } | ||
114 | } | 126 | } |
115 | 127 | ||
116 | pub(crate) fn finish_unresolved(self) -> Vec<Assist> { | 128 | pub(crate) fn finish_unresolved(self) -> Vec<Assist> { |
@@ -139,9 +151,13 @@ impl Assists { | |||
139 | target: TextRange, | 151 | target: TextRange, |
140 | f: impl FnOnce(&mut AssistBuilder), | 152 | f: impl FnOnce(&mut AssistBuilder), |
141 | ) -> Option<()> { | 153 | ) -> Option<()> { |
154 | if !self.is_allowed(&id) { | ||
155 | return None; | ||
156 | } | ||
142 | let label = Assist::new(id, label.into(), None, target); | 157 | let label = Assist::new(id, label.into(), None, target); |
143 | self.add_impl(label, f) | 158 | self.add_impl(label, f) |
144 | } | 159 | } |
160 | |||
145 | pub(crate) fn add_group( | 161 | pub(crate) fn add_group( |
146 | &mut self, | 162 | &mut self, |
147 | group: &GroupLabel, | 163 | group: &GroupLabel, |
@@ -150,9 +166,14 @@ impl Assists { | |||
150 | target: TextRange, | 166 | target: TextRange, |
151 | f: impl FnOnce(&mut AssistBuilder), | 167 | f: impl FnOnce(&mut AssistBuilder), |
152 | ) -> Option<()> { | 168 | ) -> Option<()> { |
169 | if !self.is_allowed(&id) { | ||
170 | return None; | ||
171 | } | ||
172 | |||
153 | let label = Assist::new(id, label.into(), Some(group.clone()), target); | 173 | let label = Assist::new(id, label.into(), Some(group.clone()), target); |
154 | self.add_impl(label, f) | 174 | self.add_impl(label, f) |
155 | } | 175 | } |
176 | |||
156 | fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> { | 177 | fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> { |
157 | let source_change = if self.resolve { | 178 | let source_change = if self.resolve { |
158 | let mut builder = AssistBuilder::new(self.file); | 179 | let mut builder = AssistBuilder::new(self.file); |
@@ -170,13 +191,20 @@ impl Assists { | |||
170 | self.buf.sort_by_key(|(label, _edit)| label.target.len()); | 191 | self.buf.sort_by_key(|(label, _edit)| label.target.len()); |
171 | self.buf | 192 | self.buf |
172 | } | 193 | } |
194 | |||
195 | fn is_allowed(&self, id: &AssistId) -> bool { | ||
196 | match &self.allowed { | ||
197 | Some(allowed) => allowed.iter().any(|kind| kind.contains(id.1)), | ||
198 | None => true, | ||
199 | } | ||
200 | } | ||
173 | } | 201 | } |
174 | 202 | ||
175 | pub(crate) struct AssistBuilder { | 203 | pub(crate) struct AssistBuilder { |
176 | edit: TextEditBuilder, | 204 | edit: TextEditBuilder, |
177 | file_id: FileId, | 205 | file_id: FileId, |
178 | is_snippet: bool, | 206 | is_snippet: bool, |
179 | edits: Vec<SourceFileEdit>, | 207 | change: SourceChange, |
180 | } | 208 | } |
181 | 209 | ||
182 | impl AssistBuilder { | 210 | impl AssistBuilder { |
@@ -185,7 +213,7 @@ impl AssistBuilder { | |||
185 | edit: TextEditBuilder::default(), | 213 | edit: TextEditBuilder::default(), |
186 | file_id, | 214 | file_id, |
187 | is_snippet: false, | 215 | is_snippet: false, |
188 | edits: Vec::new(), | 216 | change: SourceChange::default(), |
189 | } | 217 | } |
190 | } | 218 | } |
191 | 219 | ||
@@ -197,8 +225,8 @@ impl AssistBuilder { | |||
197 | let edit = mem::take(&mut self.edit).finish(); | 225 | let edit = mem::take(&mut self.edit).finish(); |
198 | if !edit.is_empty() { | 226 | if !edit.is_empty() { |
199 | let new_edit = SourceFileEdit { file_id: self.file_id, edit }; | 227 | let new_edit = SourceFileEdit { file_id: self.file_id, edit }; |
200 | assert!(!self.edits.iter().any(|it| it.file_id == new_edit.file_id)); | 228 | assert!(!self.change.source_file_edits.iter().any(|it| it.file_id == new_edit.file_id)); |
201 | self.edits.push(new_edit); | 229 | self.change.source_file_edits.push(new_edit); |
202 | } | 230 | } |
203 | } | 231 | } |
204 | 232 | ||
@@ -265,10 +293,10 @@ impl AssistBuilder { | |||
265 | 293 | ||
266 | fn finish(mut self) -> SourceChange { | 294 | fn finish(mut self) -> SourceChange { |
267 | self.commit(); | 295 | self.commit(); |
268 | let mut res: SourceChange = mem::take(&mut self.edits).into(); | 296 | let mut change = mem::take(&mut self.change); |
269 | if self.is_snippet { | 297 | if self.is_snippet { |
270 | res.is_snippet = true; | 298 | change.is_snippet = true; |
271 | } | 299 | } |
272 | res | 300 | change |
273 | } | 301 | } |
274 | } | 302 | } |