Skip to content

Refactor multi-diff virtualized scrolling - #333394

Merged
Henning Dieterichs (hediet) merged 4 commits into
mainfrom
hediet/multi-diff-virtualized-scrolling
Aug 30, 2026
Merged

Refactor multi-diff virtualized scrolling#333394
Henning Dieterichs (hediet) merged 4 commits into
mainfrom
hediet/multi-diff-virtualized-scrolling

Conversation

@hediet

Copy link
Copy Markdown
Member

Summary

  • introduce revisioned logical geometry, semantic scroll anchors, and transient document slack to keep virtualized multi-diff content stable as item sizes change
  • replace the ad-hoc object pool with typed virtualized item management and strict template bindings
  • add lazy timestamped JSONL layout diagnostics with composable JSON patches
  • add shared fake and real multi-diff component fixtures plus focused regression coverage

Validation

  • pre-commit hygiene
  • git diff --check origin/main...HEAD
  • tests, compilation, and type-checking were not run, per request

Introduce revisioned logical geometry, semantic scroll anchoring, pooled virtualized item management, layout diagnostics, and shared fake/real component fixtures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 628b1c91-5489-4cfc-baf3-ca556c6e50bc
Copilot AI balanced review requested due to automatic review settings August 30, 2026 13:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

Review tier: Balanced
Findings: 5 Medium severity

New issues introduced by this change (5)
Severity Finding
Medium severity src/​vs/​workbench/​contrib/​multiDiffEditor/​browser/​multiDiffEditorLayoutDebug.ts — Properties whose runtime value toggles through undefined are never represented in the patch. For…
Medium severity src/​vs/​editor/​browser/​widget/​multiDiffEditor/​diffEditorItemTemplate.ts — A valid content-size event is first stored in _observedEditorContentHeight and only copied into…
Medium severity src/​vs/​editor/​browser/​widget/​multiDiffEditor/​compressedVirtualizedScrollView.ts — Replacing the source with different items that happen to have the same heights leaves…
Medium severity src/​vs/​editor/​browser/​widget/​multiDiffEditor/​multiDiffEditorWidgetImpl.tsscrollTop here is a logical item offset, while setScrollPosition accepts the physical scrollbar…
Medium severity src/​vs/​workbench/​test/​browser/​componentFixtures/​multiDiffEditorScroll.fixture.ts — When the observable changes while this input is focused, this autorun performs no observable read,…
What changed in this PR

Refactors multi-diff virtualization to preserve scroll stability during geometry changes and adds layout diagnostics and regression fixtures.

Changes:

  • Introduces revisioned compressed scrolling with semantic anchors and transient slack.
  • Replaces generic pooling with typed virtualized item management.
  • Adds JSONL diagnostics, fixtures, and focused regression tests.
File Description
multiDiffEditorScroll.fixture.ts Adds interactive scrolling fixtures.
multiDiffEditorScroll.fixture.css Styles the new fixtures.
editor/​multiDiffEditorFixtureUtils.ts Shares fixture setup utilities.
editor/​multiDiffEditor.fixture.ts Adopts shared fixture utilities.
multiDiffEditorLayoutDebug.test.ts Tests JSON patch diagnostics.
multiDiffEditorLayoutDebug.ts Implements JSONL layout logging.
multiDiffEditor.ts Exposes layout debug state.
multiDiffEditor.contribution.ts Registers the debug action.
actions.ts Opens layout diagnostics.
sessionChangesEditor.ts Exposes session layout diagnostics.
virtualizedItemManager.test.ts Tests typed template pooling.
multiDiffEditorWidget.test.ts Tests recycled template heights.
compressedVirtualizedScrollLayout.test.ts Tests layout and anchoring behavior.
virtualizedItemManager.ts Adds typed binding and pooling management.
objectPool.ts Removes the superseded generic pool.
multiDiffEditorWidgetImpl.ts Integrates compressed virtualization.
multiDiffEditorWidget.ts Publishes debug-state access.
multiDiffEditorViewModel.ts Tracks expanded content height.
diffEditorItemTemplate.ts Implements strict virtualized bindings.
compressedVirtualizedScrollView.ts Manages anchored scrolling and slack.
compressedVirtualizedScrollLayout.ts Computes revisioned logical geometry.
hideUnchangedRegionsFeature.ts Preserves anchors during region expansion.
diffEditorWidget.ts Adds scroll-anchor callbacks.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +76 to +89
for (const key of Object.keys(previous)) {
if (!hasKey(next, { [key]: true })) {
operations.push({ op: 'remove', path: toJsonPointer([...path, key]) });
}
}
for (const [key, value] of Object.entries(next)) {
if (!hasKey(previous, { [key]: true })) {
if (value !== undefined) {
operations.push({ op: 'add', path: toJsonPointer([...path, key]), value });
}
} else if (value !== undefined && previous[key] !== undefined) {
appendJsonPatchOperations(operations, createJsonPatch(previous[key], value, [...path, key]));
}
}
Comment on lines +251 to +253
public getExpandedContentHeight(): number {
return this._editorContentHeight.get() + this._outerEditorHeight;
}
leadingScrollSlack: this._leadingScrollSlack,
trailingScrollSlack: this._trailingScrollSlack,
}, tx);
} else if (geometryChanged) {
range: options?.range,
});
this._scrollableElement.setScrollPosition({ scrollTop });
this._scrollView.setScrollPosition({ scrollTop });
Comment on lines +1474 to +1478
store.add(autorun(reader => {
if (dom.getActiveElement() !== input) {
input.value = formatNumber(value.read(reader));
}
}));
@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Screenshot Changes

Base: 004a1fbb Current: 7e231c2d

Changed (2)

editor/multiDiffEditor/MultiDiffEditorIncrementalResolved/Dark
Before After
before after
editor/multiDiffEditor/MultiDiffEditorIncrementalResolved/Light
Before After
before after

Added (6)

editor/multiDiff/multiDiffEditorScroll/ScrollModel/Dark

current

editor/multiDiff/multiDiffEditorScroll/ScrollModel/Light

current

editor/multiDiff/multiDiffEditorScroll/TemplatePool/Dark

current

editor/multiDiff/multiDiffEditorScroll/TemplatePool/Light

current

editor/multiDiff/multiDiffEditorScroll/RealWidget/Dark

current

editor/multiDiff/multiDiffEditorScroll/RealWidget/Light

current

Detach manager output from source observables during disposal so ref-counted diff view models are released regardless of downstream teardown order. Move dependent class-field initialization into constructors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 628b1c91-5489-4cfc-baf3-ca556c6e50bc
Wait for the responsive-layout diff computation before disposing the test widget, and revert the unrelated virtualized item manager experiment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 628b1c91-5489-4cfc-baf3-ca556c6e50bc
Tie references retained across diff model transactions to the widget lifetime so synchronous teardown releases them immediately.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 628b1c91-5489-4cfc-baf3-ca556c6e50bc
@hediet
Henning Dieterichs (hediet) merged commit e3ce07e into main Aug 30, 2026
37 checks passed
@hediet
Henning Dieterichs (hediet) deleted the hediet/multi-diff-virtualized-scrolling branch August 30, 2026 19:02
@vs-code-engineering vs-code-engineering Bot added this to the 1.136.0 milestone Aug 30, 2026
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