Skip to content

Commit 3cba0ec

Browse files
author
Aiday Marlen Kyzy
authored
Merge pull request microsoft#159321 from microsoft/aiday/issue159271
Sticky Scroll : Take into account child scope starting on the same line as the parent scope
2 parents ec5b41d + 99de729 commit 3cba0ec

File tree

2 files changed

+103
-8
lines changed

2 files changed

+103
-8
lines changed

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class StickyLineCandidateProvider extends Disposable {
9292
if (token.isCancellationRequested) {
9393
return;
9494
}
95-
this._outlineModel = StickyOutlineElement.fromOutlineModel(outlineModel);
95+
this._outlineModel = StickyOutlineElement.fromOutlineModel(outlineModel, -1);
9696
this._modelVersionId = modelVersionId;
9797
}
9898
}
@@ -158,12 +158,20 @@ export class StickyLineCandidateProvider extends Disposable {
158158
}
159159

160160
class StickyOutlineElement {
161-
public static fromOutlineModel(outlineModel: OutlineModel | OutlineElement | OutlineGroup): StickyOutlineElement {
161+
public static fromOutlineModel(outlineModel: OutlineModel | OutlineElement | OutlineGroup, previousStartLine: number): StickyOutlineElement {
162162

163163
const children: StickyOutlineElement[] = [];
164164
for (const child of outlineModel.children.values()) {
165-
if (child instanceof OutlineElement && child.symbol.selectionRange.startLineNumber !== child.symbol.range.endLineNumber || child instanceof OutlineGroup || child instanceof OutlineModel) {
166-
children.push(StickyOutlineElement.fromOutlineModel(child));
165+
if (child instanceof OutlineGroup || child instanceof OutlineModel) {
166+
children.push(StickyOutlineElement.fromOutlineModel(child, previousStartLine));
167+
} else if (child instanceof OutlineElement && child.symbol.selectionRange.startLineNumber !== child.symbol.range.endLineNumber) {
168+
if (child.symbol.selectionRange.startLineNumber !== previousStartLine) {
169+
children.push(StickyOutlineElement.fromOutlineModel(child, child.symbol.selectionRange.startLineNumber));
170+
} else {
171+
for (const subchild of child.children.values()) {
172+
children.push(StickyOutlineElement.fromOutlineModel(subchild, child.symbol.selectionRange.startLineNumber));
173+
}
174+
}
167175
}
168176
}
169177
children.sort((child1, child2) => {

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

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import { LanguageFeaturesService } from 'vs/editor/common/services/languageFeatu
1212
import { DocumentSymbol, SymbolKind } from 'vs/editor/common/languages';
1313
import { StickyLineCandidate, StickyLineCandidateProvider } from 'vs/editor/contrib/stickyScroll/browser/stickyScrollProvider';
1414
import { EditorOption } from 'vs/editor/common/config/editorOptions';
15+
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
1516

1617
suite('Sticky Scroll Tests', () => {
1718

1819
const serviceCollection = new ServiceCollection(
19-
[ILanguageFeaturesService, new LanguageFeaturesService()]
20+
[ILanguageFeaturesService, new LanguageFeaturesService()],
21+
[ILogService, new NullLogService()]
2022
);
2123

2224
const text = [
@@ -121,10 +123,10 @@ suite('Sticky Scroll Tests', () => {
121123
await withAsyncTestCodeEditor(model, { serviceCollection }, async (editor, _viewModel, instantiationService) => {
122124

123125
const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController);
124-
await stickyScrollController.stickyScrollCandidateProvider.update();
125126
const lineHeight: number = editor.getOption(EditorOption.lineHeight);
126127
const languageService: ILanguageFeaturesService = instantiationService.get(ILanguageFeaturesService);
127128
languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel());
129+
await stickyScrollController.stickyScrollCandidateProvider.update();
128130
let state;
129131

130132
editor.setScrollTop(1);
@@ -163,12 +165,11 @@ suite('Sticky Scroll Tests', () => {
163165
await withAsyncTestCodeEditor(model, { serviceCollection }, async (editor, viewModel, instantiationService) => {
164166

165167
const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController);
166-
await stickyScrollController.stickyScrollCandidateProvider.update();
167168
const lineHeight = editor.getOption(EditorOption.lineHeight);
168169

169170
const languageService = instantiationService.get(ILanguageFeaturesService);
170171
languageService.documentSymbolProvider.register('*', documentSymbolProviderForTestModel());
171-
172+
await stickyScrollController.stickyScrollCandidateProvider.update();
172173
editor.setHiddenAreas([{ startLineNumber: 2, endLineNumber: 2, startColumn: 1, endColumn: 1 }, { startLineNumber: 10, endLineNumber: 11, startColumn: 1, endColumn: 1 }]);
173174
let state;
174175

@@ -197,4 +198,90 @@ suite('Sticky Scroll Tests', () => {
197198
model.dispose();
198199
});
199200
});
201+
202+
const textWithScopesWithSameStartingLines = [
203+
'class TestClass { foo() {',
204+
'function bar(){',
205+
'',
206+
'}}',
207+
'}',
208+
''
209+
].join('\n');
210+
211+
function documentSymbolProviderForSecondTestModel() {
212+
return {
213+
provideDocumentSymbols() {
214+
return [
215+
{
216+
name: 'TestClass',
217+
detail: 'TestClass',
218+
kind: SymbolKind.Class,
219+
tags: [],
220+
range: { startLineNumber: 1, endLineNumber: 5, startColumn: 1, endColumn: 1 },
221+
selectionRange: { startLineNumber: 1, endLineNumber: 1, startColumn: 1, endColumn: 1 },
222+
children: [
223+
{
224+
name: 'foo',
225+
detail: 'foo',
226+
kind: SymbolKind.Function,
227+
tags: [],
228+
range: { startLineNumber: 1, endLineNumber: 4, startColumn: 1, endColumn: 1 },
229+
selectionRange: { startLineNumber: 1, endLineNumber: 1, startColumn: 1, endColumn: 1 },
230+
children: [
231+
{
232+
name: 'bar',
233+
detail: 'bar',
234+
kind: SymbolKind.Function,
235+
tags: [],
236+
range: { startLineNumber: 2, endLineNumber: 4, startColumn: 1, endColumn: 1 },
237+
selectionRange: { startLineNumber: 2, endLineNumber: 2, startColumn: 1, endColumn: 1 },
238+
children: []
239+
} as DocumentSymbol
240+
]
241+
} as DocumentSymbol,
242+
]
243+
} as DocumentSymbol
244+
];
245+
}
246+
};
247+
}
248+
249+
test('issue #159271 : render the correct widget state when the child scope starts on the same line as the parent scope', async () => {
250+
251+
const model = createTextModel(textWithScopesWithSameStartingLines);
252+
await withAsyncTestCodeEditor(model, { serviceCollection }, async (editor, _viewModel, instantiationService) => {
253+
254+
const stickyScrollController: StickyScrollController = editor.registerAndInstantiateContribution(StickyScrollController.ID, StickyScrollController);
255+
const lineHeight = editor.getOption(EditorOption.lineHeight);
256+
257+
const languageService = instantiationService.get(ILanguageFeaturesService);
258+
languageService.documentSymbolProvider.register('*', documentSymbolProviderForSecondTestModel());
259+
await stickyScrollController.stickyScrollCandidateProvider.update();
260+
let state;
261+
262+
editor.setScrollTop(1);
263+
state = stickyScrollController.getScrollWidgetState();
264+
assert.deepStrictEqual(state.lineNumbers, [1, 2]);
265+
266+
editor.setScrollTop(lineHeight + 1);
267+
state = stickyScrollController.getScrollWidgetState();
268+
assert.deepStrictEqual(state.lineNumbers, [1, 2]);
269+
270+
editor.setScrollTop(2 * lineHeight + 1);
271+
state = stickyScrollController.getScrollWidgetState();
272+
assert.deepStrictEqual(state.lineNumbers, [1]);
273+
274+
editor.setScrollTop(3 * lineHeight + 1);
275+
state = stickyScrollController.getScrollWidgetState();
276+
assert.deepStrictEqual(state.lineNumbers, [1]);
277+
278+
editor.setScrollTop(4 * lineHeight + 1);
279+
state = stickyScrollController.getScrollWidgetState();
280+
assert.deepStrictEqual(state.lineNumbers, []);
281+
282+
stickyScrollController.dispose();
283+
stickyScrollController.stickyScrollCandidateProvider.dispose();
284+
model.dispose();
285+
});
286+
});
200287
});

0 commit comments

Comments
 (0)