Skip to content

Commit dfc3f31

Browse files
committed
Fix handling of unaligned comments
1 parent c2e5ca7 commit dfc3f31

File tree

1 file changed

+58
-21
lines changed

1 file changed

+58
-21
lines changed

src/visitor.rs

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -236,58 +236,95 @@ 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
debug!("close_block: {:?} {:?} {:?}", kind, offset, sub_slice);
259266

260267
match kind {
261268
CodeCharKind::Comment => {
262-
if !unindented && unindent_comment {
263-
unindented = true;
264-
self.block_indent = self.block_indent.block_unindent(config);
265-
}
266-
let span_in_between = mk_sp(last_hi, span.lo() + BytePos::from_usize(offset));
267-
let snippet_in_between = self.snippet(span_in_between);
268-
let mut comment_on_same_line = !snippet_in_between.contains("\n")
269-
&& !last_line_contains_single_line_comment(&self.buffer);
270-
271-
let comment_shape =
272-
Shape::indented(self.block_indent, config).comment(config);
273-
269+
let comment_shape = if newline_inserted {
270+
self.shape().comment(self.config)
271+
} else {
272+
Shape {
273+
width: self.config.comment_width(),
274+
indent: Indent::from_width(self.config, last_line_offset),
275+
offset: 0,
276+
}
277+
};
274278
let comment_str = rewrite_comment(&sub_slice, false, comment_shape, config);
279+
if self
280+
.buffer
281+
.chars()
282+
.last()
283+
.map_or(false, |c| !c.is_whitespace() && c != '/')
284+
{
285+
self.push_str(" ");
286+
}
275287
match comment_str {
276288
Some(ref s) => self.push_str(s),
277289
None => self.push_str(&sub_slice),
278290
}
279291
}
280292
CodeCharKind::Normal if skip_normal(&sub_slice) => {
293+
prev_kind = kind;
281294
continue;
282295
}
283296
CodeCharKind::Normal => {
297+
let prev_is_comment = prev_kind == CodeCharKind::Comment;
298+
prev_kind = kind;
299+
300+
if iter.peek().is_none() {
301+
continue;
302+
}
303+
304+
match count_newlines(&sub_slice) {
305+
0 if !prev_is_comment
306+
|| !last_line_contains_single_line_comment(&self.buffer) =>
307+
{
308+
self.push_str(" ");
309+
continue;
310+
}
311+
0 => (),
312+
1 if prev_is_comment
313+
&& last_line_contains_single_line_comment(&self.buffer) =>
314+
{
315+
self.push_str("\n")
316+
}
317+
1 => (),
318+
_ => self.push_str("\n"),
319+
}
320+
newline_inserted = true;
321+
284322
self.push_str(&self.block_indent.to_string_with_newline(config));
285-
self.push_str(sub_slice.trim());
286323
}
287324
}
288-
last_hi = span.lo() + BytePos::from_usize(offset + sub_slice.len());
325+
prev_kind = kind;
289326
}
290-
if unindented {
327+
if unindent_comment {
291328
self.block_indent = self.block_indent.block_indent(self.config);
292329
}
293330
self.block_indent = self.block_indent.block_unindent(self.config);

0 commit comments

Comments
 (0)