@@ -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,21 @@ use std::bar::G;",
561591 )
562592 }
563593
594+ #[ test]
595+ fn insert_start_indent ( ) {
596+ mark:: check!( insert_use_indent_after) ;
597+ check_none (
598+ "std::bar::AA" ,
599+ r"
600+ use std::bar::B;
601+ use std::bar::D;" ,
602+ r"
603+ use std::bar::AA;
604+ use std::bar::B;
605+ use std::bar::D;" ,
606+ )
607+ }
608+
564609 #[ test]
565610 fn insert_middle ( ) {
566611 check_none (
@@ -579,6 +624,24 @@ use std::bar::G;",
579624 )
580625 }
581626
627+ #[ test]
628+ fn insert_middle_indent ( ) {
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,25 @@ use std::bar::ZZ;",
597660 )
598661 }
599662
663+ #[ test]
664+ fn insert_end_indent ( ) {
665+ mark:: check!( insert_use_indent_before) ;
666+ check_none (
667+ "std::bar::ZZ" ,
668+ r"
669+ use std::bar::A;
670+ use std::bar::D;
671+ use std::bar::F;
672+ use std::bar::G;" ,
673+ r"
674+ use std::bar::A;
675+ use std::bar::D;
676+ use std::bar::F;
677+ use std::bar::G;
678+ use std::bar::ZZ;" ,
679+ )
680+ }
681+
600682 #[ test]
601683 fn insert_middle_nested ( ) {
602684 check_none (
@@ -620,18 +702,18 @@ use std::bar::G;",
620702 check_none (
621703 "foo::bar::GG" ,
622704 r"
623- use std::bar::A;
624- use std::bar::D;
705+ use std::bar::A;
706+ use std::bar::D;
625707
626- use foo::bar::F;
627- use foo::bar::H;" ,
708+ use foo::bar::F;
709+ use foo::bar::H;",
628710 r"
629- use std::bar::A;
630- use std::bar::D;
711+ use std::bar::A;
712+ use std::bar::D;
631713
632- use foo::bar::F;
633- use foo::bar::GG;
634- use foo::bar::H;" ,
714+ use foo::bar::F;
715+ use foo::bar::GG;
716+ use foo::bar::H;",
635717 )
636718 }
637719
@@ -640,22 +722,22 @@ use foo::bar::H;",
640722 check_none (
641723 "foo::bar::GG" ,
642724 r"
643- use foo::bar::A;
644- use foo::bar::D;
725+ use foo::bar::A;
726+ use foo::bar::D;
645727
646- use std;
728+ use std;
647729
648- use foo::bar::F;
649- use foo::bar::H;" ,
730+ use foo::bar::F;
731+ use foo::bar::H;",
650732 r"
651- use foo::bar::A;
652- use foo::bar::D;
653- use foo::bar::GG;
733+ use foo::bar::A;
734+ use foo::bar::D;
735+ use foo::bar::GG;
654736
655- use std;
737+ use std;
656738
657- use foo::bar::F;
658- use foo::bar::H;" ,
739+ use foo::bar::F;
740+ use foo::bar::H;",
659741 )
660742 }
661743
@@ -664,13 +746,13 @@ use foo::bar::H;",
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