aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/assist_context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/assist_context.rs')
-rw-r--r--crates/ra_assists/src/assist_context.rs38
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
20use crate::{ 20use 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
62impl<'a> AssistContext<'a> { 63impl<'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
108impl Assists { 111impl 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
175pub(crate) struct AssistBuilder { 205pub(crate) struct AssistBuilder {