@@ -14,6 +14,7 @@ use syntax::{
1414 } ,
1515 InsertPosition , SyntaxElement , SyntaxNode ,
1616} ;
17+ use test_utils:: mark;
1718
1819#[ derive( Debug ) ]
1920pub enum ImportScope {
@@ -109,6 +110,12 @@ pub(crate) fn insert_use(
109110 // so look for the place we have to insert to
110111 let ( insert_position, add_blank) = find_insert_position ( scope, path) ;
111112
113+ let indent = if let ident_level @ 1 ..=usize:: MAX = scope. indent_level ( ) . 0 as usize {
114+ Some ( make:: tokens:: whitespace ( & " " . repeat ( 4 * ident_level) ) . into ( ) )
115+ } else {
116+ None
117+ } ;
118+
112119 let to_insert: Vec < SyntaxElement > = {
113120 let mut buf = Vec :: new ( ) ;
114121
@@ -120,9 +127,13 @@ pub(crate) fn insert_use(
120127 _ => ( ) ,
121128 }
122129
123- if let ident_level @ 1 ..=usize:: MAX = scope. indent_level ( ) . 0 as usize {
124- buf. push ( make:: tokens:: whitespace ( & " " . repeat ( 4 * ident_level) ) . into ( ) ) ;
130+ if add_blank. has_before ( ) {
131+ if let Some ( indent) = indent. clone ( ) {
132+ mark:: hit!( insert_use_indent_before) ;
133+ buf. push ( indent) ;
134+ }
125135 }
136+
126137 buf. push ( use_item. syntax ( ) . clone ( ) . into ( ) ) ;
127138
128139 match add_blank {
@@ -133,6 +144,16 @@ pub(crate) fn insert_use(
133144 _ => ( ) ,
134145 }
135146
147+ // only add indentation *after* our stuff if there's another node directly after it
148+ if add_blank. has_after ( ) && matches ! ( insert_position, InsertPosition :: Before ( _) ) {
149+ if let Some ( indent) = indent {
150+ mark:: hit!( insert_use_indent_after) ;
151+ buf. push ( indent) ;
152+ }
153+ } else if add_blank. has_after ( ) && matches ! ( insert_position, InsertPosition :: After ( _) ) {
154+ mark:: hit!( insert_use_no_indent_after) ;
155+ }
156+
136157 buf
137158 } ;
138159
@@ -470,6 +491,15 @@ enum AddBlankLine {
470491 AfterTwice ,
471492}
472493
494+ impl AddBlankLine {
495+ fn has_before ( & self ) -> bool {
496+ matches ! ( self , AddBlankLine :: Before | AddBlankLine :: BeforeTwice | AddBlankLine :: Around )
497+ }
498+ fn has_after ( & self ) -> bool {
499+ matches ! ( self , AddBlankLine :: After | AddBlankLine :: AfterTwice | AddBlankLine :: Around )
500+ }
501+ }
502+
473503fn find_insert_position (
474504 scope : & ImportScope ,
475505 insert_path : ast:: Path ,
@@ -561,6 +591,20 @@ use std::bar::G;",
561591 )
562592 }
563593
594+ #[ test]
595+ fn insert_start_indent ( ) {
596+ check_none (
597+ "std::bar::AA" ,
598+ r"
599+ use std::bar::B;
600+ use std::bar::D;" ,
601+ r"
602+ use std::bar::AA;
603+ use std::bar::B;
604+ use std::bar::D;" ,
605+ )
606+ }
607+
564608 #[ test]
565609 fn insert_middle ( ) {
566610 check_none (
@@ -579,6 +623,25 @@ use std::bar::G;",
579623 )
580624 }
581625
626+ #[ test]
627+ fn insert_middle_indent ( ) {
628+ mark:: check!( insert_use_indent_before) ;
629+ check_none (
630+ "std::bar::EE" ,
631+ r"
632+ use std::bar::A;
633+ use std::bar::D;
634+ use std::bar::F;
635+ use std::bar::G;" ,
636+ r"
637+ use std::bar::A;
638+ use std::bar::D;
639+ use std::bar::EE;
640+ use std::bar::F;
641+ use std::bar::G;" ,
642+ )
643+ }
644+
582645 #[ test]
583646 fn insert_end ( ) {
584647 check_none (
@@ -597,6 +660,24 @@ use std::bar::ZZ;",
597660 )
598661 }
599662
663+ #[ test]
664+ fn insert_end_indent ( ) {
665+ check_none (
666+ "std::bar::ZZ" ,
667+ r"
668+ use std::bar::A;
669+ use std::bar::D;
670+ use std::bar::F;
671+ use std::bar::G;" ,
672+ r"
673+ use std::bar::A;
674+ use std::bar::D;
675+ use std::bar::F;
676+ use std::bar::G;
677+ use std::bar::ZZ;" ,
678+ )
679+ }
680+
600681 #[ test]
601682 fn insert_middle_nested ( ) {
602683 check_none (
@@ -620,18 +701,18 @@ use std::bar::G;",
620701 check_none (
621702 "foo::bar::GG" ,
622703 r"
623- use std::bar::A;
624- use std::bar::D;
704+ use std::bar::A;
705+ use std::bar::D;
625706
626- use foo::bar::F;
627- use foo::bar::H;" ,
707+ use foo::bar::F;
708+ use foo::bar::H;",
628709 r"
629- use std::bar::A;
630- use std::bar::D;
710+ use std::bar::A;
711+ use std::bar::D;
631712
632- use foo::bar::F;
633- use foo::bar::GG;
634- use foo::bar::H;" ,
713+ use foo::bar::F;
714+ use foo::bar::GG;
715+ use foo::bar::H;",
635716 )
636717 }
637718
@@ -640,37 +721,38 @@ use foo::bar::H;",
640721 check_none (
641722 "foo::bar::GG" ,
642723 r"
643- use foo::bar::A;
644- use foo::bar::D;
724+ use foo::bar::A;
725+ use foo::bar::D;
645726
646- use std;
727+ use std;
647728
648- use foo::bar::F;
649- use foo::bar::H;" ,
729+ use foo::bar::F;
730+ use foo::bar::H;",
650731 r"
651- use foo::bar::A;
652- use foo::bar::D;
653- use foo::bar::GG;
732+ use foo::bar::A;
733+ use foo::bar::D;
734+ use foo::bar::GG;
654735
655- use std;
736+ use std;
656737
657- use foo::bar::F;
658- use foo::bar::H;" ,
738+ use foo::bar::F;
739+ use foo::bar::H;",
659740 )
660741 }
661742
662743 #[ test]
663744 fn insert_missing_group_std ( ) {
745+ mark:: check!( insert_use_indent_after) ;
664746 check_none (
665747 "std::fmt" ,
666748 r"
667- use foo::bar::A;
668- use foo::bar::D;" ,
749+ use foo::bar::A;
750+ use foo::bar::D;",
669751 r"
670- use std::fmt;
752+ use std::fmt;
671753
672- use foo::bar::A;
673- use foo::bar::D;" ,
754+ use foo::bar::A;
755+ use foo::bar::D;",
674756 )
675757 }
676758
@@ -713,6 +795,20 @@ fn main() {}",
713795 )
714796 }
715797
798+ #[ test]
799+ fn insert_empty_module ( ) {
800+ mark:: check!( insert_use_no_indent_after) ;
801+ check (
802+ "foo::bar" ,
803+ "mod x {}" ,
804+ r"{
805+ use foo::bar;
806+ }" ,
807+ None ,
808+ true
809+ )
810+ }
811+
716812 #[ test]
717813 fn insert_after_inner_attr ( ) {
718814 check_full (
@@ -991,11 +1087,13 @@ use foo::bar::baz::Qux;",
9911087 ra_fixture_before : & str ,
9921088 ra_fixture_after : & str ,
9931089 mb : Option < MergeBehaviour > ,
1090+ module : bool ,
9941091 ) {
995- let file = super :: ImportScope :: from (
996- ast:: SourceFile :: parse ( ra_fixture_before) . tree ( ) . syntax ( ) . clone ( ) ,
997- )
998- . unwrap ( ) ;
1092+ let mut syntax = ast:: SourceFile :: parse ( ra_fixture_before) . tree ( ) . syntax ( ) . clone ( ) ;
1093+ if module {
1094+ syntax = syntax. descendants ( ) . find_map ( ast:: Module :: cast) . unwrap ( ) . syntax ( ) . clone ( ) ;
1095+ }
1096+ let file = super :: ImportScope :: from ( syntax) . unwrap ( ) ;
9991097 let path = ast:: SourceFile :: parse ( & format ! ( "use {};" , path) )
10001098 . tree ( )
10011099 . syntax ( )
@@ -1008,15 +1106,15 @@ use foo::bar::baz::Qux;",
10081106 }
10091107
10101108 fn check_full ( path : & str , ra_fixture_before : & str , ra_fixture_after : & str ) {
1011- check ( path, ra_fixture_before, ra_fixture_after, Some ( MergeBehaviour :: Full ) )
1109+ check ( path, ra_fixture_before, ra_fixture_after, Some ( MergeBehaviour :: Full ) , false )
10121110 }
10131111
10141112 fn check_last ( path : & str , ra_fixture_before : & str , ra_fixture_after : & str ) {
1015- check ( path, ra_fixture_before, ra_fixture_after, Some ( MergeBehaviour :: Last ) )
1113+ check ( path, ra_fixture_before, ra_fixture_after, Some ( MergeBehaviour :: Last ) , false )
10161114 }
10171115
10181116 fn check_none ( path : & str , ra_fixture_before : & str , ra_fixture_after : & str ) {
1019- check ( path, ra_fixture_before, ra_fixture_after, None )
1117+ check ( path, ra_fixture_before, ra_fixture_after, None , false )
10201118 }
10211119
10221120 fn check_merge_only_fail ( ra_fixture0 : & str , ra_fixture1 : & str , mb : MergeBehaviour ) {
0 commit comments