@@ -236,79 +236,96 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
236
236
fn close_block ( & mut self , span : Span , unindent_comment : bool ) {
237
237
let config = self . config ;
238
238
239
- let mut last_hi = span . lo ( ) ;
240
- let mut unindented = false ;
239
+ let mut prev_kind = CodeCharKind :: Normal ;
240
+ let mut newline_inserted = false ;
241
241
242
242
let skip_normal = |s : & str | {
243
243
let trimmed = s. trim ( ) ;
244
- trimmed. is_empty ( ) || trimmed. chars ( ) . all ( |c| c == ';' )
244
+ ! trimmed. is_empty ( ) && trimmed. chars ( ) . all ( |c| c == ';' )
245
245
} ;
246
246
247
247
let last_line_offset = if last_line_contains_single_line_comment ( & self . buffer ) {
248
248
0
249
249
} else {
250
- last_line_width ( & self . buffer )
250
+ last_line_width ( & self . buffer ) + 1
251
251
} ;
252
- for ( kind, offset, sub_slice) in CommentCodeSlices :: with_offset (
252
+
253
+ if unindent_comment {
254
+ self . block_indent = self . block_indent . block_unindent ( config) ;
255
+ }
256
+
257
+ let mut iter = CommentCodeSlices :: with_offset (
253
258
self . snippet ( span) ,
254
259
last_line_offset,
255
260
self . config . tab_spaces ( ) ,
256
- ) {
261
+ )
262
+ . peekable ( ) ;
263
+ while let Some ( ( kind, offset, sub_slice) ) = iter. next ( ) {
257
264
let sub_slice = transform_missing_snippet ( config, sub_slice) ;
258
265
259
266
debug ! ( "close_block: {:?} {:?} {:?}" , kind, offset, sub_slice) ;
260
267
261
268
match kind {
262
269
CodeCharKind :: Comment => {
263
- if !unindented && unindent_comment {
264
- unindented = true ;
265
- self . block_indent = self . block_indent . block_unindent ( config) ;
266
- }
267
- let span_in_between = mk_sp ( last_hi, span. lo ( ) + BytePos :: from_usize ( offset) ) ;
268
- let snippet_in_between = self . snippet ( span_in_between) ;
269
- let mut comment_on_same_line = !snippet_in_between. contains ( "\n " )
270
- && !last_line_contains_single_line_comment ( & self . buffer ) ;
271
-
272
- let comment_shape = Shape :: indented ( self . block_indent , config) . comment ( config) ;
273
- if comment_on_same_line {
274
- // 1 = a space before `//`
275
- let offset_len = 1 + last_line_width ( & self . buffer )
276
- . saturating_sub ( self . block_indent . width ( ) ) ;
277
- match comment_shape
278
- . visual_indent ( offset_len)
279
- . sub_width ( offset_len)
280
- {
281
- Some ( shp) => comment_shape = shp,
282
- None => comment_on_same_line = false ,
270
+ let comment_shape = if newline_inserted {
271
+ self . shape ( ) . comment ( self . config )
272
+ } else {
273
+ Shape {
274
+ width : self . config . comment_width ( ) ,
275
+ indent : Indent :: from_width ( self . config , last_line_offset) ,
276
+ offset : 0 ,
283
277
}
284
278
} ;
285
-
286
- if comment_on_same_line {
279
+ let comment_str = rewrite_comment ( & sub_slice, false , comment_shape, config) ;
280
+ if self
281
+ . buffer
282
+ . chars ( )
283
+ . last ( )
284
+ . map_or ( false , |c| !c. is_whitespace ( ) && c != '/' )
285
+ {
287
286
self . push_str ( " " ) ;
288
- } else {
289
- if count_newlines ( snippet_in_between) >= 2 || extra_newline {
290
- self . push_str ( "\n " ) ;
291
- }
292
- self . push_str ( & self . block_indent . to_string_with_newline ( config) ) ;
293
287
}
294
-
295
- let comment_str = rewrite_comment ( & sub_slice, false , comment_shape, config) ;
296
288
match comment_str {
297
289
Some ( ref s) => self . push_str ( s) ,
298
290
None => self . push_str ( & sub_slice) ,
299
291
}
300
292
}
301
293
CodeCharKind :: Normal if skip_normal ( & sub_slice) => {
294
+ prev_kind = kind;
302
295
continue ;
303
296
}
304
297
CodeCharKind :: Normal => {
298
+ let prev_is_comment = prev_kind == CodeCharKind :: Comment ;
299
+ prev_kind = kind;
300
+
301
+ if iter. peek ( ) . is_none ( ) {
302
+ continue ;
303
+ }
304
+
305
+ match count_newlines ( & sub_slice) {
306
+ 0 if !prev_is_comment
307
+ || !last_line_contains_single_line_comment ( & self . buffer ) =>
308
+ {
309
+ self . push_str ( " " ) ;
310
+ continue ;
311
+ }
312
+ 0 => ( ) ,
313
+ 1 if prev_is_comment
314
+ && last_line_contains_single_line_comment ( & self . buffer ) =>
315
+ {
316
+ self . push_str ( "\n " )
317
+ }
318
+ 1 => ( ) ,
319
+ _ => self . push_str ( "\n " ) ,
320
+ }
321
+ newline_inserted = true ;
322
+
305
323
self . push_str ( & self . block_indent . to_string_with_newline ( config) ) ;
306
- self . push_str ( sub_slice. trim ( ) ) ;
307
324
}
308
325
}
309
- last_hi = span . lo ( ) + BytePos :: from_usize ( offset + sub_slice . len ( ) ) ;
326
+ prev_kind = kind ;
310
327
}
311
- if unindented {
328
+ if unindent_comment {
312
329
self . block_indent = self . block_indent . block_indent ( self . config ) ;
313
330
}
314
331
self . block_indent = self . block_indent . block_unindent ( self . config ) ;
0 commit comments