Path: blob/main/src/vs/editor/browser/stableEditorScroll.ts
3292 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { ICodeEditor } from './editorBrowser.js';6import { Position } from '../common/core/position.js';7import { ScrollType } from '../common/editorCommon.js';89export class StableEditorScrollState {1011public static capture(editor: ICodeEditor): StableEditorScrollState {12if (editor.getScrollTop() === 0 || editor.hasPendingScrollAnimation()) {13// Never mess with the scroll top if the editor is at the top of the file or if there is a pending scroll animation14return new StableEditorScrollState(editor.getScrollTop(), editor.getContentHeight(), null, 0, null);15}1617let visiblePosition: Position | null = null;18let visiblePositionScrollDelta = 0;19const visibleRanges = editor.getVisibleRanges();20if (visibleRanges.length > 0) {21visiblePosition = visibleRanges[0].getStartPosition();22const visiblePositionScrollTop = editor.getTopForPosition(visiblePosition.lineNumber, visiblePosition.column);23visiblePositionScrollDelta = editor.getScrollTop() - visiblePositionScrollTop;24}25return new StableEditorScrollState(editor.getScrollTop(), editor.getContentHeight(), visiblePosition, visiblePositionScrollDelta, editor.getPosition());26}2728constructor(29private readonly _initialScrollTop: number,30private readonly _initialContentHeight: number,31private readonly _visiblePosition: Position | null,32private readonly _visiblePositionScrollDelta: number,33private readonly _cursorPosition: Position | null,34) {35}3637public restore(editor: ICodeEditor): void {38if (this._initialContentHeight === editor.getContentHeight() && this._initialScrollTop === editor.getScrollTop()) {39// The editor's content height and scroll top haven't changed, so we don't need to do anything40return;41}4243if (this._visiblePosition) {44const visiblePositionScrollTop = editor.getTopForPosition(this._visiblePosition.lineNumber, this._visiblePosition.column);45editor.setScrollTop(visiblePositionScrollTop + this._visiblePositionScrollDelta);46}47}4849public restoreRelativeVerticalPositionOfCursor(editor: ICodeEditor): void {50if (this._initialContentHeight === editor.getContentHeight() && this._initialScrollTop === editor.getScrollTop()) {51// The editor's content height and scroll top haven't changed, so we don't need to do anything52return;53}5455const currentCursorPosition = editor.getPosition();5657if (!this._cursorPosition || !currentCursorPosition) {58return;59}6061const offset = editor.getTopForLineNumber(currentCursorPosition.lineNumber) - editor.getTopForLineNumber(this._cursorPosition.lineNumber);62editor.setScrollTop(editor.getScrollTop() + offset, ScrollType.Immediate);63}64}656667export class StableEditorBottomScrollState {6869public static capture(editor: ICodeEditor): StableEditorBottomScrollState {70if (editor.hasPendingScrollAnimation()) {71// Never mess with the scroll if there is a pending scroll animation72return new StableEditorBottomScrollState(editor.getScrollTop(), editor.getContentHeight(), null, 0);73}7475let visiblePosition: Position | null = null;76let visiblePositionScrollDelta = 0;77const visibleRanges = editor.getVisibleRanges();78if (visibleRanges.length > 0) {79visiblePosition = visibleRanges.at(-1)!.getEndPosition();80const visiblePositionScrollBottom = editor.getBottomForLineNumber(visiblePosition.lineNumber);81visiblePositionScrollDelta = visiblePositionScrollBottom - editor.getScrollTop();82}83return new StableEditorBottomScrollState(editor.getScrollTop(), editor.getContentHeight(), visiblePosition, visiblePositionScrollDelta);84}8586constructor(87private readonly _initialScrollTop: number,88private readonly _initialContentHeight: number,89private readonly _visiblePosition: Position | null,90private readonly _visiblePositionScrollDelta: number,91) {92}9394public restore(editor: ICodeEditor): void {95if (this._initialContentHeight === editor.getContentHeight() && this._initialScrollTop === editor.getScrollTop()) {96// The editor's content height and scroll top haven't changed, so we don't need to do anything97return;98}99100if (this._visiblePosition) {101const visiblePositionScrollBottom = editor.getBottomForLineNumber(this._visiblePosition.lineNumber);102editor.setScrollTop(visiblePositionScrollBottom - this._visiblePositionScrollDelta, ScrollType.Immediate);103}104}105}106107108