From ab77280f550c05b2c99d9853dc44ec9586c9d26c Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:49:27 -0500 Subject: [PATCH] try to clear transient editors on EditorViewStateManager restore (#206380) * try to clear transient editors on EditorViewStateManager restore * add onWillHide to quickpick * adopt onwillhide * Update src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts Co-authored-by: Benjamin Pasero * Update src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts Co-authored-by: Benjamin Pasero * refactoring for pr feedback * rename to PickerEditorState and ensure dispose will clean up * add openTransientEditor * Update src/vs/workbench/browser/quickaccess.ts Co-authored-by: Benjamin Pasero * Update src/vs/workbench/browser/quickaccess.ts Co-authored-by: Benjamin Pasero * use editorService.closeEditors * don't close current file * delete pickerEditorState onClose and check for dirty editors before closing * editors - do not turn non-transient already opened editors transient * let pinning clear transient * :lipstick: * :lipstick: * improve closing of editors --------- Co-authored-by: Benjamin Pasero --- src/vs/platform/editor/common/editor.ts | 3 + .../browser/parts/editor/editorGroupView.ts | 9 +-- src/vs/workbench/browser/quickaccess.ts | 69 ++++++++++++++----- .../common/editor/editorGroupModel.ts | 19 ++--- .../search/browser/anythingQuickAccess.ts | 17 +++-- .../quickTextSearch/textSearchQuickAccess.ts | 21 +++--- .../links/browser/terminalLinkQuickpick.ts | 18 ++--- .../editor/common/editorGroupsService.ts | 13 ---- .../test/browser/editorGroupsService.test.ts | 65 +++++++++-------- .../test/browser/quickAccess.test.ts | 60 +++++++++++++++- .../test/browser/workbenchTestServices.ts | 1 - 11 files changed, 187 insertions(+), 108 deletions(-) diff --git a/src/vs/platform/editor/common/editor.ts b/src/vs/platform/editor/common/editor.ts index 51060787d4a..159bea6fc8e 100644 --- a/src/vs/platform/editor/common/editor.ts +++ b/src/vs/platform/editor/common/editor.ts @@ -296,6 +296,9 @@ export interface IEditorOptions { * This option is meant to be used only when the editor is used for a short * period of time, for example when opening a preview of the editor from a * picker control in the background while navigating through results of the picker. + * + * Note: an editor that is already opened in a group that is not transient, will + * not turn transient. */ transient?: boolean; } diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 69bfb90f5d4..7baf78b613f 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -799,7 +799,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // that the transient state is not staying around when // the user interacts with the editor. - this.setTransient(this.activeEditor, false); + this.model.setTransient(this.activeEditor, false); } } @@ -1034,13 +1034,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } } - setTransient(candidate: EditorInput | undefined, transient: boolean): void { - const editor = candidate ?? this.activeEditor; - if (editor) { - this.model.setTransient(editor, transient); - } - } - //#endregion //#region openEditor() diff --git a/src/vs/workbench/browser/quickaccess.ts b/src/vs/workbench/browser/quickaccess.ts index 6b9e07abe7a..aec2065963d 100644 --- a/src/vs/workbench/browser/quickaccess.ts +++ b/src/vs/workbench/browser/quickaccess.ts @@ -8,12 +8,14 @@ import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/con import { ICommandHandler } from 'vs/platform/commands/common/commands'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { Disposable } from 'vs/base/common/lifecycle'; import { getIEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorViewState, IDiffEditorViewState } from 'vs/editor/common/editorCommon'; +import { IResourceEditorInput, ITextResourceEditorInput } from 'vs/platform/editor/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; -import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IEditorOptions } from 'vs/platform/editor/common/editor'; +import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { ACTIVE_GROUP_TYPE, AUX_WINDOW_GROUP_TYPE, IEditorService, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService'; +import { IUntitledTextResourceEditorInput, IUntypedEditorInput, GroupIdentifier, IEditorPane } from 'vs/workbench/common/editor'; export const inQuickPickContextKeyValue = 'inQuickOpen'; export const InQuickPickContextKey = new RawContextKey(inQuickPickContextKeyValue, false, localize('inQuickOpen', "Whether keyboard focus is inside the quick open control")); @@ -51,14 +53,21 @@ export function getQuickNavigateHandler(id: string, next?: boolean): ICommandHan quickInputService.navigate(!!next, quickNavigate); }; } -export class EditorViewState { +export class PickerEditorState extends Disposable { private _editorViewState: { editor: EditorInput; group: IEditorGroup; state: ICodeEditorViewState | IDiffEditorViewState | undefined; } | undefined = undefined; - constructor(private readonly editorService: IEditorService) { } + private readonly openedTransientEditors = new Set(); // editors that were opened between set and restore + + constructor( + @IEditorService private readonly editorService: IEditorService, + @IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService + ) { + super(); + } set(): void { if (this._editorViewState) { @@ -73,27 +82,55 @@ export class EditorViewState { state: getIEditor(activeEditorPane.getControl())?.saveViewState() ?? undefined, }; } + } - async restore(shouldCloseCurrEditor = false): Promise { + /** + * Open a transient editor such that it may be closed when the state is restored. + * Note that, when the state is restored, if the editor is no longer transient, it will not be closed. + */ + async openTransientEditor(editor: IResourceEditorInput | ITextResourceEditorInput | IUntitledTextResourceEditorInput | IUntypedEditorInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE | AUX_WINDOW_GROUP_TYPE): Promise { + editor.options = { ...editor.options, transient: true }; + + const editorPane = await this.editorService.openEditor(editor, group); + if (editorPane?.input && editorPane.input !== this._editorViewState?.editor && editorPane.group.isTransient(editorPane.input)) { + this.openedTransientEditors.add(editorPane.input); + } + + return editorPane; + } + + async restore(): Promise { if (this._editorViewState) { - const options: IEditorOptions = { - viewState: this._editorViewState.state, - preserveFocus: true /* import to not close the picker as a result */ - }; - if (shouldCloseCurrEditor) { - const activeEditorPane = this.editorService.activeEditorPane; - const currEditor = activeEditorPane?.input; - if (currEditor && currEditor !== this._editorViewState.editor && activeEditorPane?.group.isPinned(currEditor) !== true) { - await activeEditorPane.group.closeEditor(currEditor); + for (const editor of this.openedTransientEditors) { + if (editor.isDirty()) { + continue; + } + + for (const group of this.editorGroupsService.groups) { + if (group.isTransient(editor)) { + await group.closeEditor(editor, { preserveFocus: true }); + } } } - await this._editorViewState.group.openEditor(this._editorViewState.editor, options); + await this._editorViewState.group.openEditor(this._editorViewState.editor, { + viewState: this._editorViewState.state, + preserveFocus: true // important to not close the picker as a result + }); + + this.reset(); } } reset() { this._editorViewState = undefined; + this.openedTransientEditors.clear(); + } + + override dispose(): void { + super.dispose(); + + this.reset(); } } diff --git a/src/vs/workbench/common/editor/editorGroupModel.ts b/src/vs/workbench/common/editor/editorGroupModel.ts index 17c5ab59c26..60047f630e3 100644 --- a/src/vs/workbench/common/editor/editorGroupModel.ts +++ b/src/vs/workbench/common/editor/editorGroupModel.ts @@ -369,6 +369,11 @@ export class EditorGroupModel extends Disposable implements IEditorGroupModel { this.splice(targetIndex, false, newEditor); } + // Handle transient + if (makeTransient) { + this.doSetTransient(newEditor, targetIndex, true); + } + // Handle preview if (!makePinned) { @@ -385,11 +390,6 @@ export class EditorGroupModel extends Disposable implements IEditorGroupModel { this.preview = newEditor; } - // Handle transient - if (makeTransient) { - this.doSetTransient(newEditor, targetIndex, true); - } - // Listeners this.registerEditorListeners(newEditor); @@ -416,14 +416,14 @@ export class EditorGroupModel extends Disposable implements IEditorGroupModel { else { const [existingEditor, existingEditorIndex] = existingEditorAndIndex; + // Update transient (existing editors do not turn transient if they were not before) + this.doSetTransient(existingEditor, existingEditorIndex, makeTransient === false ? false : this.isTransient(existingEditor)); + // Pin it if (makePinned) { this.doPin(existingEditor, existingEditorIndex); } - // Update transient - this.doSetTransient(existingEditor, existingEditorIndex, makeTransient); - // Activate it if (makeActive) { this.doSetActive(existingEditor, existingEditorIndex); @@ -726,6 +726,9 @@ export class EditorGroupModel extends Disposable implements IEditorGroupModel { return; // can only pin a preview editor } + // Clear Transient + this.setTransient(editor, false); + // Convert the preview editor to be a pinned editor this.preview = null; diff --git a/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts b/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts index a85e27af833..12523447b89 100644 --- a/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts @@ -41,7 +41,7 @@ import { IFilesConfigurationService } from 'vs/workbench/services/filesConfigura import { ResourceMap } from 'vs/base/common/map'; import { SymbolsQuickAccessProvider } from 'vs/workbench/contrib/search/browser/symbolsQuickAccess'; import { AnythingQuickAccessProviderRunOptions, DefaultQuickAccessFilterValue, Extensions, IQuickAccessRegistry } from 'vs/platform/quickinput/common/quickAccess'; -import { EditorViewState, IWorkbenchQuickAccessConfiguration } from 'vs/workbench/browser/quickaccess'; +import { PickerEditorState, IWorkbenchQuickAccessConfiguration } from 'vs/workbench/browser/quickaccess'; import { GotoSymbolQuickAccessProvider } from 'vs/workbench/contrib/codeEditor/browser/quickaccess/gotoSymbolQuickAccess'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { ScrollType, IEditor } from 'vs/editor/common/editorCommon'; @@ -83,11 +83,11 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider | undefined = undefined; - editorViewState: EditorViewState; + editorViewState = this._register(this.instantiationService.createInstance(PickerEditorState)); scorerCache: FuzzyScorerCache = Object.create(null); fileQueryCache: FileQueryCacheState | undefined = undefined; @@ -100,8 +100,11 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider): void { @@ -129,7 +132,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider { - await this._editorService.openEditor({ + await this.editorViewState.openTransientEditor({ resource: itemMatch.parent().resource, - options: { transient: true, preserveFocus: true, revealIfOpened: true, ignoreError: true, selection: itemMatch.range() } + options: { preserveFocus: true, revealIfOpened: true, ignoreError: true, selection: itemMatch.range() } }); }); } })); - - disposables.add(Event.once(picker.onDidHide)(({ reason }) => { + disposables.add(Event.once(picker.onWillHide)(({ reason }) => { // Restore view state upon cancellation if we changed it // but only when the picker was closed via explicit user // gesture and not e.g. when focus was lost because that // could mean the user clicked into the editor directly. if (reason === QuickInputHideReason.Gesture) { - this.editorViewState.restore(true); + this.editorViewState.restore(); } + })); + + disposables.add(Event.once(picker.onDidHide)(({ reason }) => { this.searchModel.searchResult.toggleHighlights(false); })); diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts index c35df5218e3..423aa2430b2 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts @@ -15,17 +15,17 @@ import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/brows import { AccessibleViewProviderId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; import type { TerminalLink } from 'vs/workbench/contrib/terminalContrib/links/browser/terminalLink'; import { Sequencer, timeout } from 'vs/base/common/async'; -import { EditorViewState } from 'vs/workbench/browser/quickaccess'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { PickerEditorState } from 'vs/workbench/browser/quickaccess'; import { getLinkSuffix } from 'vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing'; import { TerminalBuiltinLinkType } from 'vs/workbench/contrib/terminalContrib/links/browser/links'; import { ILabelService } from 'vs/platform/label/common/label'; import { basenameOrAuthority, dirname } from 'vs/base/common/resources'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export class TerminalLinkQuickpick extends DisposableStore { private readonly _editorSequencer = new Sequencer(); - private readonly _editorViewState: EditorViewState; + private readonly _editorViewState: PickerEditorState; private _instance: ITerminalInstance | IDetachedTerminalInstance | undefined; @@ -33,13 +33,13 @@ export class TerminalLinkQuickpick extends DisposableStore { readonly onDidRequestMoreLinks = this._onDidRequestMoreLinks.event; constructor( - @IEditorService private readonly _editorService: IEditorService, @ILabelService private readonly _labelService: ILabelService, @IQuickInputService private readonly _quickInputService: IQuickInputService, - @IAccessibleViewService private readonly _accessibleViewService: IAccessibleViewService + @IAccessibleViewService private readonly _accessibleViewService: IAccessibleViewService, + @IInstantiationService instantiationService: IInstantiationService ) { super(); - this._editorViewState = new EditorViewState(_editorService); + this._editorViewState = this.add(instantiationService.createInstance(PickerEditorState)); } async show(instance: ITerminalInstance | IDetachedTerminalInstance, links: { viewport: IDetectedLinks; all: Promise }): Promise { @@ -145,7 +145,7 @@ export class TerminalLinkQuickpick extends DisposableStore { // gesture and not e.g. when focus was lost because that // could mean the user clicked into the editor directly. if (reason === QuickInputHideReason.Gesture) { - this._editorViewState.restore(true); + this._editorViewState.restore(); } disposables.dispose(); if (pick.selectedItems.length === 0) { @@ -266,9 +266,9 @@ export class TerminalLinkQuickpick extends DisposableStore { this._editorViewState.set(); this._editorSequencer.queue(async () => { - await this._editorService.openEditor({ + await this._editorViewState.openTransientEditor({ resource: link.uri, - options: { transient: true, preserveFocus: true, revealIfOpened: true, ignoreError: true, selection, } + options: { preserveFocus: true, revealIfOpened: true, ignoreError: true, selection, } }); }); } diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index fd2f81f70e9..7db5884efe3 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -837,19 +837,6 @@ export interface IEditorGroup { */ unstickEditor(editor?: EditorInput): void; - /** - * A transient editor will attempt to appear as preview and certain components - * (such as history tracking) may decide to ignore the editor when it becomes - * active. - * This option is meant to be used only when the editor is used for a short - * period of time, for example when opening a preview of the editor from a - * picker control in the background while navigating through results of the picker. - * - * @param editor the editor to update transient state, or the currently active editor - * if unspecified. - */ - setTransient(editor: EditorInput | undefined, transient: boolean): void; - /** * Whether this editor group should be locked or not. * 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 f1e25f4a355..56317e9b39d 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -477,7 +477,6 @@ suite('EditorGroupsService', () => { const editorCloseEvents: IGroupModelChangeEvent[] = []; let editorPinCounter = 0; let editorStickyCounter = 0; - let editorTransientCounter = 0; let editorCapabilitiesCounter = 0; const editorGroupModelChangeListener = group.onDidModelChange(e => { if (e.kind === GroupModelChangeKind.EDITOR_OPEN) { @@ -490,9 +489,6 @@ suite('EditorGroupsService', () => { } else if (e.kind === GroupModelChangeKind.EDITOR_STICKY) { assert.ok(e.editor); editorStickyCounter++; - } else if (e.kind === GroupModelChangeKind.EDITOR_TRANSIENT) { - assert.ok(e.editor); - editorTransientCounter++; } else if (e.kind === GroupModelChangeKind.EDITOR_CAPABILITIES) { assert.ok(e.editor); editorCapabilitiesCounter++; @@ -597,15 +593,6 @@ suite('EditorGroupsService', () => { group.unstickEditor(input); assert.strictEqual(editorStickyCounter, 2); - assert.strictEqual(group.isTransient(input), false); - assert.strictEqual(editorTransientCounter, 0); - group.setTransient(input, true); - assert.strictEqual(group.isTransient(input), true); - assert.strictEqual(editorTransientCounter, 1); - group.setTransient(input, false); - assert.strictEqual(group.isTransient(input), false); - assert.strictEqual(editorTransientCounter, 2); - editorCloseListener.dispose(); editorWillCloseListener.dispose(); editorDidCloseListener.dispose(); @@ -1835,30 +1822,42 @@ suite('EditorGroupsService', () => { const group = part.activeGroup; const input = createTestFileEditorInput(URI.file('foo/bar'), TEST_EDITOR_INPUT_ID); - const inputInactive = createTestFileEditorInput(URI.file('foo/bar/inactive'), TEST_EDITOR_INPUT_ID); + const inputTransient = createTestFileEditorInput(URI.file('foo/bar/inactive'), TEST_EDITOR_INPUT_ID); await group.openEditor(input, { pinned: true }); - await group.openEditor(inputInactive, { inactive: true }); - - assert.strictEqual(group.isTransient(input), false); - assert.strictEqual(group.isTransient(inputInactive), false); - - group.setTransient(input, true); - - assert.strictEqual(group.isTransient(input), true); - assert.strictEqual(group.isTransient(inputInactive), false); - - group.setTransient(input, false); - - assert.strictEqual(group.isTransient(input), false); - assert.strictEqual(group.isTransient(inputInactive), false); - - const inputTransient = createTestFileEditorInput(URI.file('foo/bar/transient'), TEST_EDITOR_INPUT_ID); - await group.openEditor(inputTransient, { transient: true }); + + assert.strictEqual(group.isTransient(input), false); assert.strictEqual(group.isTransient(inputTransient), true); - await group.openEditor(inputTransient, {}); + await group.openEditor(input, { pinned: true }); + await group.openEditor(inputTransient, { transient: true }); + + assert.strictEqual(group.isTransient(inputTransient), true); + + await group.openEditor(inputTransient, { transient: false }); + assert.strictEqual(group.isTransient(inputTransient), false); + + await group.openEditor(inputTransient, { transient: true }); + assert.strictEqual(group.isTransient(inputTransient), false); // cannot make a non-transient editor transient when already opened + }); + + test('transient editors - pinning clears transient', async () => { + const [part] = await createPart(); + const group = part.activeGroup; + + const input = createTestFileEditorInput(URI.file('foo/bar'), TEST_EDITOR_INPUT_ID); + const inputTransient = createTestFileEditorInput(URI.file('foo/bar/inactive'), TEST_EDITOR_INPUT_ID); + + await group.openEditor(input, { pinned: true }); + await group.openEditor(inputTransient, { transient: true }); + + assert.strictEqual(group.isTransient(input), false); + assert.strictEqual(group.isTransient(inputTransient), true); + + await group.openEditor(input, { pinned: true }); + await group.openEditor(inputTransient, { pinned: true, transient: true }); + assert.strictEqual(group.isTransient(inputTransient), false); }); @@ -1882,7 +1881,7 @@ suite('EditorGroupsService', () => { await group.openEditor(input2, { transient: true }); assert.strictEqual(group.isPinned(input2), false); - group.setTransient(input2, false); + group.focus(); assert.strictEqual(group.isPinned(input2), true); }); diff --git a/src/vs/workbench/test/browser/quickAccess.test.ts b/src/vs/workbench/test/browser/quickAccess.test.ts index 3130a990ac5..9d71c84ccf3 100644 --- a/src/vs/workbench/test/browser/quickAccess.test.ts +++ b/src/vs/workbench/test/browser/quickAccess.test.ts @@ -8,16 +8,23 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IQuickAccessRegistry, Extensions, IQuickAccessProvider, QuickAccessRegistry } from 'vs/platform/quickinput/common/quickAccess'; import { IQuickPick, IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestServiceAccessor, workbenchInstantiationService, createEditorPart } from 'vs/workbench/test/browser/workbenchTestServices'; import { DisposableStore, toDisposable, IDisposable } from 'vs/base/common/lifecycle'; import { timeout } from 'vs/base/common/async'; import { PickerQuickAccessProvider, FastAndSlowPicks } from 'vs/platform/quickinput/browser/pickerQuickAccess'; +import { URI } from 'vs/base/common/uri'; +import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { EditorService } from 'vs/workbench/services/editor/browser/editorService'; +import { PickerEditorState } from 'vs/workbench/browser/quickaccess'; +import { EditorsOrder } from 'vs/workbench/common/editor'; +import { Range } from 'vs/editor/common/core/range'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; suite('QuickAccess', () => { let disposables: DisposableStore; - let instantiationService: IInstantiationService; + let instantiationService: TestInstantiationService; let accessor: TestServiceAccessor; let providerDefaultCalled = false; @@ -334,4 +341,51 @@ suite('QuickAccess', () => { restore(); }); + + test('PickerEditorState can properly restore editors', async () => { + + const part = await createEditorPart(instantiationService, disposables); + instantiationService.stub(IEditorGroupsService, part); + + const editorService = disposables.add(instantiationService.createInstance(EditorService, undefined)); + instantiationService.stub(IEditorService, editorService); + + const editorViewState = disposables.add(instantiationService.createInstance(PickerEditorState)); + disposables.add(part); + disposables.add(editorService); + + const input1 = { + resource: URI.parse('foo://bar1'), + options: { + pinned: true, preserveFocus: true, selection: new Range(1, 0, 1, 3) + } + }; + const input2 = { + resource: URI.parse('foo://bar2'), + options: { + pinned: true, selection: new Range(1, 0, 1, 3) + } + }; + const input3 = { + resource: URI.parse('foo://bar3') + }; + const input4 = { + resource: URI.parse('foo://bar4') + }; + + const editor = await editorService.openEditor(input1); + assert.strictEqual(editor, editorService.activeEditorPane); + editorViewState.set(); + await editorService.openEditor(input2); + await editorViewState.openTransientEditor(input3); + await editorViewState.openTransientEditor(input4); + await editorViewState.restore(); + + assert.strictEqual(part.activeGroup.activeEditor?.resource, input1.resource); + assert.deepStrictEqual(part.activeGroup.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE).map(e => e.resource), [input1.resource, input2.resource]); + if (part.activeGroup.activeEditorPane?.getSelection) { + assert.deepStrictEqual(part.activeGroup.activeEditorPane?.getSelection(), input1.options.selection); + } + await part.activeGroup.closeAllEditors(); + }); }); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index 6fcf99d03f3..c37caab7092 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -918,7 +918,6 @@ export class TestEditorGroupView implements IEditorGroupView { pinEditor(_editor?: EditorInput): void { } stickEditor(editor?: EditorInput | undefined): void { } unstickEditor(editor?: EditorInput | undefined): void { } - setTransient(editor: EditorInput | undefined, transient: boolean): void { } lock(locked: boolean): void { } focus(): void { } get scopedContextKeyService(): IContextKeyService { throw new Error('not implemented'); }