@@ -98,30 +98,8 @@ impl<'a> AssistCtx<'a> {
98
98
Some ( assist)
99
99
}
100
100
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 ( ) }
125
103
}
126
104
127
105
pub ( crate ) fn token_at_offset ( & self ) -> TokenAtOffset < SyntaxToken > {
@@ -155,6 +133,67 @@ impl<'a> AssistCtx<'a> {
155
133
}
156
134
}
157
135
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
+
158
197
#[ derive( Default ) ]
159
198
pub ( crate ) struct ActionBuilder {
160
199
edit : TextEditBuilder ,
@@ -164,11 +203,6 @@ pub(crate) struct ActionBuilder {
164
203
}
165
204
166
205
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
-
172
206
/// Replaces specified `range` of text with a given string.
173
207
pub ( crate ) fn replace ( & mut self , range : TextRange , replace_with : impl Into < String > ) {
174
208
self . edit . replace ( range, replace_with. into ( ) )
0 commit comments