You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit a945ece
Browse filesBrowse the repository at this point in the historyBrowse files
Format a blank line around module items that span several lines
Why:
Dense code, often written by AI agents, runs multi-line modules and
functions together, which makes a file hard to scan (#8960). The
formatter already collapses several blank lines into one; it now also
separates an item that prints on more than one line from its
neighbours in structures and signatures. Blocks inside expressions
keep their layout.
Format modified (structure items):
Example:
module Details = {
let make = () => React.string("details")
}
module Output = Tool.TextResult.Output
let failed = Tool.TextResult.failed
Before (rescript):
module Details = {
let make = () => React.string("details")
}
module Output = Tool.TextResult.Output
let failed = Tool.TextResult.failed
After (rescript):
module Details = {
let make = () => React.string("details")
}
module Output = Tool.TextResult.Output
let failed = Tool.TextResult.failed
Format unchanged (one-line items with comments):
Example:
let a = 1
// about b
let b = 2 // trailing
let c = 3
After (rescript):
let a = 1
// about b
let b = 2 // trailing
let c = 3
Review: Is "multi-line" decided on the source or on the output? On the output: the new Res_doc.item_separator measures the items on each side with the printer's own layout decisions, stopping at the first line break, so an item that only breaks at the line width counts and formatting twice gives the same text. The source line span (`let x = someLongCall(a, b, c, d)` is one source line but prints on several) and Doc.will_break (a record that wraps by width is force-broken only on the second pass) would both add the blank line only on the second format. The measurement costs at most one output line per item. The roundtrip test formats every printer fixture twice and gets the same text.
Review: Why a Res_doc.comment marker? Leading comments print inside the item's document (a value binding carries them), so a `//` line above a one-line item would make it multi-line, even when the item is measured before print_list adds its own comments. The marker keeps comments out of the measurement; doc comments are attributes and still count.
Review: Why move own-line trailing comments below the blank line? A comment inside the previous item's source, such as `f(a // c => 1)`, prints on its own line after the item. Formatting again makes it a leading comment of the next item, after the blank line, so the first pass puts it there too.
Review: How are the measurement's branches tested? tests/syntax_tests/res_test.ml prints documents built for each case (line breaks, groups that fit and break, if_breaks, comments, trailing comments) and checks the output, as the printer fixtures do not reach every branch first.
Review: What else prints through it? The editor's code actions and `rescript-tools format-codeblocks` for code blocks in docstrings, so the Xform and FormatDocstringsTest2 snapshots gain a blank line.
Review: Do attributes count? Yes, an attribute or doc comment on its own line makes an item print on two lines, so runs of `@genType` or documented one-line items are spaced; an inline `@val external` is not. The fixtures cover both, and nested module bodies.
Review: Does a string literal with a line break count? Yes: it prints on several lines, like a template literal, so the line-ending test in res_test.ml separates such items with a blank line, in the file's own line endings.
Review: Is it opt-in? No: every `rescript format` uses it. The next commit formats this repository with it.
Signed-off-by: Roland Peelen <roland@magic.dev>
0 commit comments