From 3cae5f58c5c114edc26385648e513c704f431f28 Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Mon, 28 Sep 2026 22:22:36 -0400 Subject: [PATCH] fmt: format comments block & line comments --- crates/squawk_fmt/src/comment.rs | 23 +++++++++++-- crates/squawk_fmt/src/token_compare.rs | 38 ++++++++++++++++++--- crates/squawk_fmt/tests/after/comments.snap | 22 ++++++++++++ crates/squawk_fmt/tests/before/comments.sql | 24 ++++++++++++- 4 files changed, 99 insertions(+), 8 deletions(-) diff --git a/crates/squawk_fmt/src/comment.rs b/crates/squawk_fmt/src/comment.rs index 987118ebd..15d950ceb 100644 --- a/crates/squawk_fmt/src/comment.rs +++ b/crates/squawk_fmt/src/comment.rs @@ -1,5 +1,5 @@ use rowan::Direction; -use squawk_line_index::find_newline; +use squawk_line_index::{UniversalNewlines, find_newline}; use squawk_syntax::{SyntaxElement, SyntaxKind, SyntaxToken}; use tiny_pretty::Doc; @@ -8,7 +8,26 @@ pub(crate) fn is_line_comment(token: &SyntaxToken) -> bool { } pub(crate) fn build_comment<'a>(token: &SyntaxToken) -> Doc<'a> { - let line = |text: &str| Doc::text(text.trim_end_matches([' ', '\t']).to_string()); + let align_stars = !is_line_comment(token) + && find_newline(token.text()).is_some() + && token + .text() + .universal_newlines() + .skip(1) + .all(|line| line.as_str().trim_start().starts_with('*')); + let line = |text: &str| { + let text = text.trim_end_matches([' ', '\t']); + if is_line_comment(token) { + if let Some(content) = text.strip_prefix("--") { + if !content.is_empty() && !content.starts_with(' ') && !content.starts_with('\t') { + return Doc::text(format!("-- {content}")); + } + } + } else if align_stars && text.trim_start().starts_with('*') { + return Doc::text(format!(" {}", text.trim())); + } + Doc::text(text.to_string()) + }; let mut docs = vec![]; let mut text = token.text(); while let Some((position, line_ending)) = find_newline(text) { diff --git a/crates/squawk_fmt/src/token_compare.rs b/crates/squawk_fmt/src/token_compare.rs index c4767c85e..c103722a8 100644 --- a/crates/squawk_fmt/src/token_compare.rs +++ b/crates/squawk_fmt/src/token_compare.rs @@ -14,18 +14,46 @@ fn meaningful_tokens(text: &str) -> Vec<(TokenKind, &str)> { tokens } +fn line_comments_equivalent(before: &str, after: &str) -> bool { + let before = before.trim_end_matches([' ', '\t']); + let after = after.trim_end_matches([' ', '\t']); + if before == after { + return true; + } + + let Some(content) = before.strip_prefix("--") else { + return false; + }; + if content.is_empty() || content.starts_with(' ') || content.starts_with('\t') { + return false; + } + + after.strip_prefix("-- ") == Some(content) +} + fn tokens_equivalent(before: (TokenKind, &str), after: (TokenKind, &str)) -> bool { let (before_kind, before_text) = before; let (after_kind, after_text) = after; if before_kind == after_kind { - if matches!( - before_kind, - TokenKind::LineComment | TokenKind::BlockComment { .. } - ) { + if before_kind == TokenKind::LineComment { + return line_comments_equivalent(before_text, after_text); + } + if matches!(before_kind, TokenKind::BlockComment { .. }) { let normalize = |text: &str| { + let align_stars = text + .universal_newlines() + .skip(1) + .all(|line| line.as_str().trim_start().starts_with('*')); text.universal_newlines() - .map(|line| line.as_str().trim_end_matches([' ', '\t'])) + .map(|line| { + let line = line.as_str().trim_end_matches([' ', '\t']); + if align_stars && line.trim_start().starts_with('*') { + format!(" {}", line.trim()) + } else { + line.to_string() + } + }) .collect::>() .join("\n") }; diff --git a/crates/squawk_fmt/tests/after/comments.snap b/crates/squawk_fmt/tests/after/comments.snap index bfa7dca47..885a7a0f7 100644 --- a/crates/squawk_fmt/tests/after/comments.snap +++ b/crates/squawk_fmt/tests/after/comments.snap @@ -20,3 +20,25 @@ input_file: crates/squawk_fmt/tests/before/comments.sql -- we have a big gap here, but we should only output a couple lines at most /* end */ + +/* + * + * + * + */ +select 1; + +/* +* + +* +*/ +select 1; + +/* + * text + */ +select 1; + +/*foo*/ +select 1; diff --git a/crates/squawk_fmt/tests/before/comments.sql b/crates/squawk_fmt/tests/before/comments.sql index ad00ec827..bdaa1933f 100644 --- a/crates/squawk_fmt/tests/before/comments.sql +++ b/crates/squawk_fmt/tests/before/comments.sql @@ -4,7 +4,7 @@ * */ --- intentional new line follows, we should keep that +--intentional new line follows, we should keep that /* bar */ /* followed by another comment */ @@ -25,3 +25,25 @@ /* end */ + +/* +* +* +* +*/ +select 1; + +/* +* + +* +*/ +select 1; + +/* + * text + */ +select 1; + +/*foo*/ +select 1;