feat(diff): add a side-by-side view to the inline diff preview - #570
Merged
Conversation
- Toggle (inline / side-by-side) in the preview's top-right, persisted to localStorage under workspace:diff-view-mode and shared by every host (chat message diffs, permission dialog, task sheet, file panel) - Split pairing: context rows span both sides; a delete-run and its following add-run are zipped positionally, the longer run's remainder faces a filler cell (GitHub-style split alignment) - Equal-width columns via flex-1 basis-0 with a min-width floor so long lines keep the horizontal scroll; new-file previews stay single-column - Default remains the inline view — nothing changes until opted in Closes xintaofei#537
The view mode is one global preference, but each preview read it into its
own `useState` at mount. A transcript renders one preview per Edit/Write
tool call — and a permission dialog stacks another on top — so flipping
one left every sibling inline until it happened to remount, which is not
what "applies to all hosts" means.
Move the load/save pair to `lib/diff-view-mode-prefs`, the module shape
this repo already uses for cross-surface toggles, and broadcast on write
so every mounted preview subscribes to the same value. The new mode rides
on the event, so the toggle still responds when the localStorage write
throws.
Also:
- `toSplitRows` advanced its cursor only for context/add/delete rows. The
fourth `ParsedDiffRow` type ("modified") matched no branch and spun the
loop forever — a synchronous hang no test timeout can interrupt. Key the
spanning branch off "not added and not deleted" so every pass consumes a
row by construction.
- Hide the toggle when every file in the diff is a new file: those render
as plain content in both modes, so the control was a visible no-op on
exactly the previews a Write tool call produces.
…ping Each split row was its own flex container of two `flex-1 basis-0` cells. That container resolves to the tracks' MINIMUM size, and `flex-1` then halves it — so whenever a row's two sides differ in length, which is the normal case for a replaced line, the longer side overflowed its cell and painted across the divider. The opposite column's tinted background and its own text then painted on top: two lines of code rendered over each other, illegible. Measured in Chromium (240px of bleed on a 700px host) and confirmed visually in WebKit. Give the hunk one grid instead. Shared tracks mean every row breaks at the same x by construction, and `w-max` sizes the grid to twice its widest cell so no track is ever narrower than the line it holds; the enclosing x="scroll" ScrollArea scrolls it, and `min-w-full` keeps short diffs filling the host. Verified across narrow/medium/wide hosts and across hunks of differing widths. Reported by Codex in review; my own first-pass analysis of the flex intrinsic sizing had it backwards.
Owner
|
codeg work task |
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.
功能
为
UnifiedDiffPreview(聊天消息 diff、权限弹窗、任务详情、文件面板中使用的轻量 diff 预览)增加左右分栏视图,现有内联视图保留为默认。Closes #537
实现说明
workspace:diff-view-mode),对所有宿主生效flex-1 basis-0+ 最小宽度兜底),超长行保持横向滚动;纯新增文件(NewFileLines)两种模式下都保持单栏展示手动验证
打开任意一条包含 diff 的聊天消息(或权限弹窗、任务详情的 diff),点击预览右上角的分栏图标:删除行居左、新增行居右、上下文行两侧同显;刷新后选择仍保持。
验证
npx vitest run src/components/diff/unified-diff-preview.test.tsx— 11 个测试(新增 7 个:默认内联、持久化读取、切换与写回、配对算法三例)pnpm test— 353 个测试文件 / 4875 个测试全部通过pnpm build— 静态导出构建通过(与 CI 一致)npx tsc --noEmit、eslint通过