Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/browser/stableEditorScroll.ts
3292 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { ICodeEditor } from './editorBrowser.js';
7
import { Position } from '../common/core/position.js';
8
import { ScrollType } from '../common/editorCommon.js';
9
10
export class StableEditorScrollState {
11
12
public static capture(editor: ICodeEditor): StableEditorScrollState {
13
if (editor.getScrollTop() === 0 || editor.hasPendingScrollAnimation()) {
14
// Never mess with the scroll top if the editor is at the top of the file or if there is a pending scroll animation
15
return new StableEditorScrollState(editor.getScrollTop(), editor.getContentHeight(), null, 0, null);
16
}
17
18
let visiblePosition: Position | null = null;
19
let visiblePositionScrollDelta = 0;
20
const visibleRanges = editor.getVisibleRanges();
21
if (visibleRanges.length > 0) {
22
visiblePosition = visibleRanges[0].getStartPosition();
23
const visiblePositionScrollTop = editor.getTopForPosition(visiblePosition.lineNumber, visiblePosition.column);
24
visiblePositionScrollDelta = editor.getScrollTop() - visiblePositionScrollTop;
25
}
26
return new StableEditorScrollState(editor.getScrollTop(), editor.getContentHeight(), visiblePosition, visiblePositionScrollDelta, editor.getPosition());
27
}
28
29
constructor(
30
private readonly _initialScrollTop: number,
31
private readonly _initialContentHeight: number,
32
private readonly _visiblePosition: Position | null,
33
private readonly _visiblePositionScrollDelta: number,
34
private readonly _cursorPosition: Position | null,
35
) {
36
}
37
38
public restore(editor: ICodeEditor): void {
39
if (this._initialContentHeight === editor.getContentHeight() && this._initialScrollTop === editor.getScrollTop()) {
40
// The editor's content height and scroll top haven't changed, so we don't need to do anything
41
return;
42
}
43
44
if (this._visiblePosition) {
45
const visiblePositionScrollTop = editor.getTopForPosition(this._visiblePosition.lineNumber, this._visiblePosition.column);
46
editor.setScrollTop(visiblePositionScrollTop + this._visiblePositionScrollDelta);
47
}
48
}
49
50
public restoreRelativeVerticalPositionOfCursor(editor: ICodeEditor): void {
51
if (this._initialContentHeight === editor.getContentHeight() && this._initialScrollTop === editor.getScrollTop()) {
52
// The editor's content height and scroll top haven't changed, so we don't need to do anything
53
return;
54
}
55
56
const currentCursorPosition = editor.getPosition();
57
58
if (!this._cursorPosition || !currentCursorPosition) {
59
return;
60
}
61
62
const offset = editor.getTopForLineNumber(currentCursorPosition.lineNumber) - editor.getTopForLineNumber(this._cursorPosition.lineNumber);
63
editor.setScrollTop(editor.getScrollTop() + offset, ScrollType.Immediate);
64
}
65
}
66
67
68
export class StableEditorBottomScrollState {
69
70
public static capture(editor: ICodeEditor): StableEditorBottomScrollState {
71
if (editor.hasPendingScrollAnimation()) {
72
// Never mess with the scroll if there is a pending scroll animation
73
return new StableEditorBottomScrollState(editor.getScrollTop(), editor.getContentHeight(), null, 0);
74
}
75
76
let visiblePosition: Position | null = null;
77
let visiblePositionScrollDelta = 0;
78
const visibleRanges = editor.getVisibleRanges();
79
if (visibleRanges.length > 0) {
80
visiblePosition = visibleRanges.at(-1)!.getEndPosition();
81
const visiblePositionScrollBottom = editor.getBottomForLineNumber(visiblePosition.lineNumber);
82
visiblePositionScrollDelta = visiblePositionScrollBottom - editor.getScrollTop();
83
}
84
return new StableEditorBottomScrollState(editor.getScrollTop(), editor.getContentHeight(), visiblePosition, visiblePositionScrollDelta);
85
}
86
87
constructor(
88
private readonly _initialScrollTop: number,
89
private readonly _initialContentHeight: number,
90
private readonly _visiblePosition: Position | null,
91
private readonly _visiblePositionScrollDelta: number,
92
) {
93
}
94
95
public restore(editor: ICodeEditor): void {
96
if (this._initialContentHeight === editor.getContentHeight() && this._initialScrollTop === editor.getScrollTop()) {
97
// The editor's content height and scroll top haven't changed, so we don't need to do anything
98
return;
99
}
100
101
if (this._visiblePosition) {
102
const visiblePositionScrollBottom = editor.getBottomForLineNumber(this._visiblePosition.lineNumber);
103
editor.setScrollTop(visiblePositionScrollBottom - this._visiblePositionScrollDelta, ScrollType.Immediate);
104
}
105
}
106
}
107
108