Skip to content

diff: GitHub-style formatting, whole-file syntax context, working expand#101

Merged
mattmoran56 merged 4 commits into
mainfrom
claude/improve-diff-formatting-LFhMQ
May 20, 2026
Merged

diff: GitHub-style formatting, whole-file syntax context, working expand#101
mattmoran56 merged 4 commits into
mainfrom
claude/improve-diff-formatting-LFhMQ

Conversation

@mattmoran56
Copy link
Copy Markdown
Owner

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

  • GitHub-style row layout — Three visual zones per row: gutter (line numbers, more saturated tint), indicator (+ / , 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.
  • Whole-file context for syntax highlightinguseDiffHighlighting now 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.
  • Click-anywhere expander — The "Show N unchanged lines" strip is one big click target (defaults to expand-all for an in-between gap, expand-down for a tail). The discrete ↑20 / ↓20 / ⇕ buttons inside the row override that default for fine-grained control.
  • Working worktree expansion — The expander was previously inert in the worktree DiffViewer (no onExpand handler, blobLines: null hard-coded). New useExpandableBlob hook fetches the file via window.api.file.read for working changes or a new git.showFile IPC for a specific commit, caches the lines, and tracks expanded line ranges. Same component now drives both worktree and PR diff.
  • Testing hooks — Added data-line-type, data-expander-row, and data-expand-direction attributes so the diff is testable from Playwright.

Screenshots

Storybook (Git/DiffViewer story — component in isolation)

Unified mode:

Unified diff with GitHub-style gutter / indicator / body zones

Side-by-side / split mode:

Side-by-side diff in split mode

Unified, with the in-between expander already triggered (10 unchanged lines spliced in from the blob, tokenised against the whole-file context):

Unified diff after expanding context between two hunks

Split, with the same expansion applied:

Split diff after expanding context between two hunks

Real mock app — PR #42 → Files tab

Unified, with the file-list sidebar collapsed for a wider canvas:

Mock app PR review showing the new diff styling, unified mode

After clicking the tail expander (↓20):

Mock app PR review with context expanded below the hunk

Tight crop of just the diff column for use in PR descriptions:

Tight crop of the diff in the mock app

Test plan

  • 542 unit tests pass (npm test), including 26 new tests:
    • parsePatch / buildDisplayLines — 12 tests covering hunk parsing, line numbering, tail vs. between-hunk expanders, hunk collapse, blob splicing
    • buildFullText (highlight-context helper) — 6 tests covering both old/new sides, blob gaps, line-number-extending-past-blob
    • useExpandableBlob — 8 tests covering worktree vs. commit fetch, STEP=20 caps, up / down / all directions, cache dedupe, reset on file change
  • 4 new Playwright e2e tests pass (npm run test:e2e):
    • Expander row is present below the hunk
    • Clicking the down arrow expands context
    • Clicking anywhere on the row (label area, not the buttons) expands context
    • Clicking the label updates the gap label
  • Visual-regression baselines need refreshapp-git-view and app-pr-review Storybook screenshots will change because of the new row styling. Run npm run test:screenshots:update and commit the new baselines after eyeballing the diffs.
  • Native run (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

  • The git.showFile IPC is a thin wrapper over git show <ref>:<path> returning UTF-8 text (the existing showFileBase64 is kept for image diffs). The PR uses gh api .../contents/{path}?ref=... and falls back to git show — the worktree only needs the local path.
  • The new useExpandableBlob hook lives next to DiffViewer.tsx (src/renderer/components/git/) since it's only used by the worktree viewer. The PR viewer keeps using the store-backed expandContext flow because it already has GraphQL-style refs (baseRefOid / headRefOid).
  • Mock data gets a real diff --git header in mockUnifiedDiff so the Files-tab path actually mounts the diff viewer (it previously fell into the "Select a file to review" empty state because extractFileDiff couldn't find the file).

https://claude.ai/code/session_01753bVuHDnsb62Y3ZiM1eiV


Generated by Claude Code

claude added 4 commits May 20, 2026 08:06
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
@mattmoran56 mattmoran56 merged commit 9cb6470 into main May 20, 2026
2 of 3 checks passed
@mattmoran56 mattmoran56 deleted the claude/improve-diff-formatting-LFhMQ branch May 20, 2026 14:15
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