@@ -86,7 +86,14 @@ pub(crate) fn toggle_macro_delimiter(acc: &mut Assists, ctx: &AssistContext<'_>)
8686 }
8787 MacroDelims :: LCur | MacroDelims :: RCur => {
8888 editor. replace ( ltoken, make. token ( T ! [ '[' ] ) ) ;
89- editor. replace ( rtoken, make. token ( T ! [ ']' ] ) ) ;
89+ if semicolon. is_some ( ) || !needs_semicolon ( token_tree) {
90+ editor. replace ( rtoken, make. token ( T ! [ ']' ] ) ) ;
91+ } else {
92+ editor. replace_with_many (
93+ rtoken,
94+ vec ! [ make. token( T ![ ']' ] ) . into( ) , make. token( T ![ ; ] ) . into( ) ] ,
95+ ) ;
96+ }
9097 }
9198 }
9299 editor. add_mappings ( make. finish_with_mappings ( ) ) ;
@@ -103,6 +110,30 @@ fn macro_semicolon(makro: &ast::MacroCall) -> Option<SyntaxToken> {
103110 } )
104111}
105112
113+ fn needs_semicolon ( tt : ast:: TokenTree ) -> bool {
114+ ( || {
115+ let call = ast:: MacroCall :: cast ( tt. syntax ( ) . parent ( ) ?) ?;
116+ let container = call. syntax ( ) . parent ( ) ?;
117+ let kind = container. kind ( ) ;
118+
119+ if call. semicolon_token ( ) . is_some ( ) {
120+ return Some ( false ) ;
121+ }
122+
123+ Some (
124+ ast:: ItemList :: can_cast ( kind)
125+ || ast:: SourceFile :: can_cast ( kind)
126+ || ast:: AssocItemList :: can_cast ( kind)
127+ || ast:: ExternItemList :: can_cast ( kind)
128+ || ast:: MacroItems :: can_cast ( kind)
129+ || ast:: MacroExpr :: can_cast ( kind)
130+ && ast:: ExprStmt :: cast ( container. parent ( ) ?)
131+ . is_some_and ( |it| it. semicolon_token ( ) . is_none ( ) ) ,
132+ )
133+ } ) ( )
134+ . unwrap_or ( false )
135+ }
136+
106137#[ cfg( test) ]
107138mod tests {
108139 use crate :: tests:: { check_assist, check_assist_not_applicable} ;
@@ -161,7 +192,7 @@ macro_rules! sth {
161192 () => {};
162193}
163194
164- sth!$0{ };
195+ sth!$0{ }
165196 "# ,
166197 r#"
167198macro_rules! sth {
@@ -170,7 +201,117 @@ macro_rules! sth {
170201
171202sth![ ];
172203 "# ,
173- )
204+ ) ;
205+
206+ check_assist (
207+ toggle_macro_delimiter,
208+ r#"
209+ macro_rules! sth {
210+ () => {};
211+ }
212+
213+ fn foo() -> i32 {
214+ sth!$0{ }
215+ 2
216+ }
217+ "# ,
218+ r#"
219+ macro_rules! sth {
220+ () => {};
221+ }
222+
223+ fn foo() -> i32 {
224+ sth![ ];
225+ 2
226+ }
227+ "# ,
228+ ) ;
229+
230+ check_assist (
231+ toggle_macro_delimiter,
232+ r#"
233+ macro_rules! sth {
234+ () => {2};
235+ }
236+
237+ fn foo() {
238+ sth!$0{ };
239+ }
240+ "# ,
241+ r#"
242+ macro_rules! sth {
243+ () => {2};
244+ }
245+
246+ fn foo() {
247+ sth![ ];
248+ }
249+ "# ,
250+ ) ;
251+
252+ check_assist (
253+ toggle_macro_delimiter,
254+ r#"
255+ macro_rules! sth {
256+ () => {2};
257+ }
258+
259+ fn foo() -> i32 {
260+ sth!$0{ }
261+ }
262+ "# ,
263+ r#"
264+ macro_rules! sth {
265+ () => {2};
266+ }
267+
268+ fn foo() -> i32 {
269+ sth![ ]
270+ }
271+ "# ,
272+ ) ;
273+
274+ check_assist (
275+ toggle_macro_delimiter,
276+ r#"
277+ macro_rules! sth {
278+ () => {};
279+ }
280+ impl () {
281+ sth!$0{}
282+ }
283+ "# ,
284+ r#"
285+ macro_rules! sth {
286+ () => {};
287+ }
288+ impl () {
289+ sth![];
290+ }
291+ "# ,
292+ ) ;
293+
294+ check_assist (
295+ toggle_macro_delimiter,
296+ r#"
297+ macro_rules! sth {
298+ () => {2};
299+ }
300+
301+ fn foo() -> i32 {
302+ bar(sth!$0{ })
303+ }
304+ "# ,
305+ r#"
306+ macro_rules! sth {
307+ () => {2};
308+ }
309+
310+ fn foo() -> i32 {
311+ bar(sth![ ])
312+ }
313+ "# ,
314+ ) ;
174315 }
175316
176317 #[ test]
@@ -204,7 +345,7 @@ mod abc {
204345 () => {};
205346 }
206347
207- sth!$0{ };
348+ sth!$0{ }
208349}
209350 "# ,
210351 r#"
0 commit comments