Skip to content

Commit 1e6ac12

Browse files
author
Aiday Marlen Kyzy
authored
Merge pull request microsoft#158266 from microsoft/aiday/stickyScrollTesting
Tests written for Sticky Scroll
2 parents 6dbddd8 + b6f53f1 commit 1e6ac12

File tree

4 files changed

+330
-114
lines changed

4 files changed

+330
-114
lines changed

src/vs/editor/contrib/stickyScroll/browser/stickyScrollController.ts

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,53 +12,62 @@ import { StickyScrollWidget, StickyScrollWidgetState } from './stickyScrollWidge
1212
import { StickyLineCandidateProvider, StickyRange } from './stickyScrollProvider';
1313
import { IModelTokensChangedEvent } from 'vs/editor/common/textModelEvents';
1414

15-
1615
export class StickyScrollController extends Disposable implements IEditorContribution {
1716

1817
static readonly ID = 'store.contrib.stickyScrollController';
19-
private readonly editor: ICodeEditor;
20-
private readonly stickyScrollWidget: StickyScrollWidget;
21-
private readonly stickyLineCandidateProvider: StickyLineCandidateProvider;
22-
private readonly sessionStore: DisposableStore = new DisposableStore();
18+
private readonly _editor: ICodeEditor;
19+
private readonly _stickyScrollWidget: StickyScrollWidget;
20+
private readonly _stickyLineCandidateProvider: StickyLineCandidateProvider;
21+
private readonly _sessionStore: DisposableStore = new DisposableStore();
22+
private _widgetState: StickyScrollWidgetState;
2323

2424
constructor(
25-
editor: ICodeEditor,
25+
_editor: ICodeEditor,
2626
@ILanguageFeaturesService _languageFeaturesService: ILanguageFeaturesService,
2727
) {
2828
super();
29-
this.editor = editor;
30-
this.stickyScrollWidget = new StickyScrollWidget(this.editor);
31-
this.stickyLineCandidateProvider = new StickyLineCandidateProvider(this.editor, _languageFeaturesService);
29+
this._editor = _editor;
30+
this._stickyScrollWidget = new StickyScrollWidget(this._editor);
31+
this._stickyLineCandidateProvider = new StickyLineCandidateProvider(this._editor, _languageFeaturesService);
32+
this._widgetState = new StickyScrollWidgetState([], 0);
3233

33-
this._register(this.editor.onDidChangeConfiguration(e => {
34+
this._register(this._editor.onDidChangeConfiguration(e => {
3435
if (e.hasChanged(EditorOption.experimental)) {
3536
this.readConfiguration();
3637
}
3738
}));
3839
this.readConfiguration();
3940
}
4041

42+
public get stickyScrollCandidateProvider() {
43+
return this._stickyLineCandidateProvider;
44+
}
45+
46+
public get stickyScrollWidgetState() {
47+
return this._widgetState;
48+
}
49+
4150
private readConfiguration() {
42-
const options = this.editor.getOption(EditorOption.experimental);
51+
const options = this._editor.getOption(EditorOption.experimental);
4352
if (options.stickyScroll.enabled === false) {
44-
this.editor.removeOverlayWidget(this.stickyScrollWidget);
45-
this.sessionStore.clear();
53+
this._editor.removeOverlayWidget(this._stickyScrollWidget);
54+
this._sessionStore.clear();
4655
return;
4756
} else {
48-
this.editor.addOverlayWidget(this.stickyScrollWidget);
49-
this.sessionStore.add(this.editor.onDidScrollChange(() => this.renderStickyScroll()));
50-
this.sessionStore.add(this.editor.onDidLayoutChange(() => this.onDidResize()));
51-
this.sessionStore.add(this.editor.onDidChangeModelTokens((e) => this.onTokensChange(e)));
52-
this.sessionStore.add(this.stickyLineCandidateProvider.onStickyScrollChange(() => this.renderStickyScroll()));
53-
const lineNumberOption = this.editor.getOption(EditorOption.lineNumbers);
57+
this._editor.addOverlayWidget(this._stickyScrollWidget);
58+
this._sessionStore.add(this._editor.onDidScrollChange(() => this.renderStickyScroll()));
59+
this._sessionStore.add(this._editor.onDidLayoutChange(() => this.onDidResize()));
60+
this._sessionStore.add(this._editor.onDidChangeModelTokens((e) => this.onTokensChange(e)));
61+
this._sessionStore.add(this._stickyLineCandidateProvider.onStickyScrollChange(() => this.renderStickyScroll()));
62+
const lineNumberOption = this._editor.getOption(EditorOption.lineNumbers);
5463
if (lineNumberOption.renderType === RenderLineNumbersType.Relative) {
55-
this.sessionStore.add(this.editor.onDidChangeCursorPosition(() => this.renderStickyScroll()));
64+
this._sessionStore.add(this._editor.onDidChangeCursorPosition(() => this.renderStickyScroll()));
5665
}
5766
}
5867
}
5968

6069
private needsUpdate(event: IModelTokensChangedEvent) {
61-
const stickyLineNumbers = this.stickyScrollWidget.getCurrentLines();
70+
const stickyLineNumbers = this._stickyScrollWidget.getCurrentLines();
6271
for (const stickyLineNumber of stickyLineNumbers) {
6372
for (const range of event.ranges) {
6473
if (stickyLineNumber >= range.fromLineNumber && stickyLineNumber <= range.toLineNumber) {
@@ -76,32 +85,33 @@ export class StickyScrollController extends Disposable implements IEditorContrib
7685
}
7786

7887
private onDidResize() {
79-
const width = this.editor.getLayoutInfo().width - this.editor.getLayoutInfo().minimap.minimapCanvasOuterWidth - this.editor.getLayoutInfo().verticalScrollbarWidth;
80-
this.stickyScrollWidget.getDomNode().style.width = `${width}px`;
88+
const width = this._editor.getLayoutInfo().width - this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth - this._editor.getLayoutInfo().verticalScrollbarWidth;
89+
this._stickyScrollWidget.getDomNode().style.width = `${width}px`;
8190
}
8291

8392
private renderStickyScroll() {
84-
if (!(this.editor.hasModel())) {
93+
if (!(this._editor.hasModel())) {
8594
return;
8695
}
87-
const model = this.editor.getModel();
88-
if (this.stickyLineCandidateProvider.getVersionId() !== model.getVersionId()) {
96+
const model = this._editor.getModel();
97+
if (this._stickyLineCandidateProvider.getVersionId() !== model.getVersionId()) {
8998
// Old _ranges not updated yet
9099
return;
91100
}
92-
this.stickyScrollWidget.setState(this.getScrollWidgetState());
101+
this._widgetState = this.getScrollWidgetState();
102+
this._stickyScrollWidget.setState(this._widgetState);
93103
}
94104

95-
private getScrollWidgetState(): StickyScrollWidgetState {
96-
const lineHeight: number = this.editor.getOption(EditorOption.lineHeight);
97-
const maxNumberStickyLines = this.editor.getOption(EditorOption.experimental).stickyScroll.maxLineCount;
98-
const scrollTop: number = this.editor.getScrollTop();
105+
public getScrollWidgetState(): StickyScrollWidgetState {
106+
const lineHeight: number = this._editor.getOption(EditorOption.lineHeight);
107+
const maxNumberStickyLines = this._editor.getOption(EditorOption.experimental).stickyScroll.maxLineCount;
108+
const scrollTop: number = this._editor.getScrollTop();
99109
let lastLineRelativePosition: number = 0;
100110
const lineNumbers: number[] = [];
101-
const arrayVisibleRanges = this.editor.getVisibleRanges();
111+
const arrayVisibleRanges = this._editor.getVisibleRanges();
102112
if (arrayVisibleRanges.length !== 0) {
103113
const fullVisibleRange = new StickyRange(arrayVisibleRanges[0].startLineNumber, arrayVisibleRanges[arrayVisibleRanges.length - 1].endLineNumber);
104-
const candidateRanges = this.stickyLineCandidateProvider.getCandidateStickyLinesIntersecting(fullVisibleRange);
114+
const candidateRanges = this._stickyLineCandidateProvider.getCandidateStickyLinesIntersecting(fullVisibleRange);
105115
for (const range of candidateRanges) {
106116
const start = range.startLineNumber;
107117
const end = range.endLineNumber;
@@ -110,9 +120,9 @@ export class StickyScrollController extends Disposable implements IEditorContrib
110120
const topOfElementAtDepth = (depth - 1) * lineHeight;
111121
const bottomOfElementAtDepth = depth * lineHeight;
112122

113-
const bottomOfBeginningLine = this.editor.getBottomForLineNumber(start) - scrollTop;
114-
const topOfEndLine = this.editor.getTopForLineNumber(end) - scrollTop;
115-
const bottomOfEndLine = this.editor.getBottomForLineNumber(end) - scrollTop;
123+
const bottomOfBeginningLine = this._editor.getBottomForLineNumber(start) - scrollTop;
124+
const topOfEndLine = this._editor.getTopForLineNumber(end) - scrollTop;
125+
const bottomOfEndLine = this._editor.getBottomForLineNumber(end) - scrollTop;
116126

117127
if (topOfElementAtDepth > topOfEndLine && topOfElementAtDepth <= bottomOfEndLine) {
118128
lineNumbers.push(start);
@@ -133,6 +143,6 @@ export class StickyScrollController extends Disposable implements IEditorContrib
133143

134144
override dispose(): void {
135145
super.dispose();
136-
this.sessionStore.dispose();
146+
this._sessionStore.dispose();
137147
}
138148
}

src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,24 @@ export class StickyLineCandidateProvider extends Disposable {
3333
public readonly onStickyScrollChange = this.onStickyScrollChangeEmitter.event;
3434

3535
static readonly ID = 'store.contrib.stickyScrollController';
36-
private readonly editor: ICodeEditor;
37-
private readonly languageFeaturesService: ILanguageFeaturesService;
38-
private readonly updateSoon: RunOnceScheduler;
36+
private readonly _editor: ICodeEditor;
37+
private readonly _languageFeaturesService: ILanguageFeaturesService;
38+
private readonly _updateSoon: RunOnceScheduler;
3939

40-
private cts: CancellationTokenSource | undefined;
41-
private outlineModel: StickyOutlineElement | undefined;
42-
private readonly sessionStore: DisposableStore = new DisposableStore();
43-
private modelVersionId: number = 0;
40+
private _cts: CancellationTokenSource | undefined;
41+
private _outlineModel: StickyOutlineElement | undefined;
42+
private readonly _sessionStore: DisposableStore = new DisposableStore();
43+
private _modelVersionId: number = 0;
4444

4545
constructor(
4646
editor: ICodeEditor,
47-
@ILanguageFeaturesService _languageFeaturesService: ILanguageFeaturesService,
47+
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
4848
) {
4949
super();
50-
this.editor = editor;
51-
this.languageFeaturesService = _languageFeaturesService;
52-
this.updateSoon = this._register(new RunOnceScheduler(() => this.update(), 50));
53-
this._register(this.editor.onDidChangeConfiguration(e => {
50+
this._editor = editor;
51+
this._languageFeaturesService = languageFeaturesService;
52+
this._updateSoon = this._register(new RunOnceScheduler(() => this.update(), 50));
53+
this._register(this._editor.onDidChangeConfiguration(e => {
5454
if (e.hasChanged(EditorOption.experimental)) {
5555
this.readConfiguration();
5656
}
@@ -59,40 +59,40 @@ export class StickyLineCandidateProvider extends Disposable {
5959
}
6060

6161
private readConfiguration() {
62-
const options = this.editor.getOption(EditorOption.experimental);
62+
const options = this._editor.getOption(EditorOption.experimental);
6363
if (options.stickyScroll.enabled === false) {
64-
this.sessionStore.clear();
64+
this._sessionStore.clear();
6565
return;
6666
} else {
67-
this.sessionStore.add(this.editor.onDidChangeModel(() => this.update()));
68-
this.sessionStore.add(this.editor.onDidChangeHiddenAreas(() => this.update()));
69-
this.sessionStore.add(this.editor.onDidChangeModelContent(() => this.updateSoon.schedule()));
70-
this.sessionStore.add(this.languageFeaturesService.documentSymbolProvider.onDidChange(() => this.update()));
67+
this._sessionStore.add(this._editor.onDidChangeModel(() => this.update()));
68+
this._sessionStore.add(this._editor.onDidChangeHiddenAreas(() => this.update()));
69+
this._sessionStore.add(this._editor.onDidChangeModelContent(() => this._updateSoon.schedule()));
70+
this._sessionStore.add(this._languageFeaturesService.documentSymbolProvider.onDidChange(() => this.update()));
7171
this.update();
7272
}
7373
}
7474

7575
public getVersionId() {
76-
return this.modelVersionId;
76+
return this._modelVersionId;
7777
}
7878

79-
private async update(): Promise<void> {
80-
this.cts?.dispose(true);
81-
this.cts = new CancellationTokenSource();
82-
await this.updateOutlineModel(this.cts.token);
79+
public async update(): Promise<void> {
80+
this._cts?.dispose(true);
81+
this._cts = new CancellationTokenSource();
82+
await this.updateOutlineModel(this._cts.token);
8383
this.onStickyScrollChangeEmitter.fire();
8484
}
8585

8686
private async updateOutlineModel(token: CancellationToken) {
87-
if (this.editor.hasModel()) {
88-
const model = this.editor.getModel();
87+
if (this._editor.hasModel()) {
88+
const model = this._editor.getModel();
8989
const modelVersionId = model.getVersionId();
90-
const outlineModel = await OutlineModel.create(this.languageFeaturesService.documentSymbolProvider, model, token) as OutlineModel;
90+
const outlineModel = await OutlineModel.create(this._languageFeaturesService.documentSymbolProvider, model, token) as OutlineModel;
9191
if (token.isCancellationRequested) {
9292
return;
9393
}
94-
this.outlineModel = StickyOutlineElement.fromOutlineModel(outlineModel);
95-
this.modelVersionId = modelVersionId;
94+
this._outlineModel = StickyOutlineElement.fromOutlineModel(outlineModel);
95+
this._modelVersionId = modelVersionId;
9696
}
9797
}
9898

@@ -115,8 +115,8 @@ export class StickyLineCandidateProvider extends Disposable {
115115

116116
public getCandidateStickyLinesIntersecting(range: StickyRange): StickyLineCandidate[] {
117117
let stickyLineCandidates: StickyLineCandidate[] = [];
118-
this.getCandidateStickyLinesIntersectingFromOutline(range, this.outlineModel as StickyOutlineElement, stickyLineCandidates, 0, -1);
119-
const hiddenRanges: Range[] | undefined = this.editor._getViewModel()?.getHiddenAreas();
118+
this.getCandidateStickyLinesIntersectingFromOutline(range, this._outlineModel as StickyOutlineElement, stickyLineCandidates, 0, -1);
119+
const hiddenRanges: Range[] | undefined = this._editor._getViewModel()?.getHiddenAreas();
120120
if (hiddenRanges) {
121121
for (const hiddenRange of hiddenRanges) {
122122
stickyLineCandidates = stickyLineCandidates.filter(stickyLine => !(stickyLine.startLineNumber >= hiddenRange.startLineNumber && stickyLine.endLineNumber <= hiddenRange.endLineNumber + 1));
@@ -127,7 +127,7 @@ export class StickyLineCandidateProvider extends Disposable {
127127

128128
override dispose(): void {
129129
super.dispose();
130-
this.sessionStore.dispose();
130+
this._sessionStore.dispose();
131131
}
132132
}
133133

0 commit comments

Comments
 (0)