fix: preserve undo history when pasting into the chat input - #498
Open
dungdong-aws wants to merge 1 commit into
Open
dungdong-aws wants to merge 1 commit into
dungdong-aws wants to merge 1 commit into
Conversation
The paste handler cancelled the event and inserted the clipboard text itself
via a script-created text node. That insertion is not recorded on the
browser's native undo stack, so Ctrl/Cmd+Z after a paste did nothing.
The input is contenteditable="plaintext-only", so the browser already inserts
clipboard content as plain text -- the manual insertion was reimplementing
that, and cancelling the event was what broke undo. Letting the native paste
run keeps it undoable; the existing `input` handler still fires afterwards and
covers onInput / removeContextPlaceholderOverlay / checkIsEmpty.
Note document.execCommand('insertText', ...) is not a viable alternative: it
returns false inside the VS Code webview even with the input focused, which
silently falls back to the same non-undoable path.
chungjac
approved these changes
Sep 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Pasting into the chat input could not be undone — Ctrl/Cmd+Z after a paste did nothing.
The paste handler cancelled the event and inserted the clipboard text itself with
range.insertNode(document.createTextNode(text)). A script-created text node is notrecorded on the browser's native undo stack, so the paste was invisible to undo.
Why the handler existed, and why it is now redundant
It was not about stripping formatting. It was added in 52b8162 (Feb 2025) as part of the
cursor-tracking work for the context selector, which converts character offsets to DOM
positions:
That mapping only holds while the input's
childNodesare a flat sequence of text nodes andspan.contextpills. At the time the element wascontenteditable="true", where a nativepaste could inject
<div>/<br>/<span>structures and break the invariant — so forcingthe clipboard content into exactly one flat text node was correct.
Two months later, b64288b changed the element to
contenteditable="plaintext-only", whichmakes the browser guarantee that same invariant. From that point the handler was
redundant, and its only remaining effect was suppressing the native undo entry.
Fix
Stop cancelling the paste and remove the manual insertion (net −26/+3 in the handler). The
existing
inputhandler still fires after a native paste and already coversonInput,removeContextPlaceholderOverlayandcheckIsEmpty— one more than the paste path previouslydid.
This also removes a latent bug:
if ((selection?.rangeCount) != null)was always true(
rangeCountis a number, so0 != null), meaninggetRangeAt(0)could throw when there wasno range.
Why not
execCommand('insertText')That is the obvious alternative and it does not work in the VS Code webview. Measured from
inside a real paste, with the input focused:
Because a failed
execCommandfalls through to the manual insertion, that approach failssilently: undo stays broken and the behaviour is identical to no fix at all. It works in a
plain browser, so a browser-only check passes while the IDE stays broken.
This means #492, which takes the
execCommandroute for the same bug, will not fix it in theVS Code webview. Happy to consolidate — closing whichever the maintainers prefer.
Testing
Added a regression test asserting the paste event is not cancelled. jsdom cannot model
undo, so it guards the actual cause rather than simulating the symptom.
Verified manually in Amazon Q for VS Code against a locally built Flare bundle:
plaintext-onlypreserved)typed
@and picked an item — the pill is inserted at the trigger offset, confirming theoffset→DOM mapping is intact without the manual insertion
Known limitation (pre-existing, out of scope)
Context pills are inserted by script (
range.insertNodeininsertElementToGivenPosition),so they are not on the native undo stack either. After this change, undo reverts a paste but
skips a pill. That is not a regression — previously neither was undoable — but it is now
visible as an inconsistency. Making pill insertion undoable would require every scripted
mutation in the prompt input to become a native editing command or be tracked in a custom undo
stack, which is a larger design change.
Risk
Relies on
contenteditable="plaintext-only"being honoured by the host engine. It is inChromium-based hosts (VS Code, JetBrains JCEF). Worth a sanity check on Eclipse's SWT browser,
where a fallback would be needed if formatting survives a paste.