Skip to content

Standardise blank lines in the formatter - #7523

Open
ewels wants to merge 1 commit into
formatter-fmt-directivesfrom
formatter-blank-lines
Open

Standardise blank lines in the formatter#7523
ewels wants to merge 1 commit into
formatter-fmt-directivesfrom
formatter-blank-lines

Conversation

@ewels

@ewels ewels commented Aug 21, 2026

Copy link
Copy Markdown
Member

The policy (PEP8/Ruff-style):

  • exactly 2 blank lines around top-level block definitions (process, workflow, function, params, output, record, enum, agent), and between a definition and any adjacent declaration;
  • simple declarations (includes, feature flags, legacy params) stay grouped, with runs of blank lines collapsed to at most one;
  • process and workflow sections stay separated by exactly 1 blank line (this is Blank line above process / workflow blocks language-server#150);
  • blank lines at the start of a block or section are removed;
  • a shebang is followed by exactly 1 blank line;
  • runs of blank lines anywhere else collapse to at most 1.
  • Verbatim regions (fmt: off / fmt: skip, from the PR below this one) keep their original spacing untouched.

Notes:

Two decisions worth a look in review, both intentional and easy to change:

  • Exactly 2 blank lines around top-level definitions, and the feature is always on (not behind an option) — this is the most opinionated part and follows the PEP8 mapping requested in the issue.
  • Config blocks are set off by 1 blank line rather than 2, since config files are denser than script definitions.

Mechanically, top-level spacing is now driven by policy in the declaration loop (blankLinesBetween(prev, decl)) rather than derived from each node's source position; the within-line collapse stays a stateless re-derivation from the source, and blank lines at a block/section start are dropped via a small atBlockStart flag set by each opener.

Example

Before:

include { FOO } from './modules/foo.nf'
process ALIGN {
    input:
    path reads


    script:
    'echo'
}



workflow {
    ALIGN(reads)
}

After:

include { FOO } from './modules/foo.nf'


process ALIGN {
    input:
    path reads

    script:
    'echo'
}


workflow {
    ALIGN(reads)
}

The include block is separated from the process by 2 blank lines (a definition), the run of blanks before script: collapses to the single blank that separates sections, and the 3 blank lines before workflow normalise to 2.

Assisted-by: Claude Opus 4.8 (Claude Code)

Normalise the number of blank lines, PEP8/Ruff-style:

- exactly 2 blank lines around top-level block definitions (process,
  workflow, function, params, output, record, enum, agent), and between
  a definition and any adjacent declaration;
- simple declarations (includes, feature flags, legacy params) stay
  grouped, with runs collapsed to at most one blank line;
- process and workflow sections stay separated by exactly one blank line
  (issue #150);
- blank lines at the start of a block or section are removed;
- a shebang is followed by exactly one blank line;
- runs of blank lines anywhere else collapse to at most one.

Config files get the same treatment, with config blocks set off by one
blank line (config is denser than script definitions). Verbatim regions
(`fmt: off` / `fmt: skip`) keep their original spacing.

Top-level spacing is now driven by policy in the declaration loop rather
than derived from the source position of each node; the within-line blank
collapse stays a stateless re-derivation from the source.

Assisted-by: Claude Opus 4.8 (Claude Code)
Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
@ewels
ewels requested a review from a team as a code owner August 21, 2026 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant