Skip to content

Fix comment loss and misplacement in match arms, nested records, and raw strings#203

Merged
fdncred merged 1 commit into
nushell:mainfrom
xav-ie:fix/match-guard-comment-hoist
Jul 8, 2026
Merged

Fix comment loss and misplacement in match arms, nested records, and raw strings#203
fdncred merged 1 commit into
nushell:mainfrom
xav-ie:fix/match-guard-comment-hoist

Conversation

@xav-ie

@xav-ie xav-ie commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Description of changes

Fixes three formatter bugs that silently lose or misplace comments, several of which also make formatting non-idempotent (running the formatter repeatedly keeps changing the file). Each has a ground-truth + idempotency fixture.

1. Parenthesized match-arm guards vacuum nearby comments into (

A match arm with a parenthesized guard (pat if (EXPR) => body) pulled surrounding standalone comments inside the guard's (:

# before
match $x {
  a => 1
  # a comment between arms
  b if ($y | foo) == 'z' => 2
}
# after (buggy)
match $x {
    a => 1
    b if (
# a comment between arms
$y | foo) == 'z' => 2
}

The guard is rendered in a probe_format sub-formatter whose comment cursor was reset to the start of file, so the parenthesized sub-expression re-flushed every not-yet-written comment. Fix: seed each arm's probe with the pattern's own start position, and emit arm-preceding comments at the arm boundary in format_match_block (a bare guard if $y == 'z' previously dropped the same comment entirely).

2. Nested records collapse inline and drop field comments

# before
$env.config = {
  trim: {
    # wrapping or truncating
    methodology: wrapping
  }
}
# after (buggy)  ->  comment gone, inner record collapsed
$env.config = {
  trim: {methodology: wrapping}
}

The record layout decision only preserved source newlines at the top level and never checked for comments, so a short nested record took the inline path — which emits fields without write_comments_before. Fix: force multiline when the record span contains comments, using the same has_comments_in_span guard format_list already applies.

3. r#'…'# raw strings derail comment extraction

A raw string with hash delimiters containing # caused extract_comments to mis-lex: the # in r#' started a bogus comment and the closing '# opened a phantom string that swallowed real comments until the next stray apostrophe — deleting ~1 comment per pass (non-idempotent). Fix: teach extract_comments to skip r#'…'# (and multi-hash variants) and consume each quoted string inline so an unterminated string can't bleed across the file; single-quoted strings are treated as raw (no backslash escapes).

Testing

cargo test — full suite green (273 tests, incl. 7 new fixtures). All three cases verified idempotent.

Relevant Issues

None found open; happy to file tracking issues if preferred.

- match-arm guards no longer hoist or drop neighboring comments
- nested records stay multiline instead of collapsing and eating field comments
- extract_comments skips r#'...'# raw strings (were eaten, non-idempotent)
@xav-ie xav-ie marked this pull request as ready for review July 8, 2026 21:21
@fdncred fdncred merged commit 1a43bfd into nushell:main Jul 8, 2026
5 checks passed
@fdncred

fdncred commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Thanks

xav-ie added a commit to xav-ie/dots that referenced this pull request Jul 8, 2026
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.

2 participants