1
1
use either:: Either ;
2
- use ide_db:: imports:: merge_imports:: { try_merge_imports, try_merge_trees, MergeBehavior } ;
2
+ use ide_db:: imports:: {
3
+ insert_use:: { ImportGranularity , InsertUseConfig } ,
4
+ merge_imports:: { try_merge_imports, try_merge_trees, MergeBehavior } ,
5
+ } ;
3
6
use syntax:: {
4
7
algo:: neighbor,
5
8
ast:: { self , edit_in_place:: Removable } ,
@@ -30,14 +33,36 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
30
33
let ( target, edits) = if ctx. has_empty_selection ( ) {
31
34
// Merge a neighbor
32
35
let tree: ast:: UseTree = ctx. find_node_at_offset ( ) ?;
33
- let target = tree. syntax ( ) . text_range ( ) ;
36
+ let mut target = tree. syntax ( ) . text_range ( ) ;
34
37
35
38
let edits = if let Some ( use_item) = tree. syntax ( ) . parent ( ) . and_then ( ast:: Use :: cast) {
36
39
let mut neighbor = next_prev ( ) . find_map ( |dir| neighbor ( & use_item, dir) ) . into_iter ( ) ;
37
- use_item. try_merge_from ( & mut neighbor)
40
+ use_item. try_merge_from ( & mut neighbor, & ctx . config . insert_use )
38
41
} else {
39
42
let mut neighbor = next_prev ( ) . find_map ( |dir| neighbor ( & tree, dir) ) . into_iter ( ) ;
40
- tree. try_merge_from ( & mut neighbor)
43
+ let mut edits = tree. clone ( ) . try_merge_from ( & mut neighbor, & ctx. config . insert_use ) ;
44
+
45
+ if edits. is_none ( ) && ctx. config . insert_use . granularity == ImportGranularity :: One {
46
+ let one_tree = tree
47
+ . parent_use_tree_list ( )
48
+ . map ( |it| it. parent_use_tree ( ) . top_use_tree ( ) )
49
+ . filter ( |top_tree| top_tree. path ( ) . is_none ( ) )
50
+ . and_then ( |one_tree| {
51
+ one_tree. syntax ( ) . parent ( ) . and_then ( ast:: Use :: cast) . zip ( Some ( one_tree) )
52
+ } ) ;
53
+ if let Some ( ( use_item, one_tree) ) = one_tree {
54
+ let mut neighbor = next_prev ( )
55
+ . find_map ( |dir| syntax:: algo:: neighbor ( & use_item, dir) )
56
+ . into_iter ( ) ;
57
+ edits = use_item. try_merge_from ( & mut neighbor, & ctx. config . insert_use ) ;
58
+
59
+ if edits. is_some ( ) {
60
+ target = one_tree. syntax ( ) . text_range ( ) ;
61
+ }
62
+ }
63
+ }
64
+
65
+ edits
41
66
} ;
42
67
( target, edits?)
43
68
} else {
@@ -54,10 +79,10 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
54
79
let edits = match_ast ! {
55
80
match first_selected {
56
81
ast:: Use ( use_item) => {
57
- use_item. try_merge_from( & mut selected_nodes. filter_map( ast:: Use :: cast) )
82
+ use_item. try_merge_from( & mut selected_nodes. filter_map( ast:: Use :: cast) , & ctx . config . insert_use )
58
83
} ,
59
84
ast:: UseTree ( use_tree) => {
60
- use_tree. try_merge_from( & mut selected_nodes. filter_map( ast:: UseTree :: cast) )
85
+ use_tree. try_merge_from( & mut selected_nodes. filter_map( ast:: UseTree :: cast) , & ctx . config . insert_use )
61
86
} ,
62
87
_ => return None ,
63
88
}
@@ -89,11 +114,15 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
89
114
}
90
115
91
116
trait Merge : AstNode + Clone {
92
- fn try_merge_from ( self , items : & mut dyn Iterator < Item = Self > ) -> Option < Vec < Edit > > {
117
+ fn try_merge_from (
118
+ self ,
119
+ items : & mut dyn Iterator < Item = Self > ,
120
+ cfg : & InsertUseConfig ,
121
+ ) -> Option < Vec < Edit > > {
93
122
let mut edits = Vec :: new ( ) ;
94
123
let mut merged = self . clone ( ) ;
95
124
for item in items {
96
- merged = merged. try_merge ( & item) ?;
125
+ merged = merged. try_merge ( & item, cfg ) ?;
97
126
edits. push ( Edit :: Remove ( item. into_either ( ) ) ) ;
98
127
}
99
128
if !edits. is_empty ( ) {
@@ -103,21 +132,25 @@ trait Merge: AstNode + Clone {
103
132
None
104
133
}
105
134
}
106
- fn try_merge ( & self , other : & Self ) -> Option < Self > ;
135
+ fn try_merge ( & self , other : & Self , cfg : & InsertUseConfig ) -> Option < Self > ;
107
136
fn into_either ( self ) -> Either < ast:: Use , ast:: UseTree > ;
108
137
}
109
138
110
139
impl Merge for ast:: Use {
111
- fn try_merge ( & self , other : & Self ) -> Option < Self > {
112
- try_merge_imports ( self , other, MergeBehavior :: Crate )
140
+ fn try_merge ( & self , other : & Self , cfg : & InsertUseConfig ) -> Option < Self > {
141
+ let mb = match cfg. granularity {
142
+ ImportGranularity :: One => MergeBehavior :: One ,
143
+ _ => MergeBehavior :: Crate ,
144
+ } ;
145
+ try_merge_imports ( self , other, mb)
113
146
}
114
147
fn into_either ( self ) -> Either < ast:: Use , ast:: UseTree > {
115
148
Either :: Left ( self )
116
149
}
117
150
}
118
151
119
152
impl Merge for ast:: UseTree {
120
- fn try_merge ( & self , other : & Self ) -> Option < Self > {
153
+ fn try_merge ( & self , other : & Self , _ : & InsertUseConfig ) -> Option < Self > {
121
154
try_merge_trees ( self , other, MergeBehavior :: Crate )
122
155
}
123
156
fn into_either ( self ) -> Either < ast:: Use , ast:: UseTree > {
@@ -138,10 +171,35 @@ impl Edit {
138
171
139
172
#[ cfg( test) ]
140
173
mod tests {
141
- use crate :: tests:: { check_assist, check_assist_not_applicable} ;
174
+ use crate :: tests:: { check_assist, check_assist_import_one , check_assist_not_applicable} ;
142
175
143
176
use super :: * ;
144
177
178
+ macro_rules! check_assist_import_one_variations {
179
+ ( $first: literal, $second: literal, $expected: literal) => {
180
+ check_assist_import_one(
181
+ merge_imports,
182
+ concat!( concat!( "use " , $first, ";" ) , concat!( "use " , $second, ";" ) ) ,
183
+ $expected,
184
+ ) ;
185
+ check_assist_import_one(
186
+ merge_imports,
187
+ concat!( concat!( "use {" , $first, "};" ) , concat!( "use " , $second, ";" ) ) ,
188
+ $expected,
189
+ ) ;
190
+ check_assist_import_one(
191
+ merge_imports,
192
+ concat!( concat!( "use " , $first, ";" ) , concat!( "use {" , $second, "};" ) ) ,
193
+ $expected,
194
+ ) ;
195
+ check_assist_import_one(
196
+ merge_imports,
197
+ concat!( concat!( "use {" , $first, "};" ) , concat!( "use {" , $second, "};" ) ) ,
198
+ $expected,
199
+ ) ;
200
+ } ;
201
+ }
202
+
145
203
#[ test]
146
204
fn test_merge_equal ( ) {
147
205
check_assist (
@@ -153,7 +211,12 @@ use std::fmt::{Display, Debug};
153
211
r"
154
212
use std::fmt::{Display, Debug};
155
213
" ,
156
- )
214
+ ) ;
215
+ check_assist_import_one_variations ! (
216
+ "std::fmt$0::{Display, Debug}" ,
217
+ "std::fmt::{Display, Debug}" ,
218
+ "use {std::fmt::{Display, Debug}};"
219
+ ) ;
157
220
}
158
221
159
222
#[ test]
@@ -167,7 +230,12 @@ use std::fmt::Display;
167
230
r"
168
231
use std::fmt::{Debug, Display};
169
232
" ,
170
- )
233
+ ) ;
234
+ check_assist_import_one_variations ! (
235
+ "std::fmt$0::Debug" ,
236
+ "std::fmt::Display" ,
237
+ "use {std::fmt::{Debug, Display}};"
238
+ ) ;
171
239
}
172
240
173
241
#[ test]
@@ -182,6 +250,11 @@ use std::fmt$0::Display;
182
250
use std::fmt::{Debug, Display};
183
251
" ,
184
252
) ;
253
+ check_assist_import_one_variations ! (
254
+ "std::fmt::Debug" ,
255
+ "std::fmt$0::Display" ,
256
+ "use {std::fmt::{Debug, Display}};"
257
+ ) ;
185
258
}
186
259
187
260
#[ test]
@@ -196,6 +269,11 @@ use std::fmt::Display;
196
269
use std::fmt::{self, Display};
197
270
" ,
198
271
) ;
272
+ check_assist_import_one_variations ! (
273
+ "std::fmt$0" ,
274
+ "std::fmt::Display" ,
275
+ "use {std::fmt::{self, Display}};"
276
+ ) ;
199
277
}
200
278
201
279
#[ test]
@@ -207,6 +285,15 @@ use std::{fmt, $0fmt::Display};
207
285
" ,
208
286
r"
209
287
use std::{fmt::{self, Display}};
288
+ " ,
289
+ ) ;
290
+ check_assist_import_one (
291
+ merge_imports,
292
+ r"
293
+ use {std::{fmt, $0fmt::Display}};
294
+ " ,
295
+ r"
296
+ use {std::{fmt::{self, Display}}};
210
297
" ,
211
298
) ;
212
299
}
@@ -306,6 +393,15 @@ use std::{fmt$0::Debug, fmt::Display};
306
393
" ,
307
394
r"
308
395
use std::{fmt::{Debug, Display}};
396
+ " ,
397
+ ) ;
398
+ check_assist_import_one (
399
+ merge_imports,
400
+ r"
401
+ use {std::{fmt$0::Debug, fmt::Display}};
402
+ " ,
403
+ r"
404
+ use {std::{fmt::{Debug, Display}}};
309
405
" ,
310
406
) ;
311
407
}
@@ -319,6 +415,15 @@ use std::{fmt::Debug, fmt$0::Display};
319
415
" ,
320
416
r"
321
417
use std::{fmt::{Debug, Display}};
418
+ " ,
419
+ ) ;
420
+ check_assist_import_one (
421
+ merge_imports,
422
+ r"
423
+ use {std::{fmt::Debug, fmt$0::Display}};
424
+ " ,
425
+ r"
426
+ use {std::{fmt::{Debug, Display}}};
322
427
" ,
323
428
) ;
324
429
}
@@ -335,6 +440,11 @@ use std::{fmt::{self, Debug}};
335
440
use std::{fmt::{self, Debug, Display, Write}};
336
441
" ,
337
442
) ;
443
+ check_assist_import_one_variations ! (
444
+ "std$0::{fmt::{Write, Display}}" ,
445
+ "std::{fmt::{self, Debug}}" ,
446
+ "use {std::{fmt::{self, Debug, Display, Write}}};"
447
+ ) ;
338
448
}
339
449
340
450
#[ test]
@@ -349,6 +459,11 @@ use std::{fmt::{Write, Display}};
349
459
use std::{fmt::{self, Debug, Display, Write}};
350
460
" ,
351
461
) ;
462
+ check_assist_import_one_variations ! (
463
+ "std$0::{fmt::{self, Debug}}" ,
464
+ "std::{fmt::{Write, Display}}" ,
465
+ "use {std::{fmt::{self, Debug, Display, Write}}};"
466
+ ) ;
352
467
}
353
468
354
469
#[ test]
@@ -360,6 +475,15 @@ use std::{fmt$0::{self, Debug}, fmt::{Write, Display}};
360
475
" ,
361
476
r"
362
477
use std::{fmt::{self, Debug, Display, Write}};
478
+ " ,
479
+ ) ;
480
+ check_assist_import_one (
481
+ merge_imports,
482
+ r"
483
+ use {std::{fmt$0::{self, Debug}, fmt::{Write, Display}}};
484
+ " ,
485
+ r"
486
+ use {std::{fmt::{self, Debug, Display, Write}}};
363
487
" ,
364
488
) ;
365
489
}
@@ -375,7 +499,12 @@ use foo::{bar};
375
499
r"
376
500
use foo::{bar::{self}};
377
501
" ,
378
- )
502
+ ) ;
503
+ check_assist_import_one_variations ! (
504
+ "foo::$0{bar::{self}}" ,
505
+ "foo::{bar}" ,
506
+ "use {foo::{bar::{self}}};"
507
+ ) ;
379
508
}
380
509
381
510
#[ test]
@@ -389,7 +518,12 @@ use foo::{bar::{self}};
389
518
r"
390
519
use foo::{bar::{self}};
391
520
" ,
392
- )
521
+ ) ;
522
+ check_assist_import_one_variations ! (
523
+ "foo::$0{bar}" ,
524
+ "foo::{bar::{self}}" ,
525
+ "use {foo::{bar::{self}}};"
526
+ ) ;
393
527
}
394
528
395
529
#[ test]
@@ -403,7 +537,12 @@ use std::{fmt::{self, Display}};
403
537
r"
404
538
use std::{fmt::{self, Display, *}};
405
539
" ,
406
- )
540
+ ) ;
541
+ check_assist_import_one_variations ! (
542
+ "std$0::{fmt::*}" ,
543
+ "std::{fmt::{self, Display}}" ,
544
+ "use {std::{fmt::{self, Display, *}}};"
545
+ ) ;
407
546
}
408
547
409
548
#[ test]
@@ -417,7 +556,12 @@ use std::str;
417
556
r"
418
557
use std::{cell::*, str};
419
558
" ,
420
- )
559
+ ) ;
560
+ check_assist_import_one_variations ! (
561
+ "std$0::cell::*" ,
562
+ "std::str" ,
563
+ "use {std::{cell::*, str}};"
564
+ ) ;
421
565
}
422
566
423
567
#[ test]
@@ -431,7 +575,12 @@ use std::str::*;
431
575
r"
432
576
use std::{cell::*, str::*};
433
577
" ,
434
- )
578
+ ) ;
579
+ check_assist_import_one_variations ! (
580
+ "std$0::cell::*" ,
581
+ "std::str::*" ,
582
+ "use {std::{cell::*, str::*}};"
583
+ ) ;
435
584
}
436
585
437
586
#[ test]
@@ -524,6 +673,11 @@ use foo::bar::Baz;
524
673
use foo::{bar::Baz, *};
525
674
" ,
526
675
) ;
676
+ check_assist_import_one_variations ! (
677
+ "foo::$0*" ,
678
+ "foo::bar::Baz" ,
679
+ "use {foo::{bar::Baz, *}};"
680
+ ) ;
527
681
}
528
682
529
683
#[ test]
@@ -541,6 +695,21 @@ $0use std::fmt::Result;
541
695
use std::fmt::Error;
542
696
use std::fmt::{Debug, Display, Write};
543
697
use std::fmt::Result;
698
+ " ,
699
+ ) ;
700
+ check_assist_import_one (
701
+ merge_imports,
702
+ r"
703
+ use std::fmt::Error;
704
+ $0use std::fmt::Display;
705
+ use std::fmt::Debug;
706
+ use std::fmt::Write;
707
+ $0use std::fmt::Result;
708
+ " ,
709
+ r"
710
+ use std::fmt::Error;
711
+ use {std::fmt::{Debug, Display, Write}};
712
+ use std::fmt::Result;
544
713
" ,
545
714
) ;
546
715
}
0 commit comments