@@ -88,7 +88,7 @@ fn on_char_typed_inner(
8888}
8989
9090/// 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 .
9292fn on_opening_brace_typed ( file : & Parse < SourceFile > , offset : TextSize ) -> Option < TextEdit > {
9393 if !stdx:: always!( file. tree( ) . syntax( ) . text( ) . char_at( offset) == Some ( '{' ) ) {
9494 return None ;
@@ -99,30 +99,59 @@ fn on_opening_brace_typed(file: &Parse<SourceFile>, offset: TextSize) -> Option<
9999 // Remove the `{` to get a better parse tree, and reparse
100100 let file = file. reparse ( & Indel :: delete ( brace_token. text_range ( ) ) ) ;
101101
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) ;
105104 }
106105
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+ }
112109
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 ;
116116 }
117- }
118117
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+ ) )
122124 }
123125
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+ }
126155}
127156
128157/// Returns an edit which should be applied after `=` was typed. Primarily,
@@ -440,7 +469,7 @@ fn foo() -> { 92 }
440469 }
441470
442471 #[ test]
443- fn adds_closing_brace ( ) {
472+ fn adds_closing_brace_for_expr ( ) {
444473 type_char (
445474 '{' ,
446475 r#"
@@ -519,4 +548,87 @@ fn f() {
519548 "# ,
520549 ) ;
521550 }
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+ }
522634}
0 commit comments