I needed to read the source code and reference AI:
Looking at the code, I can see exactly how to replicate the scrollSnapshot() functionality using the exported APIs. The key insight is that ScrollTarget class and the scrollIntoView effect are exported by the library.
Here’s how you can implement the same functionality as scrollSnapshot():
import { EditorView, EditorSelection } from '@codemirror/view';
// Get the current scroll position
const { scrollTop, scrollLeft } = view.scrollDOM;
// Get the scroll anchor reference (you'll need to calculate this)
// The scrollSnapshot() method uses viewState. scrollAnchorAt(scrollTop)
// which finds a reference line near the top of the viewport
const ref = view.viewState.scrollAnchorAt(scrollTop);
// Create a ScrollTarget with isSnapshot=true (the last parameter)
// This is the key - the isSnapshot flag tells the view to treat this
// as a snapshot restore rather than a scroll-into-view request
const scrollEffect = EditorView.scrollIntoView(
ref. from, // cursor position at the reference line
{
y: 'start',
x: 'start',
yMargin: ref.top - scrollTop, // The yMargin stores the offset from line top
xMargin: scrollLeft // The xMargin stores the scrollLeft position
}
);
// However, there's a problem: the isSnapshot flag is NOT exposed through
// the public EditorView. scrollIntoView() API
Unfortunately, there’s a limitation: The ScrollTarget constructor’s isSnapshot parameter is not accessible through the public EditorView.scrollIntoView() method. Looking at the implementation:
static scrollIntoView(pos: number | SelectionRange, options: {
y?: ScrollStrategy,
x?: ScrollStrategy,
yMargin?: number,
xMargin?: number,
} = {}): StateEffect<unknown> {
return scrollIntoView.of(new ScrollTarget(typeof pos == "number" ? EditorSelection.cursor(pos) : pos,
options.y, options. x, options.yMargin, options.xMargin))
}
The isSnapshot parameter is always false when using the public API.
Solution: Import ScrollTarget directly
You need to import ScrollTarget and scrollIntoView directly from the extension module:
import { EditorView, EditorSelection } from '@codemirror/view';
// You may need to import these from the internal exports
// Check if these are exported in the main package index
// If exported, you can do:
import { scrollIntoView, ScrollTarget } from '@codemirror/view';
const { scrollTop, scrollLeft } = view.scrollDOM;
const ref = view.viewState.scrollAnchorAt(scrollTop);
view.dispatch({
selection: { anchor: position, head: position },
effects: [
scrollIntoView. of(
new ScrollTarget(
EditorSelection.cursor(ref.from),
'start',
'start',
ref.top - scrollTop, // yMargin stores the offset
scrollLeft, // xMargin stores scrollLeft
true // isSnapshot = true
)
)
]
});
Check if exported: You’ll need to verify if ScrollTarget and scrollIntoView (the StateEffect, not the static method) are exported in the package’s main exports. If they’re not, you might need to either:
- Request the CodeMirror maintainers to export them
- Use the
scrollSnapshot() method directly on the view: view.scrollSnapshot()
- Access them from the internal module path (not recommended as it’s not part of the public API)
The search results show these are limited to 10 results. You can view more in GitHub.