@@ -78,6 +78,9 @@ impl Rustfmt {
78
78
NewlineStyle :: Native => native,
79
79
} ;
80
80
81
+ let lsp_line_length = |line : & str | line. chars ( ) . map ( char:: len_utf16) . sum ( ) ;
82
+ let line_cols: Vec < usize > = input. lines ( ) . map ( lsp_line_length) . collect ( ) ;
83
+
81
84
let output = self . format ( input, cfg) ?;
82
85
let ModifiedLines { chunks } = output. parse ( ) . map_err ( |_| Error :: Failed ) ?;
83
86
@@ -86,15 +89,21 @@ impl Rustfmt {
86
89
. map ( |item| {
87
90
// Rustfmt's line indices are 1-based
88
91
let start_line = u64:: from ( item. line_number_orig ) - 1 ;
89
- // Could underflow if we don't remove lines and there's only one
90
- let removed = u64:: from ( item. lines_removed ) . saturating_sub ( 1 ) ;
92
+ let end_line = {
93
+ // Could underflow if we don't remove lines and there's only one
94
+ let removed = u64:: from ( item. lines_removed ) . saturating_sub ( 1 ) ;
95
+ start_line + removed
96
+ } ;
97
+ let end_col: Option < usize > = line_cols. get ( end_line as usize ) . copied ( ) ;
98
+ let end_col: u64 = end_col. map ( |col| col as u64 ) . unwrap_or_else ( u64:: max_value) ;
99
+
91
100
TextEdit {
92
101
range : Range {
93
102
start : Position :: new ( start_line, 0 ) ,
94
103
// We don't extend the range past the last line because
95
104
// sometimes it may not exist, skewing the diff and
96
105
// making us add an invalid additional trailing newline.
97
- end : Position :: new ( start_line + removed , u64 :: max_value ( ) ) ,
106
+ end : Position :: new ( end_line , end_col ) ,
98
107
} ,
99
108
new_text : item. lines . join ( newline) ,
100
109
}
@@ -202,34 +211,34 @@ mod tests {
202
211
203
212
#[ test]
204
213
fn calc_text_edits ( ) {
205
- let config = || FmtConfig :: default ( ) . get_rustfmt_config ( ) . clone ( ) ;
206
- let format = |x : & str | Rustfmt :: Internal . calc_text_edits ( x. to_string ( ) , config ( ) ) . unwrap ( ) ;
207
- let line_range = |start, end| Range {
208
- start : Position { line : start, character : 0 } ,
209
- end : Position { line : end, character : u64:: max_value ( ) } ,
210
- } ;
211
- // Handle single-line text wrt. added/removed trailing newline
212
- assert_eq ! (
213
- format( "fn main() {} " ) ,
214
- vec![ TextEdit { range: line_range( 0 , 0 ) , new_text: "fn main() {}\n " . to_owned( ) } ]
215
- ) ;
216
-
217
- assert_eq ! (
218
- format( "fn main() {} \n " ) ,
219
- vec![ TextEdit { range: line_range( 0 , 0 ) , new_text: "fn main() {}" . to_owned( ) } ]
220
- ) ;
214
+ fn format ( input : & str ) -> Vec < TextEdit > {
215
+ let config = || FmtConfig :: default ( ) . get_rustfmt_config ( ) . clone ( ) ;
216
+ Rustfmt :: Internal . calc_text_edits ( input. to_string ( ) , config ( ) ) . unwrap ( )
217
+ }
221
218
222
- assert_eq ! (
223
- format( "\n fn main() {} \n " ) ,
224
- vec![ TextEdit { range: line_range( 0 , 1 ) , new_text: "fn main() {}" . to_owned( ) } ]
225
- ) ;
219
+ fn test_case ( input : & str , output : Vec < ( u64 , u64 , u64 , u64 , & str ) > ) {
220
+ assert_eq ! (
221
+ format( input) ,
222
+ output
223
+ . into_iter( )
224
+ . map( |( start_l, start_c, end_l, end_c, out) | TextEdit {
225
+ range: Range {
226
+ start: Position { line: start_l, character: start_c } ,
227
+ end: Position { line: end_l, character: end_c } ,
228
+ } ,
229
+ new_text: out. to_owned( ) ,
230
+ } )
231
+ . collect:: <Vec <_>>( )
232
+ )
233
+ }
234
+ // Handle single-line text wrt. added/removed trailing newline
235
+ test_case ( "fn main() {} " , vec ! [ ( 0 , 0 , 0 , 13 , "fn main() {}\n " ) ] ) ;
236
+ test_case ( "fn main() {} \n " , vec ! [ ( 0 , 0 , 0 , 13 , "fn main() {}" ) ] ) ;
237
+ test_case ( "\n fn main() {} \n " , vec ! [ ( 0 , 0 , 1 , 13 , "fn main() {}" ) ] ) ;
226
238
// Check that we send two separate edits
227
- assert_eq ! (
228
- format( " struct Upper ;\n \n struct Lower ;" ) ,
229
- vec![
230
- TextEdit { range: line_range( 0 , 0 ) , new_text: "struct Upper;" . to_owned( ) } ,
231
- TextEdit { range: line_range( 2 , 2 ) , new_text: "struct Lower;\n " . to_owned( ) }
232
- ]
239
+ test_case (
240
+ " struct Upper ;\n \n struct Lower ;" ,
241
+ vec ! [ ( 0 , 0 , 0 , 16 , "struct Upper;" ) , ( 2 , 0 , 2 , 14 , "struct Lower;\n " ) ] ,
233
242
) ;
234
243
}
235
244
}
0 commit comments