@@ -7,6 +7,7 @@ use syntax::{
7
7
SyntaxKind :: { self , USE_TREE , WHITESPACE } ,
8
8
SyntaxNode , SyntaxToken , TextRange , TextSize , T ,
9
9
} ;
10
+ use test_utils:: mark;
10
11
use text_edit:: { TextEdit , TextEditBuilder } ;
11
12
12
13
// Feature: Join Lines
@@ -44,9 +45,9 @@ pub(crate) fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
44
45
let text = token. text ( ) ;
45
46
for ( pos, _) in text[ range] . bytes ( ) . enumerate ( ) . filter ( |& ( _, b) | b == b'\n' ) {
46
47
let pos: TextSize = ( pos as u32 ) . into ( ) ;
47
- let off = token. text_range ( ) . start ( ) + range. start ( ) + pos;
48
- if !edit. invalidates_offset ( off ) {
49
- remove_newline ( & mut edit, & token, off ) ;
48
+ let offset = token. text_range ( ) . start ( ) + range. start ( ) + pos;
49
+ if !edit. invalidates_offset ( offset ) {
50
+ remove_newline ( & mut edit, & token, offset ) ;
50
51
}
51
52
}
52
53
}
@@ -56,14 +57,25 @@ pub(crate) fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
56
57
57
58
fn remove_newline ( edit : & mut TextEditBuilder , token : & SyntaxToken , offset : TextSize ) {
58
59
if token. kind ( ) != WHITESPACE || token. text ( ) . bytes ( ) . filter ( |& b| b == b'\n' ) . count ( ) != 1 {
59
- // The node is either the first or the last in the file
60
- let suff = & token. text ( ) [ TextRange :: new (
61
- offset - token. text_range ( ) . start ( ) + TextSize :: of ( '\n' ) ,
62
- TextSize :: of ( token. text ( ) ) ,
63
- ) ] ;
64
- let spaces = suff. bytes ( ) . take_while ( |& b| b == b' ' ) . count ( ) ;
65
-
66
- edit. replace ( TextRange :: at ( offset, ( ( spaces + 1 ) as u32 ) . into ( ) ) , " " . to_string ( ) ) ;
60
+ let mut string_open_quote = false ;
61
+ if let Some ( string) = ast:: String :: cast ( token. clone ( ) ) {
62
+ if let Some ( range) = string. open_quote_text_range ( ) {
63
+ mark:: hit!( join_string_literal) ;
64
+ string_open_quote = range. end ( ) == offset;
65
+ }
66
+ }
67
+
68
+ let n_spaces_after_line_break = {
69
+ let suff = & token. text ( ) [ TextRange :: new (
70
+ offset - token. text_range ( ) . start ( ) + TextSize :: of ( '\n' ) ,
71
+ TextSize :: of ( token. text ( ) ) ,
72
+ ) ] ;
73
+ suff. bytes ( ) . take_while ( |& b| b == b' ' ) . count ( )
74
+ } ;
75
+
76
+ let range = TextRange :: at ( offset, ( ( n_spaces_after_line_break + 1 ) as u32 ) . into ( ) ) ;
77
+ let replace_with = if string_open_quote { "" } else { " " } ;
78
+ edit. replace ( range, replace_with. to_string ( ) ) ;
67
79
return ;
68
80
}
69
81
@@ -194,7 +206,7 @@ fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str {
194
206
#[ cfg( test) ]
195
207
mod tests {
196
208
use syntax:: SourceFile ;
197
- use test_utils:: { add_cursor, assert_eq_text, extract_offset, extract_range} ;
209
+ use test_utils:: { add_cursor, assert_eq_text, extract_offset, extract_range, mark } ;
198
210
199
211
use super :: * ;
200
212
@@ -771,4 +783,42 @@ fn foo() {
771
783
" ,
772
784
) ;
773
785
}
786
+
787
+ #[ test]
788
+ fn join_string_literal ( ) {
789
+ mark:: check!( join_string_literal) ;
790
+ check_join_lines (
791
+ r#"
792
+ fn main() {
793
+ $0"
794
+ hello
795
+ ";
796
+ }
797
+ "# ,
798
+ r#"
799
+ fn main() {
800
+ $0"hello
801
+ ";
802
+ }
803
+ "# ,
804
+ ) ;
805
+
806
+ check_join_lines (
807
+ r#"
808
+ fn main() {
809
+ "
810
+ $0hello
811
+ world
812
+ ";
813
+ }
814
+ "# ,
815
+ r#"
816
+ fn main() {
817
+ "
818
+ $0hello world
819
+ ";
820
+ }
821
+ "# ,
822
+ ) ;
823
+ }
774
824
}
0 commit comments