diff options
Diffstat (limited to 'crates/ra_assists/src/assist_ctx.rs')
-rw-r--r-- | crates/ra_assists/src/assist_ctx.rs | 83 |
1 files changed, 38 insertions, 45 deletions
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs index 5924a3fd5..5aab5fb8b 100644 --- a/crates/ra_assists/src/assist_ctx.rs +++ b/crates/ra_assists/src/assist_ctx.rs | |||
@@ -1,5 +1,4 @@ | |||
1 | //! This module defines `AssistCtx` -- the API surface that is exposed to assists. | 1 | //! This module defines `AssistCtx` -- the API surface that is exposed to assists. |
2 | use either::Either; | ||
3 | use hir::{InFile, SourceAnalyzer, SourceBinder}; | 2 | use hir::{InFile, SourceAnalyzer, SourceBinder}; |
4 | use ra_db::{FileRange, SourceDatabase}; | 3 | use ra_db::{FileRange, SourceDatabase}; |
5 | use ra_fmt::{leading_indent, reindent}; | 4 | use ra_fmt::{leading_indent, reindent}; |
@@ -11,12 +10,36 @@ use ra_syntax::{ | |||
11 | }; | 10 | }; |
12 | use ra_text_edit::TextEditBuilder; | 11 | use ra_text_edit::TextEditBuilder; |
13 | 12 | ||
14 | use crate::{AssistAction, AssistId, AssistLabel, ResolvedAssist}; | 13 | use crate::{AssistAction, AssistId, AssistLabel, GroupLabel, ResolvedAssist}; |
15 | 14 | ||
16 | #[derive(Clone, Debug)] | 15 | #[derive(Clone, Debug)] |
17 | pub(crate) enum Assist { | 16 | pub(crate) struct Assist(pub(crate) Vec<AssistInfo>); |
18 | Unresolved { label: AssistLabel }, | 17 | |
19 | Resolved { assist: ResolvedAssist }, | 18 | #[derive(Clone, Debug)] |
19 | pub(crate) struct AssistInfo { | ||
20 | pub(crate) label: AssistLabel, | ||
21 | pub(crate) group_label: Option<GroupLabel>, | ||
22 | pub(crate) action: Option<AssistAction>, | ||
23 | } | ||
24 | |||
25 | impl AssistInfo { | ||
26 | fn new(label: AssistLabel) -> AssistInfo { | ||
27 | AssistInfo { label, group_label: None, action: None } | ||
28 | } | ||
29 | |||
30 | fn resolved(self, action: AssistAction) -> AssistInfo { | ||
31 | AssistInfo { action: Some(action), ..self } | ||
32 | } | ||
33 | |||
34 | fn with_group(self, group_label: GroupLabel) -> AssistInfo { | ||
35 | AssistInfo { group_label: Some(group_label), ..self } | ||
36 | } | ||
37 | |||
38 | pub(crate) fn into_resolved(self) -> Option<ResolvedAssist> { | ||
39 | let label = self.label; | ||
40 | let group_label = self.group_label; | ||
41 | self.action.map(|action| ResolvedAssist { label, group_label, action }) | ||
42 | } | ||
20 | } | 43 | } |
21 | 44 | ||
22 | pub(crate) type AssistHandler = fn(AssistCtx) -> Option<Assist>; | 45 | pub(crate) type AssistHandler = fn(AssistCtx) -> Option<Assist>; |
@@ -84,18 +107,17 @@ impl<'a> AssistCtx<'a> { | |||
84 | ) -> Option<Assist> { | 107 | ) -> Option<Assist> { |
85 | let label = AssistLabel::new(label.into(), id); | 108 | let label = AssistLabel::new(label.into(), id); |
86 | 109 | ||
87 | let assist = if self.should_compute_edit { | 110 | let mut info = AssistInfo::new(label); |
111 | if self.should_compute_edit { | ||
88 | let action = { | 112 | let action = { |
89 | let mut edit = ActionBuilder::default(); | 113 | let mut edit = ActionBuilder::default(); |
90 | f(&mut edit); | 114 | f(&mut edit); |
91 | edit.build() | 115 | edit.build() |
92 | }; | 116 | }; |
93 | Assist::Resolved { assist: ResolvedAssist { label, action_data: Either::Left(action) } } | 117 | info = info.resolved(action) |
94 | } else { | ||
95 | Assist::Unresolved { label } | ||
96 | }; | 118 | }; |
97 | 119 | ||
98 | Some(assist) | 120 | Some(Assist(vec![info])) |
99 | } | 121 | } |
100 | 122 | ||
101 | pub(crate) fn add_assist_group(self, group_name: impl Into<String>) -> AssistGroup<'a> { | 123 | pub(crate) fn add_assist_group(self, group_name: impl Into<String>) -> AssistGroup<'a> { |
@@ -136,7 +158,7 @@ impl<'a> AssistCtx<'a> { | |||
136 | pub(crate) struct AssistGroup<'a> { | 158 | pub(crate) struct AssistGroup<'a> { |
137 | ctx: AssistCtx<'a>, | 159 | ctx: AssistCtx<'a>, |
138 | group_name: String, | 160 | group_name: String, |
139 | assists: Vec<Assist>, | 161 | assists: Vec<AssistInfo>, |
140 | } | 162 | } |
141 | 163 | ||
142 | impl<'a> AssistGroup<'a> { | 164 | impl<'a> AssistGroup<'a> { |
@@ -148,49 +170,22 @@ impl<'a> AssistGroup<'a> { | |||
148 | ) { | 170 | ) { |
149 | let label = AssistLabel::new(label.into(), id); | 171 | let label = AssistLabel::new(label.into(), id); |
150 | 172 | ||
151 | let assist = if self.ctx.should_compute_edit { | 173 | let mut info = AssistInfo::new(label).with_group(GroupLabel(self.group_name.clone())); |
174 | if self.ctx.should_compute_edit { | ||
152 | let action = { | 175 | let action = { |
153 | let mut edit = ActionBuilder::default(); | 176 | let mut edit = ActionBuilder::default(); |
154 | f(&mut edit); | 177 | f(&mut edit); |
155 | edit.build() | 178 | edit.build() |
156 | }; | 179 | }; |
157 | Assist::Resolved { assist: ResolvedAssist { label, action_data: Either::Left(action) } } | 180 | info = info.resolved(action) |
158 | } else { | ||
159 | Assist::Unresolved { label } | ||
160 | }; | 181 | }; |
161 | 182 | ||
162 | self.assists.push(assist) | 183 | self.assists.push(info) |
163 | } | 184 | } |
164 | 185 | ||
165 | pub(crate) fn finish(self) -> Option<Assist> { | 186 | pub(crate) fn finish(self) -> Option<Assist> { |
166 | assert!(!self.assists.is_empty()); | 187 | assert!(!self.assists.is_empty()); |
167 | let mut label = match &self.assists[0] { | 188 | Some(Assist(self.assists)) |
168 | Assist::Unresolved { label } => label.clone(), | ||
169 | Assist::Resolved { assist } => assist.label.clone(), | ||
170 | }; | ||
171 | label.label = self.group_name; | ||
172 | let assist = if self.ctx.should_compute_edit { | ||
173 | Assist::Resolved { | ||
174 | assist: ResolvedAssist { | ||
175 | label, | ||
176 | action_data: Either::Right( | ||
177 | self.assists | ||
178 | .into_iter() | ||
179 | .map(|assist| match assist { | ||
180 | Assist::Resolved { | ||
181 | assist: | ||
182 | ResolvedAssist { label: _, action_data: Either::Left(it) }, | ||
183 | } => it, | ||
184 | _ => unreachable!(), | ||
185 | }) | ||
186 | .collect(), | ||
187 | ), | ||
188 | }, | ||
189 | } | ||
190 | } else { | ||
191 | Assist::Unresolved { label } | ||
192 | }; | ||
193 | Some(assist) | ||
194 | } | 189 | } |
195 | } | 190 | } |
196 | 191 | ||
@@ -199,7 +194,6 @@ pub(crate) struct ActionBuilder { | |||
199 | edit: TextEditBuilder, | 194 | edit: TextEditBuilder, |
200 | cursor_position: Option<TextUnit>, | 195 | cursor_position: Option<TextUnit>, |
201 | target: Option<TextRange>, | 196 | target: Option<TextRange>, |
202 | label: Option<String>, | ||
203 | } | 197 | } |
204 | 198 | ||
205 | impl ActionBuilder { | 199 | impl ActionBuilder { |
@@ -261,7 +255,6 @@ impl ActionBuilder { | |||
261 | edit: self.edit.finish(), | 255 | edit: self.edit.finish(), |
262 | cursor_position: self.cursor_position, | 256 | cursor_position: self.cursor_position, |
263 | target: self.target, | 257 | target: self.target, |
264 | label: self.label, | ||
265 | } | 258 | } |
266 | } | 259 | } |
267 | } | 260 | } |