diff options
Diffstat (limited to 'crates/ra_assists/src/assist_context.rs')
-rw-r--r-- | crates/ra_assists/src/assist_context.rs | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/crates/ra_assists/src/assist_context.rs b/crates/ra_assists/src/assist_context.rs index c33525363..9ca2cfe68 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. |
@@ -57,6 +57,7 @@ pub(crate) struct AssistContext<'a> { | |||
57 | pub(crate) sema: Semantics<'a, RootDatabase>, | 57 | pub(crate) sema: Semantics<'a, RootDatabase>, |
58 | pub(crate) frange: FileRange, | 58 | pub(crate) frange: FileRange, |
59 | source_file: SourceFile, | 59 | source_file: SourceFile, |
60 | allowed: Option<Vec<AssistKind>>, | ||
60 | } | 61 | } |
61 | 62 | ||
62 | impl<'a> AssistContext<'a> { | 63 | impl<'a> AssistContext<'a> { |
@@ -64,9 +65,10 @@ impl<'a> AssistContext<'a> { | |||
64 | sema: Semantics<'a, RootDatabase>, | 65 | sema: Semantics<'a, RootDatabase>, |
65 | config: &'a AssistConfig, | 66 | config: &'a AssistConfig, |
66 | frange: FileRange, | 67 | frange: FileRange, |
68 | allowed: Option<Vec<AssistKind>>, | ||
67 | ) -> AssistContext<'a> { | 69 | ) -> AssistContext<'a> { |
68 | let source_file = sema.parse(frange.file_id); | 70 | let source_file = sema.parse(frange.file_id); |
69 | AssistContext { config, sema, frange, source_file } | 71 | AssistContext { config, sema, frange, source_file, allowed } |
70 | } | 72 | } |
71 | 73 | ||
72 | pub(crate) fn db(&self) -> &RootDatabase { | 74 | pub(crate) fn db(&self) -> &RootDatabase { |
@@ -103,14 +105,26 @@ pub(crate) struct Assists { | |||
103 | resolve: bool, | 105 | resolve: bool, |
104 | file: FileId, | 106 | file: FileId, |
105 | buf: Vec<(Assist, Option<SourceChange>)>, | 107 | buf: Vec<(Assist, Option<SourceChange>)>, |
108 | allowed: Option<Vec<AssistKind>>, | ||
106 | } | 109 | } |
107 | 110 | ||
108 | impl Assists { | 111 | impl Assists { |
109 | pub(crate) fn new_resolved(ctx: &AssistContext) -> Assists { | 112 | pub(crate) fn new_resolved(ctx: &AssistContext) -> Assists { |
110 | Assists { resolve: true, file: ctx.frange.file_id, buf: Vec::new() } | 113 | Assists { |
114 | resolve: true, | ||
115 | file: ctx.frange.file_id, | ||
116 | buf: Vec::new(), | ||
117 | allowed: ctx.allowed.clone(), | ||
118 | } | ||
111 | } | 119 | } |
120 | |||
112 | pub(crate) fn new_unresolved(ctx: &AssistContext) -> Assists { | 121 | pub(crate) fn new_unresolved(ctx: &AssistContext) -> Assists { |
113 | Assists { resolve: false, file: ctx.frange.file_id, buf: Vec::new() } | 122 | Assists { |
123 | resolve: false, | ||
124 | file: ctx.frange.file_id, | ||
125 | buf: Vec::new(), | ||
126 | allowed: ctx.allowed.clone(), | ||
127 | } | ||
114 | } | 128 | } |
115 | 129 | ||
116 | pub(crate) fn finish_unresolved(self) -> Vec<Assist> { | 130 | pub(crate) fn finish_unresolved(self) -> Vec<Assist> { |
@@ -139,9 +153,13 @@ impl Assists { | |||
139 | target: TextRange, | 153 | target: TextRange, |
140 | f: impl FnOnce(&mut AssistBuilder), | 154 | f: impl FnOnce(&mut AssistBuilder), |
141 | ) -> Option<()> { | 155 | ) -> Option<()> { |
156 | if !self.is_allowed(&id) { | ||
157 | return None; | ||
158 | } | ||
142 | let label = Assist::new(id, label.into(), None, target); | 159 | let label = Assist::new(id, label.into(), None, target); |
143 | self.add_impl(label, f) | 160 | self.add_impl(label, f) |
144 | } | 161 | } |
162 | |||
145 | pub(crate) fn add_group( | 163 | pub(crate) fn add_group( |
146 | &mut self, | 164 | &mut self, |
147 | group: &GroupLabel, | 165 | group: &GroupLabel, |
@@ -150,9 +168,14 @@ impl Assists { | |||
150 | target: TextRange, | 168 | target: TextRange, |
151 | f: impl FnOnce(&mut AssistBuilder), | 169 | f: impl FnOnce(&mut AssistBuilder), |
152 | ) -> Option<()> { | 170 | ) -> Option<()> { |
171 | if !self.is_allowed(&id) { | ||
172 | return None; | ||
173 | } | ||
174 | |||
153 | let label = Assist::new(id, label.into(), Some(group.clone()), target); | 175 | let label = Assist::new(id, label.into(), Some(group.clone()), target); |
154 | self.add_impl(label, f) | 176 | self.add_impl(label, f) |
155 | } | 177 | } |
178 | |||
156 | fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> { | 179 | fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> { |
157 | let source_change = if self.resolve { | 180 | let source_change = if self.resolve { |
158 | let mut builder = AssistBuilder::new(self.file); | 181 | let mut builder = AssistBuilder::new(self.file); |
@@ -170,6 +193,13 @@ impl Assists { | |||
170 | self.buf.sort_by_key(|(label, _edit)| label.target.len()); | 193 | self.buf.sort_by_key(|(label, _edit)| label.target.len()); |
171 | self.buf | 194 | self.buf |
172 | } | 195 | } |
196 | |||
197 | fn is_allowed(&self, id: &AssistId) -> bool { | ||
198 | match &self.allowed { | ||
199 | Some(allowed) => allowed.iter().any(|kind| kind.contains(id.1)), | ||
200 | None => true, | ||
201 | } | ||
202 | } | ||
173 | } | 203 | } |
174 | 204 | ||
175 | pub(crate) struct AssistBuilder { | 205 | pub(crate) struct AssistBuilder { |