-
Notifications
You must be signed in to change notification settings - Fork 28
Add collapsedContextThreshold #298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Adds a new collapsedContextThreshold option to automatically expand small collapsed context regions (defaulting to 2), updating diff iteration/rendering, documentation examples, and virtualization tests/snapshots accordingly.
Changes:
- Introduce
collapsedContextThreshold(default2) and thread it through diff rendering/iteration paths. - Auto-expand collapsed context regions at/below the threshold to reduce “1 unmodified line” separators.
- Update docs examples and adjust virtualization tests/snapshots to the new rendered output.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/diffs/src/constants.ts | Adds DEFAULT_COLLAPSED_CONTEXT_THRESHOLD. |
| packages/diffs/src/types.ts | Exposes collapsedContextThreshold in public option types. |
| packages/diffs/src/utils/iterateOverDiff.ts | Implements threshold-based auto-expansion for collapsed context regions. |
| packages/diffs/src/utils/renderDiffWithHighlighter.ts | Plumbs collapsedContextThreshold into iteration used for highlighted/plain diff rendering. |
| packages/diffs/src/renderers/DiffHunksRenderer.ts | Defaults and forwards collapsedContextThreshold through renderer + worker plain-AST path. |
| packages/diffs/src/components/SimpleVirtualizedFileDiff.ts | Applies threshold in virtualization sizing/expansion logic and passes it into iteration. |
| packages/diffs/src/worker/WorkerPoolManager.ts | Passes collapsedContextThreshold to plain diff rendering in worker manager. |
| packages/diffs/src/style.css | Removes styling hooks for context-expanded lines. |
| packages/diffs/test/DiffHunksRendererVirtualization.test.ts | Updates expected counts/indices to match new auto-expanded rendering. |
| packages/diffs/test/snapshots/DiffHunksRendererVirtualization.test.ts.snap | Updates snapshots for new DOM/line-type output. |
| apps/docs/app/docs/VanillaAPI/constants.ts | Documents the new option in the Vanilla API example. |
| apps/docs/app/docs/ReactAPI/constants.ts | Documents the new option in the React API example. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| startingLine, | ||
| totalLines, | ||
| expandedHunks, | ||
| collapsedContextThreshold, |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
collapsedContextThreshold is destructured from ForcePlainTextOptions without any default. Callers that omit the 4th arg to renderDiffWithHighlighter (e.g. the worker render path) will end up passing undefined into iterateOverDiff, effectively disabling the “default: 2” behavior and potentially causing the plain pre-render and highlighted render to disagree.
Consider defaulting collapsedContextThreshold here (e.g. via destructuring default or by including it in DEFAULT_PLAIN_TEXT_OPTIONS) so the default behavior is consistent for all call sites.
| collapsedContextThreshold, | |
| collapsedContextThreshold = 2, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably akin to one of my other comments, but obvi use the constant
| : this.hunksRenderer.getExpandedHunksMap(), | ||
| collapsedContextThreshold: | ||
| this.options.collapsedContextThreshold ?? | ||
| DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kind of a nit, but can we pull this value out above from this.options on line 190? Since we do that with a couple of other props out of options already?
| renderAll: false, | ||
| }; | ||
| } | ||
| const threshold = Math.max( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need Math.max for this? The value check on threshold and rangeSize should be sufficient?
| DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, | ||
| 0 | ||
| ); | ||
| if (threshold > 0 && rangeSize <= threshold) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also since this line is essentially the same return as expandUnchanged, can we just combine this if statement with the one below?
if (expandUnchanged || rangeSize <= collapsedContextThreshold)
Might also be a nice opportunity to destruct both expandUnchanged and collapsedContextThreshold out at the same time with default values.
| : this.hunksRenderer.getExpandedHunksMap(), | ||
| collapsedContextThreshold: | ||
| this.options.collapsedContextThreshold ?? | ||
| DEFAULT_COLLAPSED_CONTEXT_THRESHOLD, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nit to destruct this higher up with the other this.options above
| ? true | ||
| : this.expandedHunks | ||
| : this.expandedHunks, | ||
| this.getOptionsWithDefaults().collapsedContextThreshold |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This a good spot where i did a dumb. On line 325, i use this.options, I should've used this.getOptionsWithDefaults(). then can you destruct both this value and expandUnchanged up there?
| startingLine = 0, | ||
| totalLines = Infinity, | ||
| expandedHunks, | ||
| collapsedContextThreshold, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question here -- if 2 is our default, should we default prop this to that constant?
collapsedContextThreshold = 2
That or imo we should default arg it to 0. Kinda thinking if we go all in on 2, then everywhere we default arg it to 2 for consistency?
Then the rest of the functions internally here should just require a number, and this should satisfy them. Then the call sites to use it are cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh yeah -- codex code review brought up a good point that we should probably default this arg in renderDiffWithHighlighter as well
| expandedHunks: Map<number, HunkExpansionRegion> | true | undefined, | ||
| hunkIndex: number | ||
| hunkIndex: number, | ||
| collapsedContextThreshold: number | undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This becomes just collapsedContextThreshold: number
| collapsedLines: 0, | ||
| }; | ||
| } | ||
| if (expandedHunks === true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment from before, i don't think we need a max here, and if it's a : number then we can just do the:
if (expandedHunks === true || rangeSize <= collapsedContextThreshold)
| // to figure out, so mostly a good reference if tests change these | ||
| // assumptions | ||
| expect(unifiedIndices[0]).toBe(186); | ||
| expect(unifiedIndices[0]).toBe(184); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
weird that this number went down... 🤔
all the rest went up, which is what you would expect if they are rendering a few more lines...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The number going down makes sense. Previously, collapsedContextThreshold was not being defaulted in the rendering path (it was
undefined), so small collapsed regions (1-2 lines) stayed collapsed and were rendered as a single hunk separator. Now with the
default threshold of 2, those small regions are expanded into actual lines.
When a 1-2 line collapsed region expands, it takes up more rendered lines (1-2 lines instead of 1 separator). So when iterating to
find line index 100 (the startingLine), the iteration reaches 100 rendered lines sooner — meaning the first rendered line
corresponds to an earlier source line index. That's why 186 dropped to 184: the expanded small regions before line 100 cause the
window to start at an earlier point in the file.
The other values going up follows the same logic — more total source lines are being rendered within the same window because
previously-collapsed lines are now visible.
| expansionLineCount: 100, | ||
| // Auto-expand collapsed context regions at or below this size | ||
| // (default: 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it to 1 i think that's better than 2
🏄