@@ -88,7 +88,7 @@ fn on_char_typed_inner(
88
88
}
89
89
90
90
/// Inserts a closing `}` when the user types an opening `{`, wrapping an existing expression in a
91
- /// block.
91
+ /// block, or a part of a `use` item .
92
92
fn on_opening_brace_typed ( file : & Parse < SourceFile > , offset : TextSize ) -> Option < TextEdit > {
93
93
if !stdx:: always!( file. tree( ) . syntax( ) . text( ) . char_at( offset) == Some ( '{' ) ) {
94
94
return None ;
@@ -99,30 +99,59 @@ fn on_opening_brace_typed(file: &Parse<SourceFile>, offset: TextSize) -> Option<
99
99
// Remove the `{` to get a better parse tree, and reparse
100
100
let file = file. reparse ( & Indel :: delete ( brace_token. text_range ( ) ) ) ;
101
101
102
- let mut expr: ast:: Expr = find_node_at_offset ( file. tree ( ) . syntax ( ) , offset) ?;
103
- if expr. syntax ( ) . text_range ( ) . start ( ) != offset {
104
- return None ;
102
+ if let Some ( edit) = brace_expr ( & file. tree ( ) , offset) {
103
+ return Some ( edit) ;
105
104
}
106
105
107
- // Enclose the outermost expression starting at `offset`
108
- while let Some ( parent) = expr. syntax ( ) . parent ( ) {
109
- if parent. text_range ( ) . start ( ) != expr. syntax ( ) . text_range ( ) . start ( ) {
110
- break ;
111
- }
106
+ if let Some ( edit) = brace_use_path ( & file. tree ( ) , offset) {
107
+ return Some ( edit) ;
108
+ }
112
109
113
- match ast:: Expr :: cast ( parent) {
114
- Some ( parent) => expr = parent,
115
- None => break ,
110
+ return None ;
111
+
112
+ fn brace_use_path ( file : & SourceFile , offset : TextSize ) -> Option < TextEdit > {
113
+ let segment: ast:: PathSegment = find_node_at_offset ( file. syntax ( ) , offset) ?;
114
+ if segment. syntax ( ) . text_range ( ) . start ( ) != offset {
115
+ return None ;
116
116
}
117
- }
118
117
119
- // If it's a statement in a block, we don't know how many statements should be included
120
- if ast:: ExprStmt :: can_cast ( expr. syntax ( ) . parent ( ) ?. kind ( ) ) {
121
- return None ;
118
+ let tree: ast:: UseTree = find_node_at_offset ( file. syntax ( ) , offset) ?;
119
+
120
+ Some ( TextEdit :: insert (
121
+ tree. syntax ( ) . text_range ( ) . end ( ) + TextSize :: of ( "{" ) ,
122
+ "}" . to_string ( ) ,
123
+ ) )
122
124
}
123
125
124
- // Insert `}` right after the expression.
125
- Some ( TextEdit :: insert ( expr. syntax ( ) . text_range ( ) . end ( ) + TextSize :: of ( "{" ) , "}" . to_string ( ) ) )
126
+ fn brace_expr ( file : & SourceFile , offset : TextSize ) -> Option < TextEdit > {
127
+ let mut expr: ast:: Expr = find_node_at_offset ( file. syntax ( ) , offset) ?;
128
+ if expr. syntax ( ) . text_range ( ) . start ( ) != offset {
129
+ return None ;
130
+ }
131
+
132
+ // Enclose the outermost expression starting at `offset`
133
+ while let Some ( parent) = expr. syntax ( ) . parent ( ) {
134
+ if parent. text_range ( ) . start ( ) != expr. syntax ( ) . text_range ( ) . start ( ) {
135
+ break ;
136
+ }
137
+
138
+ match ast:: Expr :: cast ( parent) {
139
+ Some ( parent) => expr = parent,
140
+ None => break ,
141
+ }
142
+ }
143
+
144
+ // If it's a statement in a block, we don't know how many statements should be included
145
+ if ast:: ExprStmt :: can_cast ( expr. syntax ( ) . parent ( ) ?. kind ( ) ) {
146
+ return None ;
147
+ }
148
+
149
+ // Insert `}` right after the expression.
150
+ Some ( TextEdit :: insert (
151
+ expr. syntax ( ) . text_range ( ) . end ( ) + TextSize :: of ( "{" ) ,
152
+ "}" . to_string ( ) ,
153
+ ) )
154
+ }
126
155
}
127
156
128
157
/// Returns an edit which should be applied after `=` was typed. Primarily,
@@ -440,7 +469,7 @@ fn foo() -> { 92 }
440
469
}
441
470
442
471
#[ test]
443
- fn adds_closing_brace ( ) {
472
+ fn adds_closing_brace_for_expr ( ) {
444
473
type_char (
445
474
'{' ,
446
475
r#"
@@ -519,4 +548,87 @@ fn f() {
519
548
"# ,
520
549
) ;
521
550
}
551
+
552
+ #[ test]
553
+ fn adds_closing_brace_for_use_tree ( ) {
554
+ type_char (
555
+ '{' ,
556
+ r#"
557
+ use some::$0Path;
558
+ "# ,
559
+ r#"
560
+ use some::{Path};
561
+ "# ,
562
+ ) ;
563
+ type_char (
564
+ '{' ,
565
+ r#"
566
+ use some::{Path, $0Other};
567
+ "# ,
568
+ r#"
569
+ use some::{Path, {Other}};
570
+ "# ,
571
+ ) ;
572
+ type_char (
573
+ '{' ,
574
+ r#"
575
+ use some::{$0Path, Other};
576
+ "# ,
577
+ r#"
578
+ use some::{{Path}, Other};
579
+ "# ,
580
+ ) ;
581
+ type_char (
582
+ '{' ,
583
+ r#"
584
+ use some::path::$0to::Item;
585
+ "# ,
586
+ r#"
587
+ use some::path::{to::Item};
588
+ "# ,
589
+ ) ;
590
+ type_char (
591
+ '{' ,
592
+ r#"
593
+ use some::$0path::to::Item;
594
+ "# ,
595
+ r#"
596
+ use some::{path::to::Item};
597
+ "# ,
598
+ ) ;
599
+ type_char (
600
+ '{' ,
601
+ r#"
602
+ use $0some::path::to::Item;
603
+ "# ,
604
+ r#"
605
+ use {some::path::to::Item};
606
+ "# ,
607
+ ) ;
608
+ type_char (
609
+ '{' ,
610
+ r#"
611
+ use some::path::$0to::{Item};
612
+ "# ,
613
+ r#"
614
+ use some::path::{to::{Item}};
615
+ "# ,
616
+ ) ;
617
+ type_char (
618
+ '{' ,
619
+ r#"
620
+ use $0Thing as _;
621
+ "# ,
622
+ r#"
623
+ use {Thing as _};
624
+ "# ,
625
+ ) ;
626
+
627
+ type_char_noop (
628
+ '{' ,
629
+ r#"
630
+ use some::pa$0th::to::Item;
631
+ "# ,
632
+ ) ;
633
+ }
522
634
}
0 commit comments