Skip to content

Commit fb99831

Browse files
committed
Slightly simpler API for groups
1 parent aa5f80a commit fb99831

File tree

2 files changed

+77
-48
lines changed

2 files changed

+77
-48
lines changed

crates/ra_assists/src/assist_ctx.rs

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -98,30 +98,8 @@ impl<'a> AssistCtx<'a> {
9898
Some(assist)
9999
}
100100

101-
pub(crate) fn add_assist_group(
102-
self,
103-
id: AssistId,
104-
label: impl Into<String>,
105-
f: impl FnOnce() -> Vec<ActionBuilder>,
106-
) -> Option<Assist> {
107-
let label = AssistLabel::new(label.into(), id);
108-
let assist = if self.should_compute_edit {
109-
let actions = f();
110-
assert!(!actions.is_empty(), "Assist cannot have no");
111-
112-
Assist::Resolved {
113-
assist: ResolvedAssist {
114-
label,
115-
action_data: Either::Right(
116-
actions.into_iter().map(ActionBuilder::build).collect(),
117-
),
118-
},
119-
}
120-
} else {
121-
Assist::Unresolved { label }
122-
};
123-
124-
Some(assist)
101+
pub(crate) fn add_assist_group(self, group_name: impl Into<String>) -> AssistGroup<'a> {
102+
AssistGroup { ctx: self, group_name: group_name.into(), assists: Vec::new() }
125103
}
126104

127105
pub(crate) fn token_at_offset(&self) -> TokenAtOffset<SyntaxToken> {
@@ -155,6 +133,67 @@ impl<'a> AssistCtx<'a> {
155133
}
156134
}
157135

136+
pub(crate) struct AssistGroup<'a> {
137+
ctx: AssistCtx<'a>,
138+
group_name: String,
139+
assists: Vec<Assist>,
140+
}
141+
142+
impl<'a> AssistGroup<'a> {
143+
pub(crate) fn add_assist(
144+
&mut self,
145+
id: AssistId,
146+
label: impl Into<String>,
147+
f: impl FnOnce(&mut ActionBuilder),
148+
) {
149+
let label = AssistLabel::new(label.into(), id);
150+
151+
let assist = if self.ctx.should_compute_edit {
152+
let action = {
153+
let mut edit = ActionBuilder::default();
154+
f(&mut edit);
155+
edit.build()
156+
};
157+
Assist::Resolved { assist: ResolvedAssist { label, action_data: Either::Left(action) } }
158+
} else {
159+
Assist::Unresolved { label }
160+
};
161+
162+
self.assists.push(assist)
163+
}
164+
165+
pub(crate) fn finish(self) -> Option<Assist> {
166+
assert!(!self.assists.is_empty());
167+
let mut label = match &self.assists[0] {
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+
}
195+
}
196+
158197
#[derive(Default)]
159198
pub(crate) struct ActionBuilder {
160199
edit: TextEditBuilder,
@@ -164,11 +203,6 @@ pub(crate) struct ActionBuilder {
164203
}
165204

166205
impl ActionBuilder {
167-
/// Adds a custom label to the action, if it needs to be different from the assist label
168-
pub(crate) fn label(&mut self, label: impl Into<String>) {
169-
self.label = Some(label.into())
170-
}
171-
172206
/// Replaces specified `range` of text with a given string.
173207
pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
174208
self.edit.replace(range, replace_with.into())

crates/ra_assists/src/handlers/auto_import.rs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
use hir::ModPath;
21
use ra_ide_db::imports_locator::ImportsLocator;
3-
use ra_syntax::{
4-
ast::{self, AstNode},
5-
SyntaxNode,
6-
};
2+
use ra_syntax::ast::{self, AstNode};
73

84
use crate::{
9-
assist_ctx::{ActionBuilder, Assist, AssistCtx},
5+
assist_ctx::{Assist, AssistCtx},
106
insert_use_statement, AssistId,
117
};
128
use std::collections::BTreeSet;
@@ -67,19 +63,18 @@ pub(crate) fn auto_import(ctx: AssistCtx) -> Option<Assist> {
6763
return None;
6864
}
6965

70-
ctx.add_assist_group(AssistId("auto_import"), format!("Import {}", name_to_import), || {
71-
proposed_imports
72-
.into_iter()
73-
.map(|import| import_to_action(import, &position, &path_to_import_syntax))
74-
.collect()
75-
})
76-
}
77-
78-
fn import_to_action(import: ModPath, position: &SyntaxNode, anchor: &SyntaxNode) -> ActionBuilder {
79-
let mut action_builder = ActionBuilder::default();
80-
action_builder.label(format!("Import `{}`", &import));
81-
insert_use_statement(position, anchor, &import, action_builder.text_edit_builder());
82-
action_builder
66+
let mut group = ctx.add_assist_group(format!("Import {}", name_to_import));
67+
for import in proposed_imports {
68+
group.add_assist(AssistId("auto_import"), format!("Import `{}`", &import), |edit| {
69+
insert_use_statement(
70+
&position,
71+
path_to_import_syntax,
72+
&import,
73+
edit.text_edit_builder(),
74+
);
75+
});
76+
}
77+
group.finish()
8378
}
8479

8580
#[cfg(test)]

0 commit comments

Comments
 (0)