From 44f89fc13c30b5872efa7406b15c2b9d17a3726c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 29 Mar 2021 11:12:54 +0200 Subject: [PATCH] editors - do not wait for editor to resolve to signal restored phase (fix #119059) --- .../editor/common/services/resolverService.ts | 5 - .../workbench/browser/parts/editor/editor.ts | 1 - .../browser/parts/editor/editorGroupView.ts | 44 ++++---- .../browser/parts/editor/editorPart.ts | 63 +++++------ .../browser/parts/editor/editorsObserver.ts | 4 +- .../test/browser/backupRestorer.test.ts | 4 +- .../backup/test/browser/backupTracker.test.ts | 4 +- .../electron-browser/backupTracker.test.ts | 4 +- .../files/test/browser/editorAutoSave.test.ts | 2 +- .../browser/textFileEditorTracker.test.ts | 4 +- .../test/browser/editorGroupsService.test.ts | 100 +++++++++--------- .../editor/test/browser/editorService.test.ts | 84 ++++----------- .../test/browser/editorsObserver.test.ts | 5 +- .../history/test/browser/history.test.ts | 4 +- .../test/browser/workbenchTestServices.ts | 4 +- 15 files changed, 127 insertions(+), 205 deletions(-) diff --git a/src/vs/editor/common/services/resolverService.ts b/src/vs/editor/common/services/resolverService.ts index 74470a81017..38e885c223f 100644 --- a/src/vs/editor/common/services/resolverService.ts +++ b/src/vs/editor/common/services/resolverService.ts @@ -57,11 +57,6 @@ export interface ITextEditorModel extends IEditorModel { */ isReadonly(): boolean; - /** - * Figure out if this model is resolved or not. - */ - isResolved(): this is IResolvedTextEditorModel; - /** * The mode id of the text model if known. */ diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 68146c8b734..08ac7156c0c 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -135,7 +135,6 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito readonly onDidCloseEditor: Event; readonly group: EditorGroup; - readonly whenRestored: Promise; readonly titleHeight: IEditorGroupTitleHeight; diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 2f95e8cf947..5c681da5775 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -100,12 +100,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#endregion - private readonly _group: EditorGroup; - private active: boolean | undefined; private dimension: Dimension | undefined; - private readonly _whenRestored: Promise; private isRestored = false; private readonly scopedInstantiationService: IInstantiationService; @@ -213,9 +210,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } //#endregion - this._whenRestored = this.restoreEditors(from); - this._whenRestored.then(() => this.isRestored = true); + // Restore editors if provided + this.restoreEditors(from); + // Register Listeners this.registerListeners(); } @@ -439,7 +437,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return this.titleAreaControl; } - private async restoreEditors(from: IEditorGroupView | ISerializedEditorGroup | null): Promise { + private restoreEditors(from: IEditorGroupView | ISerializedEditorGroup | null): void { if (this._group.count === 0) { return; // nothing to show } @@ -463,16 +461,21 @@ export class EditorGroupView extends Themable implements IEditorGroupView { const activeElement = document.activeElement; - // Show active editor - await this.doShowEditor(activeEditor, { active: true, isNew: false /* restored */ }, options); + // Show active editor (intentionally not using async to keep + // `restoreEditors` from executing in same stack) + this.doShowEditor(activeEditor, { active: true, isNew: false /* restored */ }, options).then(() => { - // Set focused now if this is the active group and focus has - // not changed meanwhile. This prevents focus from being - // stolen accidentally on startup when the user already - // clicked somewhere. - if (this.accessor.activeGroup === this && activeElement === document.activeElement) { - this.focus(); - } + // Set focused now if this is the active group and focus has + // not changed meanwhile. This prevents focus from being + // stolen accidentally on startup when the user already + // clicked somewhere. + if (this.accessor.activeGroup === this && activeElement === document.activeElement) { + this.focus(); + } + + // Signal restored + this.isRestored = true; + }); } //#region event handling @@ -683,6 +686,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //region IEditorGroupView + private readonly _group: EditorGroup; get group(): EditorGroup { return this._group; } @@ -704,10 +708,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return this._disposed; } - get whenRestored(): Promise { - return this._whenRestored; - } - get isEmpty(): boolean { return this._group.count === 0; } @@ -977,10 +977,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return showEditorResult; } - private async doShowEditor(editor: EditorInput, context: { active: boolean, isNew: boolean }, options?: EditorOptions): Promise { + private doShowEditor(editor: EditorInput, context: { active: boolean, isNew: boolean }, options?: EditorOptions): Promise { // Show in editor control if the active editor changed - let openEditorPromise: Promise | undefined; + let openEditorPromise: Promise; if (context.active) { openEditorPromise = (async () => { try { @@ -1001,7 +1001,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } })(); } else { - openEditorPromise = undefined; // inactive: return undefined as result to signal this + openEditorPromise = Promise.resolve(undefined); // inactive: return undefined as result to signal this } // Show in title control after editor control because some actions depend on it diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 01dc39281e7..398f9a19213 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -27,11 +27,9 @@ import { CenteredViewLayout } from 'vs/base/browser/ui/centered/centeredViewLayo import { onUnexpectedError } from 'vs/base/common/errors'; import { Parts, IWorkbenchLayoutService, Position } from 'vs/workbench/services/layout/browser/layoutService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { MementoObject } from 'vs/workbench/common/memento'; import { assertIsDefined } from 'vs/base/common/types'; import { IBoundarySashes } from 'vs/base/browser/ui/grid/gridview'; import { CompositeDragAndDropObserver } from 'vs/workbench/browser/dnd'; -import { Promises } from 'vs/base/common/async'; interface IEditorPartUIState { serializedGrid: ISerializedGrid; @@ -121,8 +119,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro //#endregion - private readonly workspaceMemento: MementoObject; - private readonly globalMemento: MementoObject; + private readonly workspaceMemento = this.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); + private readonly globalMemento = this.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE); private readonly groupViews = new Map(); private mostRecentActiveGroups: GroupIdentifier[] = []; @@ -132,10 +130,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro private centeredLayoutWidget!: CenteredViewLayout; private gridWidget!: SerializableGrid; - private gridWidgetView: GridWidgetView; - - private _whenRestored: Promise; - private whenRestoredResolve: (() => void) | undefined; + private readonly gridWidgetView = this._register(new GridWidgetView()); constructor( @IInstantiationService private readonly instantiationService: IInstantiationService, @@ -146,13 +141,6 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro ) { super(Parts.EDITOR_PART, { hasTitle: false }, themeService, storageService, layoutService); - this.gridWidgetView = new GridWidgetView(); - - this.workspaceMemento = this.getMemento(StorageScope.WORKSPACE, StorageTarget.MACHINE); - this.globalMemento = this.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE); - - this._whenRestored = new Promise(resolve => (this.whenRestoredResolve = resolve)); - this.registerListeners(); } @@ -217,6 +205,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro return (this.gridWidget && this.gridWidget.orientation === Orientation.VERTICAL) ? GroupOrientation.VERTICAL : GroupOrientation.HORIZONTAL; } + private whenRestoredResolve: (() => void) | undefined; + private readonly _whenRestored = new Promise(resolve => (this.whenRestoredResolve = resolve)); get whenRestored(): Promise { return this._whenRestored; } @@ -835,13 +825,25 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro this.container.classList.add('content'); parent.appendChild(this.container); - // Grid control with center layout + // Grid control this.doCreateGridControl(options); + // Centered layout widget this.centeredLayoutWidget = this._register(new CenteredViewLayout(this.container, this.gridWidgetView, this.globalMemento[EditorPart.EDITOR_PART_CENTERED_VIEW_STORAGE_KEY])); - // Drop support - this._register(this.createEditorDropTarget(this.container, Object.create(null))); + // Drag & Drop support + this.setupDragAndDropSupport(parent, this.container); + + // Signal restored + this.whenRestoredResolve?.(); + + return this.container; + } + + private setupDragAndDropSupport(parent: HTMLElement, container: HTMLElement): void { + + // Editor drop target + this._register(this.createEditorDropTarget(container, Object.create(null))); // No drop in the editor const overlay = document.createElement('div'); @@ -849,17 +851,11 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro parent.appendChild(overlay); // Hide the block if a mouse down event occurs #99065 - this._register(addDisposableGenericMouseDownListner(overlay, () => { - overlay.classList.remove('visible'); - })); + this._register(addDisposableGenericMouseDownListner(overlay, () => overlay.classList.remove('visible'))); this._register(CompositeDragAndDropObserver.INSTANCE.registerTarget(this.element, { - onDragStart: e => { - overlay.classList.add('visible'); - }, - onDragEnd: e => { - overlay.classList.remove('visible'); - } + onDragStart: e => overlay.classList.add('visible'), + onDragEnd: e => overlay.classList.remove('visible') })); let panelOpenerTimeout: any; @@ -920,8 +916,6 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } } })); - - return this.container; } centerLayout(active: boolean): void { @@ -955,13 +949,6 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro this.doSetGroupActive(initialGroup); } - // Signal restored - Promises.settled(this.groups.map(group => group.whenRestored)).finally(() => { - if (this.whenRestoredResolve) { - this.whenRestoredResolve(); - } - }); - // Update container this.updateContainer(); @@ -1143,9 +1130,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro this.groupViews.clear(); // Grid widget - if (this.gridWidget) { - this.gridWidget.dispose(); - } + this.gridWidget?.dispose(); super.dispose(); } diff --git a/src/vs/workbench/browser/parts/editor/editorsObserver.ts b/src/vs/workbench/browser/parts/editor/editorsObserver.ts index 4c68ea92054..cde2a302c69 100644 --- a/src/vs/workbench/browser/parts/editor/editorsObserver.ts +++ b/src/vs/workbench/browser/parts/editor/editorsObserver.ts @@ -384,10 +384,8 @@ export class EditorsObserver extends Disposable { private loadState(): void { const serialized = this.storageService.get(EditorsObserver.STORAGE_KEY, StorageScope.WORKSPACE); - // Previous state: + // Previous state: Load editors map from persisted state if (serialized) { - - // Load editors map from persisted state this.deserialize(JSON.parse(serialized)); } diff --git a/src/vs/workbench/contrib/backup/test/browser/backupRestorer.test.ts b/src/vs/workbench/contrib/backup/test/browser/backupRestorer.test.ts index 1cbc3778c2b..7d5e6e28dd3 100644 --- a/src/vs/workbench/contrib/backup/test/browser/backupRestorer.test.ts +++ b/src/vs/workbench/contrib/backup/test/browser/backupRestorer.test.ts @@ -48,7 +48,7 @@ suite('BackupRestorer', () => { const instantiationService = workbenchInstantiationService(); instantiationService.stub(IBackupFileService, backupFileService); - const part = createEditorPart(instantiationService, disposables); + const part = await createEditorPart(instantiationService, disposables); instantiationService.stub(IEditorGroupsService, part); @@ -57,8 +57,6 @@ suite('BackupRestorer', () => { accessor = instantiationService.createInstance(TestServiceAccessor); - await part.whenRestored; - disposables.add(instantiationService.createInstance(BrowserBackupTracker)); const restorer = instantiationService.createInstance(TestBackupRestorer); diff --git a/src/vs/workbench/contrib/backup/test/browser/backupTracker.test.ts b/src/vs/workbench/contrib/backup/test/browser/backupTracker.test.ts index fecd4daba47..9ecdb9bcda0 100644 --- a/src/vs/workbench/contrib/backup/test/browser/backupTracker.test.ts +++ b/src/vs/workbench/contrib/backup/test/browser/backupTracker.test.ts @@ -53,7 +53,7 @@ suite('BackupTracker (browser)', function () { const instantiationService = workbenchInstantiationService(); instantiationService.stub(IBackupFileService, backupFileService); - const part = createEditorPart(instantiationService, disposables); + const part = await createEditorPart(instantiationService, disposables); disposables.add(registerTestResourceEditor()); @@ -64,8 +64,6 @@ suite('BackupTracker (browser)', function () { accessor = instantiationService.createInstance(TestServiceAccessor); - await part.whenRestored; - const tracker = disposables.add(instantiationService.createInstance(TestBackupTracker)); return { accessor, part, tracker, backupFileService, instantiationService, cleanup: () => disposables.dispose() }; diff --git a/src/vs/workbench/contrib/backup/test/electron-browser/backupTracker.test.ts b/src/vs/workbench/contrib/backup/test/electron-browser/backupTracker.test.ts index 54580acfab3..27602496a68 100644 --- a/src/vs/workbench/contrib/backup/test/electron-browser/backupTracker.test.ts +++ b/src/vs/workbench/contrib/backup/test/electron-browser/backupTracker.test.ts @@ -135,7 +135,7 @@ flakySuite('BackupTracker (native)', function () { configurationService )); - const part = createEditorPart(instantiationService, disposables); + const part = await createEditorPart(instantiationService, disposables); instantiationService.stub(IEditorGroupsService, part); @@ -144,8 +144,6 @@ flakySuite('BackupTracker (native)', function () { accessor = instantiationService.createInstance(TestServiceAccessor); - await part.whenRestored; - const tracker = instantiationService.createInstance(TestBackupTracker); const cleanup = async () => { diff --git a/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts b/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts index 9bb8ebf0634..1543fea70d0 100644 --- a/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/editorAutoSave.test.ts @@ -44,7 +44,7 @@ suite('EditorAutoSave', () => { configurationService )); - const part = createEditorPart(instantiationService, disposables); + const part = await createEditorPart(instantiationService, disposables); instantiationService.stub(IEditorGroupsService, part); diff --git a/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts b/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts index 91b0271c6ea..01cf917692d 100644 --- a/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts @@ -53,7 +53,7 @@ suite('Files - TextFileEditorTracker', () => { )); } - const part = createEditorPart(instantiationService, disposables); + const part = await createEditorPart(instantiationService, disposables); instantiationService.stub(IEditorGroupsService, part); @@ -63,8 +63,6 @@ suite('Files - TextFileEditorTracker', () => { const accessor = instantiationService.createInstance(TestServiceAccessor); disposables.add((accessor.textFileService.files)); - await part.whenRestored; - disposables.add(instantiationService.createInstance(TextFileEditorTracker)); return accessor; diff --git a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts index 5a13a21e421..caaada0ce8e 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -29,15 +29,15 @@ suite('EditorGroupsService', () => { disposables.clear(); }); - function createPart(instantiationService = workbenchInstantiationService()): [TestEditorPart, ITestInstantiationService] { - const part = createEditorPart(instantiationService, disposables); + async function createPart(instantiationService = workbenchInstantiationService()): Promise<[TestEditorPart, ITestInstantiationService]> { + const part = await createEditorPart(instantiationService, disposables); return [part, instantiationService]; } test('groups basics', async function () { const instantiationService = workbenchInstantiationService({ contextKeyService: instantiationService => instantiationService.createInstance(MockScopableContextKeyService) }); - const [part] = createPart(instantiationService); + const [part] = await createPart(instantiationService); let activeGroupChangeCounter = 0; const activeGroupChangeListener = part.onDidChangeActiveGroup(() => { @@ -190,7 +190,7 @@ suite('EditorGroupsService', () => { }); test('save & restore state', async function () { - let [part, instantiationService] = createPart(); + let [part, instantiationService] = await createPart(); const rootGroup = part.groups[0]; const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT); @@ -207,7 +207,7 @@ suite('EditorGroupsService', () => { part.saveState(); part.dispose(); - let [restoredPart] = createPart(instantiationService); + let [restoredPart] = await createPart(instantiationService); assert.strictEqual(restoredPart.groups.length, 3); assert.ok(restoredPart.getGroup(rootGroup.id)); @@ -217,8 +217,8 @@ suite('EditorGroupsService', () => { restoredPart.clearState(); }); - test('groups index / labels', function () { - const [part] = createPart(); + test('groups index / labels', async function () { + const [part] = await createPart(); const rootGroup = part.groups[0]; const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT); @@ -274,7 +274,7 @@ suite('EditorGroupsService', () => { }); test('copy/merge groups', async () => { - const [part] = createPart(); + const [part] = await createPart(); let groupAddedCounter = 0; const groupAddedListener = part.onDidAddGroup(() => { @@ -316,7 +316,7 @@ suite('EditorGroupsService', () => { }); test('merge all groups', async () => { - const [part] = createPart(); + const [part] = await createPart(); const rootGroup = part.groups[0]; @@ -344,14 +344,14 @@ suite('EditorGroupsService', () => { }); test('whenRestored', async () => { - const [part] = createPart(); + const [part] = await createPart(); await part.whenRestored; assert.ok(true); }); - test('options', () => { - const [part] = createPart(); + test('options', async () => { + const [part] = await createPart(); let oldOptions!: IEditorPartOptions; let newOptions!: IEditorPartOptions; @@ -370,12 +370,10 @@ suite('EditorGroupsService', () => { }); test('editor basics', async function () { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); - await part.whenRestored; - let editorWillOpenCounter = 0; const editorWillOpenListener = group.onWillOpenEditor(() => { editorWillOpenCounter++; @@ -479,7 +477,7 @@ suite('EditorGroupsService', () => { }); test('openEditors / closeEditors', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -504,7 +502,7 @@ suite('EditorGroupsService', () => { }); test('closeEditor - dirty editor handling', async () => { - const [part, instantiationService] = createPart(); + const [part, instantiationService] = await createPart(); const accessor = instantiationService.createInstance(TestServiceAccessor); accessor.fileDialogService.setConfirmResult(ConfirmResult.DONT_SAVE); @@ -528,7 +526,7 @@ suite('EditorGroupsService', () => { }); test('closeEditor (one, opened in multiple groups)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -550,7 +548,7 @@ suite('EditorGroupsService', () => { }); test('closeEditors - dirty editor handling', async () => { - const [part, instantiationService] = createPart(); + const [part, instantiationService] = await createPart(); const accessor = instantiationService.createInstance(TestServiceAccessor); accessor.fileDialogService.setConfirmResult(ConfirmResult.DONT_SAVE); @@ -579,7 +577,7 @@ suite('EditorGroupsService', () => { }); test('closeEditors (except one)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -604,7 +602,7 @@ suite('EditorGroupsService', () => { }); test('closeEditors (except one, sticky editor)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -639,7 +637,7 @@ suite('EditorGroupsService', () => { }); test('closeEditors (saved only)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -663,7 +661,7 @@ suite('EditorGroupsService', () => { }); test('closeEditors (saved only, sticky editor)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -694,7 +692,7 @@ suite('EditorGroupsService', () => { }); test('closeEditors (direction: right)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -720,7 +718,7 @@ suite('EditorGroupsService', () => { }); test('closeEditors (direction: right, sticky editor)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -753,7 +751,7 @@ suite('EditorGroupsService', () => { }); test('closeEditors (direction: left)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -779,7 +777,7 @@ suite('EditorGroupsService', () => { }); test('closeEditors (direction: left, sticky editor)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -813,7 +811,7 @@ suite('EditorGroupsService', () => { }); test('closeAllEditors', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -834,7 +832,7 @@ suite('EditorGroupsService', () => { }); test('closeAllEditors - dirty editor handling', async () => { - const [part, instantiationService] = createPart(); + const [part, instantiationService] = await createPart(); const accessor = instantiationService.createInstance(TestServiceAccessor); accessor.fileDialogService.setConfirmResult(ConfirmResult.DONT_SAVE); @@ -863,7 +861,7 @@ suite('EditorGroupsService', () => { }); test('closeAllEditors (sticky editor)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -890,7 +888,7 @@ suite('EditorGroupsService', () => { }); test('moveEditor (same group)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -918,7 +916,7 @@ suite('EditorGroupsService', () => { }); test('moveEditor (across groups)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -939,7 +937,7 @@ suite('EditorGroupsService', () => { }); test('copyEditor (across groups)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -961,7 +959,7 @@ suite('EditorGroupsService', () => { }); test('replaceEditors', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -978,7 +976,7 @@ suite('EditorGroupsService', () => { }); test('replaceEditors - dirty editor handling', async () => { - const [part, instantiationService] = createPart(); + const [part, instantiationService] = await createPart(); const accessor = instantiationService.createInstance(TestServiceAccessor); accessor.fileDialogService.setConfirmResult(ConfirmResult.DONT_SAVE); @@ -1007,7 +1005,7 @@ suite('EditorGroupsService', () => { }); test('replaceEditors - forceReplaceDirty flag', async () => { - const [part, instantiationService] = createPart(); + const [part, instantiationService] = await createPart(); const accessor = instantiationService.createInstance(TestServiceAccessor); accessor.fileDialogService.setConfirmResult(ConfirmResult.DONT_SAVE); @@ -1034,7 +1032,7 @@ suite('EditorGroupsService', () => { }); test('replaceEditors - proper index handling', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -1067,8 +1065,8 @@ suite('EditorGroupsService', () => { assert.strictEqual(group.getEditorByIndex(4), input8); }); - test('find neighbour group (left/right)', function () { - const [part] = createPart(); + test('find neighbour group (left/right)', async function () { + const [part] = await createPart(); const rootGroup = part.activeGroup; const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT); @@ -1076,8 +1074,8 @@ suite('EditorGroupsService', () => { assert.strictEqual(rootGroup, part.findGroup({ direction: GroupDirection.LEFT }, rightGroup)); }); - test('find neighbour group (up/down)', function () { - const [part] = createPart(); + test('find neighbour group (up/down)', async function () { + const [part] = await createPart(); const rootGroup = part.activeGroup; const downGroup = part.addGroup(rootGroup, GroupDirection.DOWN); @@ -1085,8 +1083,8 @@ suite('EditorGroupsService', () => { assert.strictEqual(rootGroup, part.findGroup({ direction: GroupDirection.UP }, downGroup)); }); - test('find group by location (left/right)', function () { - const [part] = createPart(); + test('find group by location (left/right)', async function () { + const [part] = await createPart(); const rootGroup = part.activeGroup; const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT); const downGroup = part.addGroup(rightGroup, GroupDirection.DOWN); @@ -1101,16 +1099,16 @@ suite('EditorGroupsService', () => { assert.strictEqual(rightGroup, part.findGroup({ location: GroupLocation.PREVIOUS }, downGroup)); }); - test('applyLayout (2x2)', function () { - const [part] = createPart(); + test('applyLayout (2x2)', async function () { + const [part] = await createPart(); part.applyLayout({ groups: [{ groups: [{}, {}] }, { groups: [{}, {}] }], orientation: GroupOrientation.HORIZONTAL }); assert.strictEqual(part.groups.length, 4); }); - test('centeredLayout', function () { - const [part] = createPart(); + test('centeredLayout', async function () { + const [part] = await createPart(); part.centerLayout(true); @@ -1118,11 +1116,9 @@ suite('EditorGroupsService', () => { }); test('sticky editors', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; - await part.whenRestored; - assert.strictEqual(group.stickyCount, 0); assert.strictEqual(group.getEditors(EditorsOrder.SEQUENTIAL).length, 0); assert.strictEqual(group.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE).length, 0); @@ -1220,7 +1216,7 @@ suite('EditorGroupsService', () => { }); test('moveEditor with context (across groups)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); @@ -1245,7 +1241,7 @@ suite('EditorGroupsService', () => { }); test('copyEditor with context (across groups)', async () => { - const [part] = createPart(); + const [part] = await createPart(); const group = part.activeGroup; assert.strictEqual(group.isEmpty, true); diff --git a/src/vs/workbench/services/editor/test/browser/editorService.test.ts b/src/vs/workbench/services/editor/test/browser/editorService.test.ts index b2edff9eaed..698d8abef34 100644 --- a/src/vs/workbench/services/editor/test/browser/editorService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorService.test.ts @@ -56,8 +56,8 @@ suite('EditorService', () => { disposables.clear(); }); - function createEditorService(instantiationService: ITestInstantiationService = workbenchInstantiationService()): [EditorPart, EditorService, TestServiceAccessor] { - const part = createEditorPart(instantiationService, disposables); + async function createEditorService(instantiationService: ITestInstantiationService = workbenchInstantiationService()): Promise<[EditorPart, EditorService, TestServiceAccessor]> { + const part = await createEditorPart(instantiationService, disposables); instantiationService.stub(IEditorGroupsService, part); @@ -68,7 +68,7 @@ suite('EditorService', () => { } test('basics', async () => { - const [part, service] = createEditorService(); + const [, service] = await createEditorService(); let input = new TestFileEditorInput(URI.parse('my://resource-basics'), TEST_EDITOR_INPUT_ID); let otherInput = new TestFileEditorInput(URI.parse('my://resource2-basics'), TEST_EDITOR_INPUT_ID); @@ -88,8 +88,6 @@ suite('EditorService', () => { didCloseEditorListenerCounter++; }); - await part.whenRestored; - // Open input let editor = await service.openEditor(input, { pinned: true }); @@ -172,14 +170,12 @@ suite('EditorService', () => { }); test('isOpen() with side by side editor', async () => { - const [part, service] = createEditorService(); + const [part, service] = await createEditorService(); const input = new TestFileEditorInput(URI.parse('my://resource-openEditors'), TEST_EDITOR_INPUT_ID); const otherInput = new TestFileEditorInput(URI.parse('my://resource2-openEditors'), TEST_EDITOR_INPUT_ID); const sideBySideInput = new SideBySideEditorInput('sideBySide', '', input, otherInput); - await part.whenRestored; - const editor1 = await service.openEditor(sideBySideInput, { pinned: true }); assert.strictEqual(part.activeGroup.count, 1); @@ -217,14 +213,12 @@ suite('EditorService', () => { }); test('openEditors() / replaceEditors()', async () => { - const [part, service] = createEditorService(); + const [part, service] = await createEditorService(); const input = new TestFileEditorInput(URI.parse('my://resource-openEditors'), TEST_EDITOR_INPUT_ID); const otherInput = new TestFileEditorInput(URI.parse('my://resource2-openEditors'), TEST_EDITOR_INPUT_ID); const replaceInput = new TestFileEditorInput(URI.parse('my://resource3-openEditors'), TEST_EDITOR_INPUT_ID); - await part.whenRestored; - // Open editors await service.openEditors([{ editor: input }, { editor: otherInput }]); assert.strictEqual(part.activeGroup.count, 2); @@ -413,15 +407,13 @@ suite('EditorService', () => { }); test('close editor does not dispose when editor opened in other group', async () => { - const [part, service] = createEditorService(); + const [part, service] = await createEditorService(); const input = new TestFileEditorInput(URI.parse('my://resource-close1'), TEST_EDITOR_INPUT_ID); const rootGroup = part.activeGroup; const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT); - await part.whenRestored; - // Open input await service.openEditor(input, { pinned: true }); await service.openEditor(input, { pinned: true }, rightGroup); @@ -440,15 +432,13 @@ suite('EditorService', () => { }); test('open to the side', async () => { - const [part, service] = createEditorService(); + const [part, service] = await createEditorService(); const input1 = new TestFileEditorInput(URI.parse('my://resource1-openside'), TEST_EDITOR_INPUT_ID); const input2 = new TestFileEditorInput(URI.parse('my://resource2-openside'), TEST_EDITOR_INPUT_ID); const rootGroup = part.activeGroup; - await part.whenRestored; - await service.openEditor(input1, { pinned: true }, rootGroup); let editor = await service.openEditor(input1, { pinned: true, preserveFocus: true }, SIDE_GROUP); @@ -464,15 +454,13 @@ suite('EditorService', () => { }); test('editor group activation', async () => { - const [part, service] = createEditorService(); + const [part, service] = await createEditorService(); const input1 = new TestFileEditorInput(URI.parse('my://resource1-openside'), TEST_EDITOR_INPUT_ID); const input2 = new TestFileEditorInput(URI.parse('my://resource2-openside'), TEST_EDITOR_INPUT_ID); const rootGroup = part.activeGroup; - await part.whenRestored; - await service.openEditor(input1, { pinned: true }, rootGroup); let editor = await service.openEditor(input2, { pinned: true, preserveFocus: true, activation: EditorActivation.ACTIVATE }, SIDE_GROUP); const sideGroup = editor?.group; @@ -497,15 +485,13 @@ suite('EditorService', () => { }); test('inactive editor group does not activate when closing editor (#117686)', async () => { - const [part, service] = createEditorService(); + const [part, service] = await createEditorService(); const input1 = new TestFileEditorInput(URI.parse('my://resource1-openside'), TEST_EDITOR_INPUT_ID); const input2 = new TestFileEditorInput(URI.parse('my://resource2-openside'), TEST_EDITOR_INPUT_ID); const rootGroup = part.activeGroup; - await part.whenRestored; - await service.openEditor(input1, { pinned: true }, rootGroup); await service.openEditor(input2, { pinned: true }, rootGroup); @@ -523,7 +509,7 @@ suite('EditorService', () => { }); test('active editor change / visible editor change events', async function () { - const [part, service] = createEditorService(); + const [part, service] = await createEditorService(); let input = new TestFileEditorInput(URI.parse('my://resource-active'), TEST_EDITOR_INPUT_ID); let otherInput = new TestFileEditorInput(URI.parse('my://resource2-active'), TEST_EDITOR_INPUT_ID); @@ -553,8 +539,6 @@ suite('EditorService', () => { await timeout(0); // closing an editor will not immediately open the next one, so we need to wait } - await part.whenRestored; - // 1.) open, open same, open other, close let editor = await service.openEditor(input, { pinned: true }); const group = editor?.group!; @@ -741,7 +725,7 @@ suite('EditorService', () => { }); test('two active editor change events when opening editor to the side', async function () { - const [part, service] = createEditorService(); + const [, service] = await createEditorService(); let input = new TestFileEditorInput(URI.parse('my://resource-active'), TEST_EDITOR_INPUT_ID); @@ -755,8 +739,6 @@ suite('EditorService', () => { activeEditorChangeEvents = 0; } - await part.whenRestored; - await service.openEditor(input, { pinned: true }); assertActiveEditorChangedEvent(1); @@ -776,9 +758,7 @@ suite('EditorService', () => { }); test('activeTextEditorControl / activeTextEditorMode', async () => { - const [part, service] = createEditorService(); - - await part.whenRestored; + const [, service] = await createEditorService(); // Open untitled input let editor = await service.openEditor({}); @@ -789,15 +769,13 @@ suite('EditorService', () => { }); test('openEditor returns NULL when opening fails or is inactive', async function () { - const [part, service] = createEditorService(); + const [, service] = await createEditorService(); const input = new TestFileEditorInput(URI.parse('my://resource-active'), TEST_EDITOR_INPUT_ID); const otherInput = new TestFileEditorInput(URI.parse('my://resource2-inactive'), TEST_EDITOR_INPUT_ID); const failingInput = new TestFileEditorInput(URI.parse('my://resource3-failing'), TEST_EDITOR_INPUT_ID); failingInput.setFailToOpen(); - await part.whenRestored; - let editor = await service.openEditor(input, { pinned: true }); assert.ok(editor); @@ -809,7 +787,7 @@ suite('EditorService', () => { }); test('save, saveAll, revertAll', async function () { - const [part, service] = createEditorService(); + const [part, service] = await createEditorService(); const input1 = new TestFileEditorInput(URI.parse('my://resource1'), TEST_EDITOR_INPUT_ID); input1.dirty = true; @@ -820,8 +798,6 @@ suite('EditorService', () => { const rootGroup = part.activeGroup; - await part.whenRestored; - await service.openEditor(input1, { pinned: true }); await service.openEditor(input2, { pinned: true }); await service.openEditor(sameInput1, { pinned: true }, SIDE_GROUP); @@ -888,7 +864,7 @@ suite('EditorService', () => { }); test('saveAll, revertAll (sticky editor)', async function () { - const [part, service] = createEditorService(); + const [, service] = await createEditorService(); const input1 = new TestFileEditorInput(URI.parse('my://resource1'), TEST_EDITOR_INPUT_ID); input1.dirty = true; @@ -897,8 +873,6 @@ suite('EditorService', () => { const sameInput1 = new TestFileEditorInput(URI.parse('my://resource1'), TEST_EDITOR_INPUT_ID); sameInput1.dirty = true; - await part.whenRestored; - await service.openEditor(input1, { pinned: true, sticky: true }); await service.openEditor(input2, { pinned: true }); await service.openEditor(sameInput1, { pinned: true }, SIDE_GROUP); @@ -936,7 +910,7 @@ suite('EditorService', () => { }); async function testFileDeleteEditorClose(dirty: boolean): Promise { - const [part, service, accessor] = createEditorService(); + const [part, service, accessor] = await createEditorService(); const input1 = new TestFileEditorInput(URI.parse('my://resource1'), TEST_EDITOR_INPUT_ID); input1.dirty = dirty; @@ -945,8 +919,6 @@ suite('EditorService', () => { const rootGroup = part.activeGroup; - await part.whenRestored; - await service.openEditor(input1, { pinned: true }); await service.openEditor(input2, { pinned: true }); @@ -966,7 +938,7 @@ suite('EditorService', () => { } test('file move asks input to move', async function () { - const [part, service, accessor] = createEditorService(); + const [part, service, accessor] = await createEditorService(); const input1 = new TestFileEditorInput(URI.parse('my://resource1'), TEST_EDITOR_INPUT_ID); const movedInput = new TestFileEditorInput(URI.parse('my://resource2'), TEST_EDITOR_INPUT_ID); @@ -974,8 +946,6 @@ suite('EditorService', () => { const rootGroup = part.activeGroup; - await part.whenRestored; - await service.openEditor(input1, { pinned: true }); const activeEditorChangePromise = awaitActiveEditorChange(service); @@ -1000,13 +970,11 @@ suite('EditorService', () => { } test('file watcher gets installed for out of workspace files', async function () { - const [part, service, accessor] = createEditorService(); + const [, service, accessor] = await createEditorService(); const input1 = new TestFileEditorInput(URI.parse('file://resource1'), TEST_EDITOR_INPUT_ID); const input2 = new TestFileEditorInput(URI.parse('file://resource2'), TEST_EDITOR_INPUT_ID); - await part.whenRestored; - await service.openEditor(input1, { pinned: true }); assert.strictEqual(accessor.fileService.watches.length, 1); assert.strictEqual(accessor.fileService.watches[0].toString(), input1.resource.toString()); @@ -1021,13 +989,11 @@ suite('EditorService', () => { test('activeEditorPane scopedContextKeyService', async function () { const instantiationService = workbenchInstantiationService({ contextKeyService: instantiationService => instantiationService.createInstance(MockScopableContextKeyService) }); - const [part, service] = createEditorService(instantiationService); + const [part, service] = await createEditorService(instantiationService); const input1 = new TestFileEditorInput(URI.parse('file://resource1'), TEST_EDITOR_INPUT_ID); new TestFileEditorInput(URI.parse('file://resource2'), TEST_EDITOR_INPUT_ID); - await part.whenRestored; - await service.openEditor(input1, { pinned: true }); const editorContextKeyService = service.activeEditorPane?.scopedContextKeyService; @@ -1036,13 +1002,11 @@ suite('EditorService', () => { }); test('overrideOpenEditor', async function () { - const [part, service] = createEditorService(); + const [, service] = await createEditorService(); const input1 = new TestFileEditorInput(URI.parse('file://resource1'), TEST_EDITOR_INPUT_ID); const input2 = new TestFileEditorInput(URI.parse('file://resource2'), TEST_EDITOR_INPUT_ID); - await part.whenRestored; - let overrideCalled = false; const handler = service.overrideOpenEditor({ @@ -1066,13 +1030,11 @@ suite('EditorService', () => { }); test('whenClosed', async function () { - const [part, service] = createEditorService(); + const [, service] = await createEditorService(); const input1 = new TestFileEditorInput(URI.parse('file://resource1'), TEST_EDITOR_INPUT_ID); const input2 = new TestFileEditorInput(URI.parse('file://resource2'), TEST_EDITOR_INPUT_ID); - await part.whenRestored; - const editor = await service.openEditor(input1, { pinned: true }); await service.openEditor(input2, { pinned: true }); @@ -1084,13 +1046,11 @@ suite('EditorService', () => { }); test('findEditors', async () => { - const [part, service] = createEditorService(); + const [part, service] = await createEditorService(); const input = new TestFileEditorInput(URI.parse('my://resource-openEditors'), TEST_EDITOR_INPUT_ID); const otherInput = new TestFileEditorInput(URI.parse('my://resource2-openEditors'), TEST_EDITOR_INPUT_ID); - await part.whenRestored; - // Open editors await service.openEditors([{ editor: input }, { editor: otherInput }]); assert.strictEqual(part.activeGroup.count, 2); diff --git a/src/vs/workbench/services/editor/test/browser/editorsObserver.test.ts b/src/vs/workbench/services/editor/test/browser/editorsObserver.test.ts index 8516a4d4b81..bad27f08a1d 100644 --- a/src/vs/workbench/services/editor/test/browser/editorsObserver.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorsObserver.test.ts @@ -38,11 +38,9 @@ suite('EditorsObserver', function () { const instantiationService = workbenchInstantiationService(); instantiationService.invokeFunction(accessor => Registry.as(EditorExtensions.EditorInputFactories).start(accessor)); - const part = createEditorPart(instantiationService, disposables); + const part = await createEditorPart(instantiationService, disposables); disposables.add(toDisposable(() => part.clearState())); - await part.whenRestored; - return part; } @@ -225,7 +223,6 @@ suite('EditorsObserver', function () { assert.strictEqual(observer.hasEditor(input3.resource), true); const copiedGroup = part.copyGroup(rootGroup, rootGroup, GroupDirection.RIGHT); - await copiedGroup.whenRestored; copiedGroup.setActive(true); copiedGroup.focus(); diff --git a/src/vs/workbench/services/history/test/browser/history.test.ts b/src/vs/workbench/services/history/test/browser/history.test.ts index 3af981dbd48..8368e03f073 100644 --- a/src/vs/workbench/services/history/test/browser/history.test.ts +++ b/src/vs/workbench/services/history/test/browser/history.test.ts @@ -25,9 +25,7 @@ suite('HistoryService', function () { async function createServices(): Promise<[EditorPart, HistoryService, EditorService]> { const instantiationService = workbenchInstantiationService(); - const part = createEditorPart(instantiationService, disposables); - - await part.whenRestored; + const part = await createEditorPart(instantiationService, disposables); instantiationService.stub(IEditorGroupsService, part); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 6dd37cb46ae..ef982144177 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -1411,11 +1411,13 @@ export class TestEditorPart extends EditorPart { } } -export function createEditorPart(instantiationService: IInstantiationService, disposables: DisposableStore): TestEditorPart { +export async function createEditorPart(instantiationService: IInstantiationService, disposables: DisposableStore): Promise { const part = disposables.add(instantiationService.createInstance(TestEditorPart)); part.create(document.createElement('div')); part.layout(1080, 800); + await part.whenRestored; + return part; }