Skip to content

Sectioned diff view: one sticky section per file with expandable context - #12

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1786595561-sectioned-diff-view
Open

Sectioned diff view: one sticky section per file with expandable context#12
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1786595561-sectioned-diff-view

Conversation

@devin-ai-integration

Copy link
Copy Markdown

Summary

Adds DiffFilesViewController (UIKit/visionOS): a "Files Changed" screen that renders a multi-file patch as a UICollectionView with one section per file, the file header pinned while its hunks scroll (header.pinToVisibleBounds = true), and the gaps the patch omits rendered as tappable expander rows that pull in more of the original file, showing a spinner in the tapped arrow until the lines arrive.

The existing parser already recognized files and hunks internally but flattened everything into one [DiffRenderBlock.Row], which loses the file/hunk boundaries and old-file line ranges a sectioned view needs. DiffPatchDocument re-derives that structure from the flattened block and owns all the expansion math; the UI layer is a thin renderer over it.

Where the lines come from is the host's problem — the controller only asks:

controller.fileLineCountProvider = { path in sources[path]?.count }
controller.contextProvider = { request in           // request: filePath, oldLineRange, direction
    try await api.lines(of: request.filePath, in: request.oldLineRange)
}

Expanders are hidden until contextProvider is set; the expander below the last hunk additionally needs fileLineCountProvider, since without the file's length there is no way to know whether more lines follow.

Expansion modes fall out of the gap's shape (DiffExpander.Direction):

gap control
above the first hunk .up
between two hunks, larger than expansionChunkSize (20) .both — one arrow per end
after the last hunk .down
smaller than one chunk single control revealing all of it

insertContext splices the fetched lines into the hunk the arrow grows (prepend for .up, append for .down) and then merges hunks that now touch, so filling a gap collapses two hunks into one:

hunk(10...12) + [expander 13...99] + hunk(100...101)
  --tap ⇕-->  hunk(10...101)

It trims lines the target hunk already covers before splicing, so an over-long or stale provider response can't duplicate rows.

Hunk cells reuse the existing DiffView with block headers/rounding/border suppressed (the section header names the file) and are sized up front with DiffViewConfiguration.intrinsicHeight, avoiding a Core Text self-sizing pass per cell.

Also adds a "Files Changed" screen to the Example app, driven by a generated stand-in repo so expanded context matches the diff, with a 600 ms delay in the provider to make the loading state visible.

Verification

The package only builds on Apple platforms, so the model layer (DiffPatchDocument + UnifiedDiff parsing + the Example fixture's patch generation) was compiled and exercised on Linux in a scratch package with the same sources; those cases ship as Tests/MarkdownViewTests/DiffPatchDocumentTests.swift (splitting, expander placement/direction, requested ranges, up/down/full-gap expansion, hunk merging, duplicate trimming). The UIKit layer and the Example app are unverified locally and rely on CI.

Link to Devin session: https://app.devin.ai/sessions/02792c188b7b4e948c6262ed086f8e66
Requested by: @gtokman

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@gtokman gtokman self-assigned this Aug 13, 2026
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@vercel

vercel Bot commented Aug 13, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
markdown-view Ready Ready Preview, v0 Aug 13, 2026 4:33am

Request Review

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.

1 participant