Skip to content

Conversation

@fat
Copy link
Contributor

@fat fat commented Jan 27, 2026

🏄

@vercel
Copy link

vercel bot commented Jan 27, 2026

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

Project Deployment Review Updated (UTC)
pierrejs-diff-demo Ready Ready Preview Jan 29, 2026 0:45am
pierrejs-docs Ready Ready Preview Jan 29, 2026 0:45am
pierrejs-solid-diff-demo Ready Ready Preview Jan 29, 2026 0:45am

Request Review

Copy link

Copilot AI left a 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 (default 2) 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,
Copy link

Copilot AI Jan 27, 2026

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.

Suggested change
collapsedContextThreshold,
collapsedContextThreshold = 2,

Copilot uses AI. Check for mistakes.
Copy link
Member

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,
Copy link
Member

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(
Copy link
Member

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) {
Copy link
Member

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,
Copy link
Member

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
Copy link
Member

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,
Copy link
Member

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.

Copy link
Member

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
Copy link
Member

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) {
Copy link
Member

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);
Copy link
Member

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...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image
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)
Copy link
Contributor Author

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

@fat fat merged commit 03d26df into main Jan 29, 2026
9 checks passed
@fat fat deleted the fat/expanded-v2 branch January 29, 2026 02:11
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.

3 participants