diff: GitHub-style formatting, whole-file syntax context, working expand#101
Merged
Conversation
The diff viewer used to have a flat row layout with thin tints and the "Show more lines" expander wired up only in the PR view — clicking it from the worktree did nothing. - Restyle rows into three visual zones (gutter / indicator / body) with GitHub-like opacity ramp so changed lines pop without overwhelming the context, plus a redesigned expander row with discrete ↑20 / ↓20 / ⇕ buttons and a clickable label. - Highlight against the whole-file blob when available: a new buildFullText helper splices visible add/context lines into the blob at their correct positions, so shiki tokenises with proper context even for hunks that start mid-class or mid-string. - Wire expand in the worktree DiffViewer via a new useExpandableBlob hook. Fetches the file from the worktree (file.read) or from a git ref (a new git.showFile IPC) on first click, caches the lines, and marks the requested range expanded. - Add data-line-type / data-expander-row attributes so the diff is testable. - Tests: 26 new unit tests for parsePatch / buildDisplayLines / buildFullText / useExpandableBlob, plus 3 e2e tests covering the PR expander click flow. Screenshots in docs/screenshots/diff-viewer/. https://claude.ai/code/session_01753bVuHDnsb62Y3ZiM1eiV
- New Git/DiffViewer Storybook entries (unified, split, plus expanded-context variants) so the diff component can be reviewed in isolation and added to the visual-regression suite. - Wire the four diff stories into scripts/capture-screenshots.ts so they show up in the standard `npm run screenshots` flow. - Rewrite scripts/capture-diff-screenshots.ts to drive both Storybook (component-level) and the mock app (PR #42 Files tab) — including a cropped diff-only shot for use in PR descriptions. - Replace the prior diff-viewer screenshots with the new clean set (4 Storybook stories, 3 in-app shots, 1 zoomed crop). https://claude.ai/code/session_01753bVuHDnsb62Y3ZiM1eiV
The "Show N unchanged lines" strip previously only triggered expand on its narrow buttons / label. Promote the row root to role="button" so a click anywhere fires the default action (expand-all for an in-between gap, expand-down for a tail). The discrete arrow buttons inside the row stop propagation so they keep their specific behaviour. Adds an e2e test that clicks the label span (well clear of the arrow column) to prove the row-level click handler works. https://claude.ai/code/session_01753bVuHDnsb62Y3ZiM1eiV
- Bump the Features bullet to call out full-file syntax context, click-anywhere context expansion, and the unified/split toggle. - Rewrite the Git integration section with the new diff capabilities and embed four Storybook screenshots showing unified, split, and both with context expanded. - Refresh the PR-review "Expand context" bullet to describe the click-anywhere row behaviour, with the discrete ↑20 / ↓20 / ⇕ all buttons overriding the default for fine-grained control. https://claude.ai/code/session_01753bVuHDnsb62Y3ZiM1eiV
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.
Summary
Rebuild the diff viewer's look-and-feel to match what makes GitHub's review surface easy to read, fix the broken "Show N unchanged lines" expander in the worktree path, and use whole-file context for syntax highlighting so hunks that start mid-class or mid-string still tokenise correctly.
What changed
+/−, strongest tint), body (softest tint). Hunk header is an accent band. Tabular line numbers, vertical separator before code. Context rows stay completely untinted so the eye lands on the actual change.useDiffHighlightingnow splices visible add/context lines into the full-file blob at their real line numbers before handing the text to Shiki. Tokens stay correct even when a hunk begins inside a class body or template literal. Falls back gracefully when the blob isn't available.onExpandhandler,blobLines: nullhard-coded). NewuseExpandableBlobhook fetches the file viawindow.api.file.readfor working changes or a newgit.showFileIPC for a specific commit, caches the lines, and tracks expanded line ranges. Same component now drives both worktree and PR diff.data-line-type,data-expander-row, anddata-expand-directionattributes so the diff is testable from Playwright.Screenshots
Storybook (
Git/DiffViewerstory — component in isolation)Unified mode:
Side-by-side / split mode:
Unified, with the in-between expander already triggered (10 unchanged lines spliced in from the blob, tokenised against the whole-file context):
Split, with the same expansion applied:
Real mock app — PR #42 → Files tab
Unified, with the file-list sidebar collapsed for a wider canvas:
After clicking the tail expander (
↓20):Tight crop of just the diff column for use in PR descriptions:
Test plan
npm test), including 26 new tests:parsePatch/buildDisplayLines— 12 tests covering hunk parsing, line numbering, tail vs. between-hunk expanders, hunk collapse, blob splicingbuildFullText(highlight-context helper) — 6 tests covering both old/new sides, blob gaps, line-number-extending-past-blobuseExpandableBlob— 8 tests covering worktree vs. commit fetch, STEP=20 caps,up/down/alldirections, cache dedupe, reset on file changenpm run test:e2e):app-git-viewandapp-pr-reviewStorybook screenshots will change because of the new row styling. Runnpm run test:screenshots:updateand commit the new baselines after eyeballing the diffs.npm run dev) — open a worktree, select a file, click anywhere on the "Show more lines below" strip to confirm the expansion fetches from the working tree.Notes for reviewers
git.showFileIPC is a thin wrapper overgit show <ref>:<path>returning UTF-8 text (the existingshowFileBase64is kept for image diffs). The PR usesgh api .../contents/{path}?ref=...and falls back togit show— the worktree only needs the local path.useExpandableBlobhook lives next toDiffViewer.tsx(src/renderer/components/git/) since it's only used by the worktree viewer. The PR viewer keeps using the store-backedexpandContextflow because it already has GraphQL-style refs (baseRefOid/headRefOid).diff --githeader inmockUnifiedDiffso the Files-tab path actually mounts the diff viewer (it previously fell into the "Select a file to review" empty state becauseextractFileDiffcouldn't find the file).https://claude.ai/code/session_01753bVuHDnsb62Y3ZiM1eiV
Generated by Claude Code