editors - do not wait for editor to resolve to signal restored phase (fix #119059)

This commit is contained in:
Benjamin Pasero 2021-03-29 11:12:54 +02:00
parent f554a74550
commit 44f89fc13c
No known key found for this signature in database
GPG key ID: C035C296C8A46619
15 changed files with 127 additions and 205 deletions

View file

@ -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.
*/

View file

@ -135,7 +135,6 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito
readonly onDidCloseEditor: Event<IEditorCloseEvent>;
readonly group: EditorGroup;
readonly whenRestored: Promise<void>;
readonly titleHeight: IEditorGroupTitleHeight;

View file

@ -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<void>;
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<void> {
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<void> {
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<IEditorPane | undefined> {
private doShowEditor(editor: EditorInput, context: { active: boolean, isNew: boolean }, options?: EditorOptions): Promise<IEditorPane | undefined> {
// Show in editor control if the active editor changed
let openEditorPromise: Promise<IEditorPane | undefined> | undefined;
let openEditorPromise: Promise<IEditorPane | undefined>;
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

View file

@ -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<GroupIdentifier, IEditorGroupView>();
private mostRecentActiveGroups: GroupIdentifier[] = [];
@ -132,10 +130,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
private centeredLayoutWidget!: CenteredViewLayout;
private gridWidget!: SerializableGrid<IEditorGroupView>;
private gridWidgetView: GridWidgetView<IEditorGroupView>;
private _whenRestored: Promise<void>;
private whenRestoredResolve: (() => void) | undefined;
private readonly gridWidgetView = this._register(new GridWidgetView<IEditorGroupView>());
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<IEditorGroupView>();
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<void>(resolve => (this.whenRestoredResolve = resolve));
get whenRestored(): Promise<void> {
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();
}

View file

@ -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));
}

View file

@ -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);

View file

@ -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() };

View file

@ -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 () => {

View file

@ -44,7 +44,7 @@ suite('EditorAutoSave', () => {
configurationService
));
const part = createEditorPart(instantiationService, disposables);
const part = await createEditorPart(instantiationService, disposables);
instantiationService.stub(IEditorGroupsService, part);

View file

@ -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((<TextFileEditorModelManager>accessor.textFileService.files));
await part.whenRestored;
disposables.add(instantiationService.createInstance(TextFileEditorTracker));
return accessor;

View file

@ -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);

View file

@ -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<void> {
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);

View file

@ -38,11 +38,9 @@ suite('EditorsObserver', function () {
const instantiationService = workbenchInstantiationService();
instantiationService.invokeFunction(accessor => Registry.as<IEditorInputFactoryRegistry>(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();

View file

@ -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);

View file

@ -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<TestEditorPart> {
const part = disposables.add(instantiationService.createInstance(TestEditorPart));
part.create(document.createElement('div'));
part.layout(1080, 800);
await part.whenRestored;
return part;
}