Skip to content

Commit

Permalink
Merge pull request #159198 from microsoft/aiday/issue157165
Browse files Browse the repository at this point in the history
When no document symbol provider use the folding model for the sticky scroll
  • Loading branch information
Aiday Marlen Kyzy committed Aug 30, 2022
2 parents 2ba0464 + cb8f0bb commit f62d2c8
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export class StickyScrollController extends Disposable implements IEditorContrib
this._stickyLineCandidateProvider = new StickyLineCandidateProvider(this._editor, _languageFeaturesService);
this._widgetState = new StickyScrollWidgetState([], 0);

this._register(this._stickyScrollWidget);
this._register(this._stickyLineCandidateProvider);
this._register(this._editor.onDidChangeConfiguration(e => {
if (e.hasChanged(EditorOption.stickyScroll)) {
this.readConfiguration();
Expand Down
64 changes: 61 additions & 3 deletions src/vs/editor/contrib/stickyScroll/browser/stickyScrollProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { RunOnceScheduler } from 'vs/base/common/async';
import { Range } from 'vs/editor/common/core/range';
import { Emitter } from 'vs/base/common/event';
import { binarySearch } from 'vs/base/common/arrays';
import { FoldingController } from 'vs/editor/contrib/folding/browser/folding';
import { FoldingModel } from 'vs/editor/contrib/folding/browser/foldingModel';

export class StickyRange {
constructor(
Expand Down Expand Up @@ -92,7 +94,24 @@ export class StickyLineCandidateProvider extends Disposable {
if (token.isCancellationRequested) {
return;
}
this._outlineModel = StickyOutlineElement.fromOutlineModel(outlineModel, -1);
if (outlineModel.children.size !== 0) {
this._outlineModel = StickyOutlineElement.fromOutlineModel(outlineModel, -1);
} else {
const foldingController = FoldingController.get(this._editor);
const foldingModel = await foldingController?.getFoldingModel();
if (token.isCancellationRequested) {
return;
}
if (foldingModel && foldingModel.regions.length !== 0) {
this._outlineModel = StickyOutlineElement.fromFoldingModel(foldingModel);
} else {
this._outlineModel = new StickyOutlineElement(
new StickyRange(-1, -1),
[],
undefined
);
}
}
this._modelVersionId = modelVersionId;
}
}
Expand Down Expand Up @@ -191,9 +210,44 @@ class StickyOutlineElement {
}
return new StickyOutlineElement(
range,
children
children,
undefined
);
}

public static fromFoldingModel(foldingModel: FoldingModel): StickyOutlineElement {
const regions = foldingModel.regions;
const length = regions.length;
let range: StickyRange | undefined;
const stackOfParents: StickyRange[] = [];

const stickyOutlineElement = new StickyOutlineElement(
undefined,
[],
undefined
);
let parentStickyOutlineElement = stickyOutlineElement;

for (let i = 0; i < length; i++) {
range = new StickyRange(regions.getStartLineNumber(i), regions.getEndLineNumber(i));
while (stackOfParents.length !== 0 && (range.startLineNumber < stackOfParents[stackOfParents.length - 1].startLineNumber || range.endLineNumber > stackOfParents[stackOfParents.length - 1].endLineNumber)) {
stackOfParents.pop();
if (parentStickyOutlineElement.parent !== undefined) {
parentStickyOutlineElement = parentStickyOutlineElement.parent;
}
}
const child = new StickyOutlineElement(
range,
[],
parentStickyOutlineElement
);
parentStickyOutlineElement.children.push(child);
parentStickyOutlineElement = child;
stackOfParents.push(range);
}
return stickyOutlineElement;
}

constructor(
/**
* Range of line numbers spanned by the current scope
Expand All @@ -202,7 +256,11 @@ class StickyOutlineElement {
/**
* Must be sorted by start line number
*/
public readonly children: readonly StickyOutlineElement[],
public readonly children: StickyOutlineElement[],
/**
* Parent sticky outline element
*/
public readonly parent: StickyOutlineElement | undefined
) {
}
}
12 changes: 6 additions & 6 deletions src/vs/editor/test/browser/testCodeEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ function isTextModel(arg: ITextModel | string | string[] | ITextBufferFactory):

function _withTestCodeEditor(arg: ITextModel | string | string[] | ITextBufferFactory, options: TestCodeEditorInstantiationOptions, callback: (editor: ITestCodeEditor, viewModel: ViewModel, instantiationService: TestInstantiationService) => void): void;
function _withTestCodeEditor(arg: ITextModel | string | string[] | ITextBufferFactory, options: TestCodeEditorInstantiationOptions, callback: (editor: ITestCodeEditor, viewModel: ViewModel, instantiationService: TestInstantiationService) => Promise<void>): Promise<void>;
function _withTestCodeEditor(arg: ITextModel | string | string[] | ITextBufferFactory, options: TestCodeEditorInstantiationOptions, callback: (editor: ITestCodeEditor, viewModel: ViewModel, instantiationService: TestInstantiationService) => Promise<void> | void): Promise<void> | void {
async function _withTestCodeEditor(arg: ITextModel | string | string[] | ITextBufferFactory, options: TestCodeEditorInstantiationOptions, callback: (editor: ITestCodeEditor, viewModel: ViewModel, instantiationService: TestInstantiationService) => Promise<void> | void): Promise<Promise<void> | void> {
const disposables = new DisposableStore();
const instantiationService = createCodeEditorServices(disposables, options.serviceCollection);
delete options.serviceCollection;
Expand All @@ -149,12 +149,12 @@ function _withTestCodeEditor(arg: ITextModel | string | string[] | ITextBufferFa
const editor = disposables.add(instantiateTestCodeEditor(instantiationService, model, options));
const viewModel = editor.getViewModel()!;
viewModel.setHasFocus(true);
const result = callback(<ITestCodeEditor>editor, editor.getViewModel()!, instantiationService);
if (result) {
return result.then(() => disposables.dispose());
try {
const result = callback(<ITestCodeEditor>editor, editor.getViewModel()!, instantiationService);
await result;
} finally {
disposables.dispose();
}

disposables.dispose();
}

export function createCodeEditorServices(disposables: DisposableStore, services: ServiceCollection = new ServiceCollection()): TestInstantiationService {
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/test/browser/workbenchTestServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export class TestTextResourceEditor extends TextResourceEditor {
export class TestTextFileEditor extends TextFileEditor {

protected override createEditorControl(parent: HTMLElement, configuration: any): void {
this.editorControl = this.instantiationService.createInstance(TestCodeEditor, parent, configuration, {});
this.editorControl = this.instantiationService.createInstance(TestCodeEditor, parent, configuration, { contributions: [] });
}

setSelection(selection: Selection | undefined, reason: EditorPaneSelectionChangeReason): void {
Expand Down

0 comments on commit f62d2c8

Please sign in to comment.