@@ -70,9 +70,11 @@ impl<'a> ListFormatting<'a> {
70
70
71
71
pub struct ListItem {
72
72
pub pre_comment : Option < String > ,
73
- // Item should include attributes and doc comments
73
+ // Item should include attributes and doc comments.
74
74
pub item : String ,
75
75
pub post_comment : Option < String > ,
76
+ // Whether there is extra whitespace before this item.
77
+ pub new_lines : bool ,
76
78
}
77
79
78
80
impl ListItem {
@@ -86,7 +88,7 @@ impl ListItem {
86
88
}
87
89
88
90
pub fn from_str < S : Into < String > > ( s : S ) -> ListItem {
89
- ListItem { pre_comment : None , item : s. into ( ) , post_comment : None }
91
+ ListItem { pre_comment : None , item : s. into ( ) , post_comment : None , new_lines : false }
90
92
}
91
93
}
92
94
@@ -206,10 +208,8 @@ pub fn write_list<'b>(items: &[ListItem], formatting: &ListFormatting<'b>) -> St
206
208
207
209
// Post-comments
208
210
if tactic != ListTactic :: Vertical && item. post_comment . is_some ( ) {
209
- let formatted_comment = rewrite_comment ( item. post_comment . as_ref ( ) . unwrap ( ) ,
210
- true ,
211
- formatting. v_width ,
212
- 0 ) ;
211
+ let comment = item. post_comment . as_ref ( ) . unwrap ( ) ;
212
+ let formatted_comment = rewrite_comment ( comment, true , formatting. v_width , 0 ) ;
213
213
214
214
result. push ( ' ' ) ;
215
215
result. push_str ( & formatted_comment) ;
@@ -234,6 +234,10 @@ pub fn write_list<'b>(items: &[ListItem], formatting: &ListFormatting<'b>) -> St
234
234
result. push ( ' ' ) ;
235
235
result. push_str ( & formatted_comment) ;
236
236
}
237
+
238
+ if !last && tactic == ListTactic :: Vertical && item. new_lines {
239
+ result. push ( '\n' ) ;
240
+ }
237
241
}
238
242
239
243
result
@@ -264,13 +268,14 @@ impl<'a, T, I, F1, F2, F3> Iterator for ListItems<'a, I, F1, F2, F3>
264
268
let white_space: & [ _ ] = & [ ' ' , '\t' ] ;
265
269
266
270
self . inner . next ( ) . map ( |item| {
271
+ let mut new_lines = false ;
267
272
// Pre-comment
268
273
let pre_snippet = self . codemap . span_to_snippet ( codemap:: mk_sp ( self . prev_span_end ,
269
274
( self . get_lo ) ( & item) ) )
270
275
. unwrap ( ) ;
271
- let pre_snippet = pre_snippet. trim ( ) ;
272
- let pre_comment = if !pre_snippet . is_empty ( ) {
273
- Some ( pre_snippet . to_owned ( ) )
276
+ let trimmed_pre_snippet = pre_snippet. trim ( ) ;
277
+ let pre_comment = if !trimmed_pre_snippet . is_empty ( ) {
278
+ Some ( trimmed_pre_snippet . to_owned ( ) )
274
279
} else {
275
280
None
276
281
} ;
@@ -307,7 +312,7 @@ impl<'a, T, I, F1, F2, F3> Iterator for ListItems<'a, I, F1, F2, F3>
307
312
separator_index + 1 )
308
313
}
309
314
// Potential *single* line comment.
310
- ( _, Some ( j) ) => { j + 1 }
315
+ ( _, Some ( j) ) => j + 1 ,
311
316
_ => post_snippet. len ( )
312
317
}
313
318
} ,
@@ -317,18 +322,40 @@ impl<'a, T, I, F1, F2, F3> Iterator for ListItems<'a, I, F1, F2, F3>
317
322
}
318
323
} ;
319
324
325
+ if !post_snippet. is_empty ( ) && comment_end > 0 {
326
+ // Account for extra whitespace between items. This is fiddly
327
+ // because of the way we divide pre- and post- comments.
328
+
329
+ // Everything from the separator to the next item.
330
+ let test_snippet = & post_snippet[ comment_end-1 ..] ;
331
+ let first_newline = test_snippet. find ( '\n' ) . unwrap_or ( test_snippet. len ( ) ) ;
332
+ // From the end of the first line of comments.
333
+ let test_snippet = & test_snippet[ first_newline..] ;
334
+ let first = test_snippet. find ( |c : char | !c. is_whitespace ( ) )
335
+ . unwrap_or ( test_snippet. len ( ) ) ;
336
+ // From the end of the first line of comments to the next non-whitespace char.
337
+ let test_snippet = & test_snippet[ ..first] ;
338
+
339
+ if test_snippet. chars ( ) . filter ( |c| c == & '\n' ) . count ( ) > 1 {
340
+ // There were multiple line breaks which got trimmed to nothing.
341
+ new_lines = true ;
342
+ }
343
+ }
344
+
320
345
// Cleanup post-comment: strip separators and whitespace.
321
346
self . prev_span_end = ( self . get_hi ) ( & item) + BytePos ( comment_end as u32 ) ;
322
- let mut post_snippet = post_snippet[ ..comment_end] . trim ( ) ;
347
+ let post_snippet = post_snippet[ ..comment_end] . trim ( ) ;
323
348
324
- if post_snippet. starts_with ( ',' ) {
325
- post_snippet = post_snippet [ 1 ..] . trim_matches ( white_space) ;
349
+ let post_snippet_trimmed = if post_snippet. starts_with ( ',' ) {
350
+ post_snippet[ 1 ..] . trim_matches ( white_space)
326
351
} else if post_snippet. ends_with ( "," ) {
327
- post_snippet = post_snippet[ ..( post_snippet. len ( ) - 1 ) ] . trim_matches ( white_space) ;
328
- }
352
+ post_snippet[ ..( post_snippet. len ( ) - 1 ) ] . trim_matches ( white_space)
353
+ } else {
354
+ post_snippet
355
+ } ;
329
356
330
- let post_comment = if !post_snippet . is_empty ( ) {
331
- Some ( post_snippet . to_owned ( ) )
357
+ let post_comment = if !post_snippet_trimmed . is_empty ( ) {
358
+ Some ( post_snippet_trimmed . to_owned ( ) )
332
359
} else {
333
360
None
334
361
} ;
@@ -337,6 +364,7 @@ impl<'a, T, I, F1, F2, F3> Iterator for ListItems<'a, I, F1, F2, F3>
337
364
pre_comment : pre_comment,
338
365
item : ( self . get_item_string ) ( & item) ,
339
366
post_comment : post_comment,
367
+ new_lines : new_lines,
340
368
}
341
369
} )
342
370
}
0 commit comments