fix(vscode): allow shrinking prompt mention selections - #11936
Conversation
| if (endRange) { | ||
| const shrink = dir === "forward" && last?.start === start && last.end === endRange.end | ||
| snappedEnd = shrink ? endRange.start : endRange.end | ||
| } |
There was a problem hiding this comment.
WARNING: Shrink can collapse the selection to empty when the anchor sits exactly on the mention boundary
Both shrink branches snap the moving edge to the opposite mention boundary (startRange.end for backward, endRange.start for forward). This works when the fixed anchor is outside the mention with some text between them (as in the new tests), but when the anchor itself coincides with the mention's own boundary, the opposite boundary equals the anchor position, so the shrink collapses the selection to zero length instead of leaving a sensible selection.
This is reachable in an ordinary case: a mention at the very start of the text (@README.md rest of text), with the cursor placed right before it. Shift+Right across the mention snaps to a full-mention selection (0, 11) with dir === "forward" and anchor start === 0. Pressing Shift+Left to shrink then hits shrink = true with endRange.start === 0 === start, so snappedEnd becomes 0 too, producing an empty selection at position 0 instead of shrinking back to "just before the mention" as intended. The mirrored case (mention at the very end of the text, anchor at text.length coinciding with end_mention) collapses the same way for the backward direction.
Worth guarding against snapped === end / snappedEnd === start (or otherwise detecting anchor-on-boundary) so the shrink doesn't zero out the selection. It may also be worth adding a test for the forward-direction shrink path (current tests only cover backward), which would have caught this.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
There was a problem hiding this comment.
I think the zero-length selection here is expected.
In a textarea, selectionStart === 0 and selectionEnd === 0 means the caret is positioned just before the first character. So for a mention that starts at position 0, collapsing to (0, 0) is the same practical state as “just before the mention.”
Because mentions are treated as atomic, there is no valid intermediate partial selection inside the mention. When shrinking a selection over a mention, the selection should move to the next valid atomic state. If additional text outside the mention remains selected, that text should stay selected. If the selection only covers the mention, the next valid state is a collapsed caret at the boundary.
So I don’t think this boundary collapse needs to be guarded against; it is the intended atomic-selection behavior rather than a regression.
Code Review SummaryStatus: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (3 files)
Fix these issues in Kilo Cloud Reviewed by claude-sonnet-5-20260630 · Input: 22 · Output: 30.3K · Cached: 624.8K Review guidance: REVIEW.md from base branch |
…lection fix(vscode): allow shrinking prompt mention selections
Issue
Prompt input treats file mentions as atomic selection units when growing a Shift+Arrow selection, but shrinking the selection back across the same mention gets stuck. This makes it hard to correct or adjust selected prompt text once a file mention has been included.
Context
This fixes Shift+Arrow selection behavior in the VS Code prompt input when the selection crosses an inline file mention.
Before this change, selection growth could snap over the full mention, but shrinking back into the mention would immediately snap back to the full mention again, so the selection appeared not to move.
Implementation
The fix stays in the existing
snapSelectionpath that already makes partially selected file mentions atomic.scanSelectionnow remembers the previous snapped selection bounds. When the next native selection still has the same anchor but moves the active edge back into a mention, it treats that as a shrink operation and snaps to the opposite mention boundary instead of expanding back over the full mention.This keeps normal grow behavior unchanged and avoids adding special Shift+Arrow key handling.
Screenshots / Video
before.mp4
after.mp4
How to Test
Manual/local verification
bun test tests/unit/use-file-mention.test.ts.bun run lint.bun run typecheck.Reviewer test steps
A @README.md B.B.@README.md.ی @README.md س.س.@README.md.Blocked checks and substitute verification
Checklist