@@ -3,7 +3,7 @@ use std::iter::successors;
3
3
use ra_syntax:: {
4
4
algo:: neighbor,
5
5
ast:: { self , edit:: AstNodeEdit , make} ,
6
- AstNode , AstToken , Direction , InsertPosition , SyntaxElement , T ,
6
+ AstNode , AstToken , Direction , InsertPosition , SyntaxElement , TextRange , T ,
7
7
} ;
8
8
9
9
use crate :: { Assist , AssistCtx , AssistId } ;
@@ -22,18 +22,15 @@ use crate::{Assist, AssistCtx, AssistId};
22
22
// ```
23
23
pub ( crate ) fn merge_imports ( ctx : AssistCtx ) -> Option < Assist > {
24
24
let tree: ast:: UseTree = ctx. find_node_at_offset ( ) ?;
25
- let use_item = tree. syntax ( ) . parent ( ) . and_then ( ast:: UseItem :: cast) ?;
26
- let ( merged, to_delete) = [ Direction :: Prev , Direction :: Next ]
27
- . iter ( )
28
- . copied ( )
29
- . filter_map ( |dir| neighbor ( & use_item, dir) )
30
- . filter_map ( |it| Some ( ( it. clone ( ) , it. use_tree ( ) ?) ) )
31
- . find_map ( |( use_item, use_tree) | {
32
- Some ( ( try_merge_trees ( & tree, & use_tree) ?, use_item. clone ( ) ) )
33
- } ) ?;
34
- let mut offset = ctx. frange . range . start ( ) ;
35
- ctx. add_assist ( AssistId ( "merge_imports" ) , "Merge imports" , |edit| {
36
- edit. replace_ast ( tree, merged) ;
25
+ let ( new_tree, to_delete) = if let Some ( use_item) =
26
+ tree. syntax ( ) . parent ( ) . and_then ( ast:: UseItem :: cast)
27
+ {
28
+ let ( merged, to_delete) = next_prev ( )
29
+ . filter_map ( |dir| neighbor ( & use_item, dir) )
30
+ . filter_map ( |it| Some ( ( it. clone ( ) , it. use_tree ( ) ?) ) )
31
+ . find_map ( |( use_item, use_tree) | {
32
+ Some ( ( try_merge_trees ( & tree, & use_tree) ?, use_item. clone ( ) ) )
33
+ } ) ?;
37
34
38
35
let mut range = to_delete. syntax ( ) . text_range ( ) ;
39
36
let next_ws = to_delete
@@ -44,14 +41,41 @@ pub(crate) fn merge_imports(ctx: AssistCtx) -> Option<Assist> {
44
41
if let Some ( ws) = next_ws {
45
42
range = range. extend_to ( & ws. syntax ( ) . text_range ( ) )
46
43
}
47
- edit. delete ( range) ;
48
- if range. end ( ) <= offset {
49
- offset -= range. len ( ) ;
44
+ ( merged, range)
45
+ } else {
46
+ let ( merged, to_delete) = next_prev ( )
47
+ . filter_map ( |dir| neighbor ( & tree, dir) )
48
+ . find_map ( |use_tree| Some ( ( try_merge_trees ( & tree, & use_tree) ?, use_tree. clone ( ) ) ) ) ?;
49
+
50
+ let mut range = to_delete. syntax ( ) . text_range ( ) ;
51
+ if let Some ( ( dir, nb) ) = next_prev ( ) . find_map ( |dir| Some ( ( dir, neighbor ( & to_delete, dir) ?) ) )
52
+ {
53
+ let nb_range = nb. syntax ( ) . text_range ( ) ;
54
+ if dir == Direction :: Prev {
55
+ range = TextRange :: from_to ( nb_range. end ( ) , range. end ( ) ) ;
56
+ } else {
57
+ range = TextRange :: from_to ( range. start ( ) , nb_range. start ( ) ) ;
58
+ }
59
+ }
60
+ ( merged, range)
61
+ } ;
62
+
63
+ let mut offset = ctx. frange . range . start ( ) ;
64
+ ctx. add_assist ( AssistId ( "merge_imports" ) , "Merge imports" , |edit| {
65
+ edit. replace_ast ( tree, new_tree) ;
66
+ edit. delete ( to_delete) ;
67
+
68
+ if to_delete. end ( ) <= offset {
69
+ offset -= to_delete. len ( ) ;
50
70
}
51
71
edit. set_cursor ( offset) ;
52
72
} )
53
73
}
54
74
75
+ fn next_prev ( ) -> impl Iterator < Item = Direction > {
76
+ [ Direction :: Next , Direction :: Prev ] . iter ( ) . copied ( )
77
+ }
78
+
55
79
fn try_merge_trees ( old : & ast:: UseTree , new : & ast:: UseTree ) -> Option < ast:: UseTree > {
56
80
let lhs_path = old. path ( ) ?;
57
81
let rhs_path = new. path ( ) ?;
@@ -134,20 +158,28 @@ use std::fmt<|>::Display;
134
158
r"
135
159
use std::fmt<|>::{Display, Debug};
136
160
" ,
137
- )
161
+ ) ;
138
162
}
139
163
140
164
#[ test]
141
- #[ ignore]
142
165
fn test_merge_nested ( ) {
143
166
check_assist (
144
167
merge_imports,
145
168
r"
146
169
use std::{fmt<|>::Debug, fmt::Display};
147
170
" ,
148
171
r"
149
- use std::{fmt::{Debug, Display}};
172
+ use std::{fmt<|> ::{Debug, Display}};
150
173
" ,
151
- )
174
+ ) ;
175
+ check_assist (
176
+ merge_imports,
177
+ r"
178
+ use std::{fmt::Debug, fmt<|>::Display};
179
+ " ,
180
+ r"
181
+ use std::{fmt<|>::{Display, Debug}};
182
+ " ,
183
+ ) ;
152
184
}
153
185
}
0 commit comments