Repository navigation
Fix markdown sticky scroll when earlier sections are folded (#343881) - #344079
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The inverted filter discards multiline child symbols and their descendants, removing nested sticky headings even without folding.
1 open issue
What changed in this PR
This PR aims to fix Markdown Sticky Scroll losing nested headings after an earlier section is folded, addressing #343881 in the editor’s outline-based sticky model.
Changes:
- Refactors child-symbol filtering to use an early exit.
- Adjusts handling of same-start-line symbols and their nested children.
| File | Description |
|---|---|
| src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts | Changes filtering and recursion when building sticky elements from outline symbols. |
Review effort: Balanced
| @@ -275,11 +275,16 @@ class StickyModelFromCandidateOutlineProvider extends StickyModelCandidateProvid | |||
| const children: StickyElement[] = []; | |||
| for (const child of outlineElement.children.values()) { | |||
| if (child.symbol.selectionRange.startLineNumber !== child.symbol.range.endLineNumber) { | |||
Rahul (rahul05ranjan)
left a comment
There was a problem hiding this comment.
I traced this change against the outline shapes markdown produces and I'm having trouble connecting the diff to the reported repro, so sharing what I checked in case it helps.
What the diff actually changes (two things, not one):
-
Hoisted subchildren now go through the same
selectionRange.startLineNumber !== range.endLineNumberfilter that every other path applies — before, a same-line child's subchildren were hoisted unconditionally. That's consistent; a single-line symbol hoisted into the parent's children previously produced a degenerate sticky entry that the normal path would have filtered. -
The recursion into a hoisted subchild now passes the subchild's own start line instead of
child.symbol.selectionRange.startLineNumber. This one is a real behavior change beyond the title: with a subchild S (multi-line, not on the parent's line) that itself has a multi-line child starting on S's line, the old code kept that grandchild as S's child (compared against the merged child's line), while the new code hoists it out of S into the parent's children. Traced example — parent 1–10, same-line child 1–8, subchild S 2–8, grandchild 2–5: old model has S with a child {2–5}, new model hoists it so S has none. Passing the expanded element's own line matches how every other call site works, so I think it's right, but it'd be good to confirm that was intentional since the PR description doesn't mention it.
The part I couldn't verify: for the document attached to #343881, the markdown language service emits symbols as level-nested sections where range = selectionRange = the section span (header line to next same-or-higher header − 1). That document's headers are all on distinct lines and every section spans multiple lines, so neither the same-line hoist branch nor the single-line check fires for any element of it — I ported _stickyModelFromOutlineElement (old and new) and the resulting sticky models are byte-identical for that outline tree. Folding also doesn't alter document symbols, so I can't see how this path changes the sticky model for that repro.
Could you walk through how the fix connects to the issue — e.g. the symbol shape you observed when you reproduced it? And since both changes are only observable in the same-line/hoist path, a test along the lines of the existing #159271 fixture (with a single-line subchild under a same-line child) would lock in the behavior and demonstrate the failure mode.

Fixes #343881 "Fix markdown sticky scroll when earlier sections are folded"
Summary
Testing