Skip to content

Commit e4d4969

Browse files
committed
Fix handling of unaligned comments
1 parent 63a7590 commit e4d4969

File tree

1 file changed

+55
-38
lines changed

1 file changed

+55
-38
lines changed

src/visitor.rs

+55-38
Original file line numberDiff line numberDiff line change
@@ -236,79 +236,96 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
236236
fn close_block(&mut self, span: Span, unindent_comment: bool) {
237237
let config = self.config;
238238

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;
241241

242242
let skip_normal = |s: &str| {
243243
let trimmed = s.trim();
244-
trimmed.is_empty() || trimmed.chars().all(|c| c == ';')
244+
!trimmed.is_empty() && trimmed.chars().all(|c| c == ';')
245245
};
246246

247247
let last_line_offset = if last_line_contains_single_line_comment(&self.buffer) {
248248
0
249249
} else {
250-
last_line_width(&self.buffer)
250+
last_line_width(&self.buffer) + 1
251251
};
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(
253258
self.snippet(span),
254259
last_line_offset,
255260
self.config.tab_spaces(),
256-
) {
261+
)
262+
.peekable();
263+
while let Some((kind, offset, sub_slice)) = iter.next() {
257264
let sub_slice = transform_missing_snippet(config, sub_slice);
258265

259266
debug!("close_block: {:?} {:?} {:?}", kind, offset, sub_slice);
260267

261268
match kind {
262269
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,
283277
}
284278
};
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+
{
287286
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));
293287
}
294-
295-
let comment_str = rewrite_comment(&sub_slice, false, comment_shape, config);
296288
match comment_str {
297289
Some(ref s) => self.push_str(s),
298290
None => self.push_str(&sub_slice),
299291
}
300292
}
301293
CodeCharKind::Normal if skip_normal(&sub_slice) => {
294+
prev_kind = kind;
302295
continue;
303296
}
304297
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+
305323
self.push_str(&self.block_indent.to_string_with_newline(config));
306-
self.push_str(sub_slice.trim());
307324
}
308325
}
309-
last_hi = span.lo() + BytePos::from_usize(offset + sub_slice.len());
326+
prev_kind = kind;
310327
}
311-
if unindented {
328+
if unindent_comment {
312329
self.block_indent = self.block_indent.block_indent(self.config);
313330
}
314331
self.block_indent = self.block_indent.block_unindent(self.config);

0 commit comments

Comments
 (0)