Skip to content

fix(diffs): Refresh reshaped split edits safely#910

Open
necolas wants to merge 1 commit into
beta-1.3from
nicolas/editor-fix-redo-stack-diffstyle
Open

fix(diffs): Refresh reshaped split edits safely#910
necolas wants to merge 1 commit into
beta-1.3from
nicolas/editor-fix-redo-stack-diffstyle

Conversation

@necolas

@necolas necolas commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Fixes split-diff edit-mode rerendering issues surfaced by the Codex review on this branch.

Reproduction

  1. Open a split editable diff (e.g. /playground with Edit mode).
  2. Edit an added line back to the old-side text so its hunk disappears or changes shape.

Before this change the editor stayed on the split fast-refresh path, which only patches row attributes — leaving stale added/deleted rows in the DOM.

Changes

  • Detect when recomputing content hunks changes the rendered hunk shape, and use a full refresh (clearing the render cache) for that case instead of the in-place fast patch.
  • Reset the editor's caret/selection geometry caches when a split content edit rebuilds rows, so the caret doesn't measure a detached row and jump.
  • fastRefreshDiffView self-escalates to a full rebuild when a column's rendered row count diverges, instead of silently leaving stale rows.
  • Guard the async editor-sync continuation so a highlighter promise from an older render can't resync a detached or replaced editor.
  • Document getDiffRenderShapeKey (the fast-vs-full gate) and add regression coverage: split reshape that removes a hunk, a same-split-count reshape, and fast-path reachability.

Scope note
Rebased to drop the "preserve editor history across layout toggles" commit — that workaround is being handled via the cacheKey approach in #878. This PR is now only the split-reshape / async-sync correctness fix.

@vercel

vercel Bot commented Jun 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pierre-docs-diffs Ready Ready Preview Jun 30, 2026 6:51pm
pierre-docs-diffshub Ready Ready Preview Jun 30, 2026 6:51pm
pierre-docs-trees Ready Ready Preview Jun 30, 2026 6:51pm
pierrejs-diff-demo Ready Ready Preview Jun 30, 2026 6:51pm

Request Review

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

this.fastRefreshDiffView();

P2 Badge Use a full refresh when split edits reshape hunks

In split edit mode, when a user edits an added line back to the old-side text (or otherwise causes hunks to merge/split), recomputeContentHunks can replace the hunk structure, but this path still schedules fastRefreshDiffView(). That fast path only patches data-line-type and skips when the new AST child count differs, so the stale deletion/addition rows remain visible until some later full rerender. Use the full refresh path when the recompute changes the hunk shape/row count.


void this.hunksRenderer.initializeHighlighter().then((highlighter) => {
editor.__syncRenderView(

P2 Badge Guard async editor sync against stale renders

If an editable diff changes files or unmounts while initializeHighlighter() is still pending, this captured continuation can still call __syncRenderView with the old fileDiff/container after a newer render has attached the same editor. In that race the editor document can be reset to stale contents, or a cleaned editor can be touched after unmount. Check that this.editor, this.fileDiff, and this.fileContainer still match the captured values before syncing.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@necolas

necolas commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

Still working on this...

@ije ije left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread apps/docs/app/(diffs)/playground/PlaygroundClient.tsx Outdated
@ije ije self-requested a review June 30, 2026 07:56
@ije

ije commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

@necolas #878 will ensure the cacheKey with the file name if it's not provided. we better should not add workarounds for the layout/options update. in further update, we need to cache TextDocuments using the cacheKey. so when switching file the undo stack remains.

i also updated the playground/home apps in #878, please take a look

In a split editable diff, change an added line back to the old-side
text. The hunk can disappear or change shape, but the editor still used
the split fast-refresh path, which only patches existing row attributes
and leaves stale added or deleted rows in the DOM.

Detect when recomputing content hunks changes the rendered hunk shape and
use a full refresh for that case, clearing empty columns when a hunk
disappears. Also guard async editor sync continuations so a highlighter
promise from an older render cannot resync a detached or replaced editor.
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