Skip to content

Fix format selection deleting comments when selection ends inside comment trivia#3159

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/fix-js-ts-format-selection-comments
Draft

Fix format selection deleting comments when selection ends inside comment trivia#3159
Copilot wants to merge 4 commits intomainfrom
copilot/fix-js-ts-format-selection-comments

Conversation

Copy link
Contributor

Copilot AI commented Mar 19, 2026

Format Selection deletes block comments when the selection range ends inside the comment. For example, selecting any part of the comment (except the closing /) in const test/* comment */=5; and formatting deletes the comment entirely, producing const test =5;.

Root cause

In consumeTokenAndAdvanceScanner, previousRangeTriviaEnd is set to the end of all trailing trivia unconditionally. When a block comment in the trailing trivia extends past originalRange.End(), processTrivia correctly skips it (not fully contained by the range), but previousRangeTriviaEnd still points past the comment. This makes the trailing edit contiguity check in execute() think previousRange and the next token are adjacent, causing processPair to emit an edit that spans—and deletes—the unprocessed comment.

Fix

In consumeTokenAndAdvanceScanner, after setting previousRangeTriviaEnd, cap it before any comment trivia that is not contained by originalRange. This prevents the contiguity check from pairing across unprocessed comment content, while still allowing legitimate trailing edits when only non-comment trivia (e.g., newlines) extends past the range.

// In consumeTokenAndAdvanceScanner, after setting previousRangeTriviaEnd:
for _, trivia := range currentTokenInfo.trailingTrivia {
    if isComment(trivia.Kind) && !trivia.Loc.ContainedBy(w.originalRange) {
        w.previousRangeTriviaEnd = trivia.Loc.Pos()
        break
    }
}
  • internal/format/span.go: Cap previousRangeTriviaEnd before unprocessed comment trivia in consumeTokenAndAdvanceScanner
  • internal/format/comment_test.go: Regression tests for format selection preserving block comments
Original prompt

This section details on the original issue you should resolve

<issue_title>[bug] JS/TS Format Selection can delete comments</issue_title>
<issue_description>### Extension Version

0.20251214.1

VS Code Version

1.107.0

Operating system Version

Windows 11

Steps to reproduce

  1. open a javascript or typescript file
  2. create a block comment in such a way that a space will be inserted next to it when formatting
const test/* comment */=5;
  1. select any part of the comment (except the ending /)
  2. right click => Format Selection
Image
  1. comment gets deleted ❌
Image
const test =5;

Issue

Format Selection can delete comments

<agent_instructions>Write a test for this FIRST. COMMIT THAT! Then, fix the bug</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits March 19, 2026 06:43
…nside comment

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
…ment trivia

When the selection range ends inside a block comment (e.g., selecting
part of /* comment */ in const test/* comment */=5;), the trailing edit
block's contiguity check would incorrectly pass because
previousRangeTriviaEnd was set to the end of the comment (beyond the
selection range). This caused processPair to generate edits that replaced
the comment text between previousRange and the next token, effectively
deleting the comment.

The fix adds an additional guard: previousRangeTriviaEnd must not exceed
originalRange.End() for the trailing edit to proceed. When trivia extends
beyond the selection range, it was not actually processed, so any edit
spanning that trivia would be bogus.

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copilot AI changed the title [WIP] [bug] Fix JS/TS format selection deleting comments Fix format selection deleting comments when selection ends inside comment trivia Mar 19, 2026
Copilot AI requested a review from jakebailey March 19, 2026 06:47
@jakebailey
Copy link
Member

@copilot you must not have run the tests. you broke formatSelectionEditAtEndOfRange_test

…ectionEditAtEndOfRange

The previous fix added a bounds check in the trailing edit block that was
too broad - it blocked legitimate trailing edits when non-comment trivia
(like newlines) extended past the original range.

The new fix is in consumeTokenAndAdvanceScanner: when setting
previousRangeTriviaEnd, cap it before any comment trivia that extends
past the original range. This way, the contiguity check in execute()
correctly fails for unprocessed comments but still works for legitimate
cases like semicolon removal where only newline trivia extends past.

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 19, 2026

@copilot you must not have run the tests. you broke formatSelectionEditAtEndOfRange_test

Fixed in 82bec94. The previous fix was too broad — it blocked all trailing edits when any trivia extended past the range, including legitimate cases like newline trivia in the semicolon-removal test.

Moved the fix to consumeTokenAndAdvanceScanner instead: when setting previousRangeTriviaEnd, it now caps it before any comment trivia not contained by originalRange. This way newline trivia (like in formatSelectionEditAtEndOfRange) still allows the trailing edit, but unprocessed comment trivia blocks it. Verified all format selection gen tests pass (including formatSelectionEditAtEndOfRange).

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.

[bug] JS/TS Format Selection can delete comments

2 participants