提交 bc8547c4 编写于 作者: B Benjamin Pasero

reimplement "Reopen Closed Editor" with stacks

上级 fe6e2251
......@@ -393,7 +393,7 @@ export class VSCodeMenu {
}
private setOpenRecentMenu(openRecentMenu: Electron.Menu): void {
openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedFile', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed File"), 'workbench.files.action.reopenClosedFile'));
openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedEditor', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed Editor"), 'workbench.action.reopenClosedEditor'));
let recentList = this.getOpenedPathsList();
......
......@@ -34,7 +34,7 @@ import {KeyMod, KeyCode} from 'vs/base/common/keyCodes';
import {EditorStacksModel} from 'vs/workbench/common/editor/editorStacksModel';
import {CloseEditorsInGroupAction, CloseEditorsInOtherGroupsAction, CloseAllEditorsAction, MoveGroupLeftAction, MoveGroupRightAction, SplitEditorAction, PinEditorAction, UnpinEditorAction, CloseOtherEditorsInGroupAction, OpenToSideAction,
NavigateBetweenGroupsAction, FocusFirstGroupAction, FocusSecondGroupAction, FocusThirdGroupAction, EvenGroupWidthsAction, MaximizeGroupAction, MinimizeOtherGroupsAction, FocusPreviousGroup, FocusNextGroup,
toEditorQuickOpenEntry, CloseLeftEditorsInGroupAction, CloseRightEditorsInGroupAction, OpenNextEditor, OpenPreviousEditor, NavigateBackwardsAction, NavigateForwardAction
toEditorQuickOpenEntry, CloseLeftEditorsInGroupAction, CloseRightEditorsInGroupAction, OpenNextEditor, OpenPreviousEditor, NavigateBackwardsAction, NavigateForwardAction, ReopenClosedEditorAction
} from 'vs/workbench/browser/parts/editor/editorActions';
// Register String Editor
......@@ -256,6 +256,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(OpenPreviousEditor, Op
primary: KeyMod.CtrlCmd | KeyCode.PageUp,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.LeftArrow }
}), 'View: Open Previous Editor', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(ReopenClosedEditorAction, ReopenClosedEditorAction.ID, ReopenClosedEditorAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_T }), 'View: Reopen Closed Editor', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(PinEditorAction, PinEditorAction.ID, PinEditorAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.Enter) }), 'View: Pin Editor', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(UnpinEditorAction, UnpinEditorAction.ID, UnpinEditorAction.LABEL), 'View: Unpin Editor', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseAllEditorsAction, CloseAllEditorsAction.ID, CloseAllEditorsAction.LABEL), 'View: Close All Editors', category);
......
......@@ -9,7 +9,7 @@ import nls = require('vs/nls');
import types = require('vs/base/common/types');
import {Action} from 'vs/base/common/actions';
import {BaseEditor} from 'vs/workbench/browser/parts/editor/baseEditor';
import {EditorInput, getUntitledOrFileResource, TextEditorOptions} from 'vs/workbench/common/editor';
import {EditorInput, getUntitledOrFileResource, TextEditorOptions, EditorOptions} from 'vs/workbench/common/editor';
import {QuickOpenEntryGroup} from 'vs/base/parts/quickopen/browser/quickOpenModel';
import {EditorQuickOpenEntry, EditorQuickOpenEntryGroup, IEditorQuickOpenEntry} from 'vs/workbench/browser/quickopen';
import {IWorkbenchEditorService, GroupArrangement} from 'vs/workbench/services/editor/common/editorService';
......@@ -808,3 +808,34 @@ export class NavigateBackwardsAction extends Action {
return TPromise.as(null);
}
}
export class ReopenClosedEditorAction extends Action {
public static ID = 'workbench.action.reopenClosedEditor';
public static LABEL = nls.localize('reopenClosedEditor', "Reopen Closed Editor");
constructor(
id: string,
label: string,
@IPartService private partService: IPartService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService
) {
super(id, label);
}
public run(): TPromise<any> {
const stacks = this.editorService.getStacksModel();
// Find an editor that was closed and is currently not opened in the group
let lastClosedEditor = stacks.popLastClosedEditor();
while (lastClosedEditor && stacks.activeGroup && stacks.activeGroup.indexOf(lastClosedEditor) >= 0) {
lastClosedEditor = stacks.popLastClosedEditor();
}
if (lastClosedEditor) {
this.editorService.openEditor(lastClosedEditor, EditorOptions.create({ pinned: true }));
}
return TPromise.as(false);
}
}
\ No newline at end of file
......@@ -26,7 +26,7 @@ export interface IEditorGroup {
onEditorActivated: Event<EditorInput>;
onEditorOpened: Event<EditorInput>;
onEditorClosed: Event<EditorInput>;
onEditorClosed: Event<IGroupEvent>;
onEditorMoved: Event<EditorInput>;
onEditorPinned: Event<EditorInput>;
onEditorUnpinned: Event<EditorInput>;
......@@ -41,6 +41,11 @@ export interface IEditorGroup {
isPinned(editor: EditorInput): boolean;
}
export interface IGroupEvent {
editor: EditorInput;
pinned: boolean;
}
export interface IEditorStacksModel {
onGroupOpened: Event<IEditorGroup>;
......@@ -60,6 +65,8 @@ export interface IEditorStacksModel {
next(): IEditorIdentifier;
previous(): IEditorIdentifier;
popLastClosedEditor(): EditorInput;
toString(): string;
}
......@@ -110,7 +117,7 @@ export class EditorGroup implements IEditorGroup {
private _onEditorActivated: Emitter<EditorInput>;
private _onEditorOpened: Emitter<EditorInput>;
private _onEditorClosed: Emitter<EditorInput>;
private _onEditorClosed: Emitter<IGroupEvent>;
private _onEditorMoved: Emitter<EditorInput>;
private _onEditorPinned: Emitter<EditorInput>;
private _onEditorUnpinned: Emitter<EditorInput>;
......@@ -134,7 +141,7 @@ export class EditorGroup implements IEditorGroup {
this._onEditorActivated = new Emitter<EditorInput>();
this._onEditorOpened = new Emitter<EditorInput>();
this._onEditorClosed = new Emitter<EditorInput>();
this._onEditorClosed = new Emitter<IGroupEvent>();
this._onEditorMoved = new Emitter<EditorInput>();
this._onEditorPinned = new Emitter<EditorInput>();
this._onEditorUnpinned = new Emitter<EditorInput>();
......@@ -167,7 +174,7 @@ export class EditorGroup implements IEditorGroup {
return this._onEditorOpened.event;
}
public get onEditorClosed(): Event<EditorInput> {
public get onEditorClosed(): Event<IGroupEvent> {
return this._onEditorClosed.event;
}
......@@ -313,8 +320,10 @@ export class EditorGroup implements IEditorGroup {
}
// Preview Editor closed
let pinned = true;
if (this.matches(this.preview, editor)) {
this.preview = null;
pinned = false;
}
// Close it
......@@ -324,7 +333,7 @@ export class EditorGroup implements IEditorGroup {
this.splice(index, true);
// Event
this.fireEvent(this._onEditorClosed, editor);
this.fireEvent(this._onEditorClosed, { editor, pinned });
}
public closeEditors(except: EditorInput, direction?: Direction): void {
......@@ -434,9 +443,9 @@ export class EditorGroup implements IEditorGroup {
return !this.matches(this.preview, editor);
}
private fireEvent(emitter: Emitter<EditorInput>, editor: EditorInput): void {
emitter.fire(editor);
this._onEditorChanged.fire(editor);
private fireEvent(emitter: Emitter<EditorInput | IGroupEvent>, arg2: EditorInput | IGroupEvent): void {
emitter.fire(arg2);
this._onEditorChanged.fire(arg2 instanceof EditorInput ? arg2 : arg2.editor);
}
private splice(index: number, del: boolean, editor?: EditorInput): void {
......@@ -505,7 +514,7 @@ export class EditorGroup implements IEditorGroup {
}
public serialize(): ISerializedEditorGroup {
let registry = (<IEditorRegistry>Registry.as(Extensions.Editors));
const registry = Registry.as<IEditorRegistry>(Extensions.Editors);
// Serialize all editor inputs so that we can store them.
// Editors that cannot be serialized need to be ignored
......@@ -539,7 +548,7 @@ export class EditorGroup implements IEditorGroup {
}
private deserialize(data: ISerializedEditorGroup): void {
let registry = (<IEditorRegistry>Registry.as(Extensions.Editors));
const registry = Registry.as<IEditorRegistry>(Extensions.Editors);
this._label = data.label;
this.editors = data.editors.map(e => registry.getEditorInputFactory(e.id).deserialize(this.instantiationService, e.value));
......@@ -556,6 +565,7 @@ export class EditorGroup implements IEditorGroup {
interface ISerializedEditorStacksModel {
groups: ISerializedEditorGroup[];
active: number;
lastClosed: ISerializedEditorInput[];
}
export class EditorStacksModel implements IEditorStacksModel {
......@@ -569,6 +579,8 @@ export class EditorStacksModel implements IEditorStacksModel {
private _activeGroup: EditorGroup;
private groupToIdentifier: { [id: number]: EditorGroup };
private recentlyClosedEditors: ISerializedEditorInput[];
private _onGroupOpened: Emitter<EditorGroup>;
private _onGroupClosed: Emitter<EditorGroup>;
private _onGroupMoved: Emitter<EditorGroup>;
......@@ -587,6 +599,8 @@ export class EditorStacksModel implements IEditorStacksModel {
this._groups = [];
this.groupToIdentifier = Object.create(null);
this.recentlyClosedEditors = [];
this._onGroupOpened = new Emitter<EditorGroup>();
this._onGroupClosed = new Emitter<EditorGroup>();
this._onGroupActivated = new Emitter<EditorGroup>();
......@@ -851,7 +865,8 @@ export class EditorStacksModel implements IEditorStacksModel {
return {
groups: serializableGroups,
active: serializableActiveIndex
active: serializableActiveIndex,
lastClosed: this.recentlyClosedEditors
};
}
......@@ -888,6 +903,7 @@ export class EditorStacksModel implements IEditorStacksModel {
this._groups = serialized.groups.map(s => this.doCreateGroup(s));
this._activeGroup = this._groups[serialized.active];
this._groups.forEach(g => this.groupToIdentifier[g.id] = g);
this.recentlyClosedEditors = serialized.lastClosed || [];
}
}
......@@ -928,15 +944,45 @@ export class EditorStacksModel implements IEditorStacksModel {
// Funnel editor changes in the group through our event aggregator
const l1 = group.onEditorChanged(e => this._onModelChanged.fire(group));
const l2 = this.onGroupClosed(g => {
const l2 = group.onEditorClosed(e => this.onEditorClosed(e));
const l3 = this.onGroupClosed(g => {
if (g === group) {
dispose(l1, l2);
dispose(l1, l2, l3);
}
});
return group;
}
public popLastClosedEditor(): EditorInput {
const registry = Registry.as<IEditorRegistry>(Extensions.Editors);
let serializedEditor = this.recentlyClosedEditors.pop();
if (serializedEditor) {
return registry.getEditorInputFactory(serializedEditor.id).deserialize(this.instantiationService, serializedEditor.value);
}
return null;
}
private onEditorClosed(event: IGroupEvent): void {
if (!event.pinned) {
return; // we only care about pinned editors
}
const editor = event.editor;
const registry = Registry.as<IEditorRegistry>(Extensions.Editors);
let factory = registry.getEditorInputFactory(editor.getId());
if (factory) {
let value = factory.serialize(editor);
if (typeof value === 'string') {
this.recentlyClosedEditors.push({ id: editor.getId(), value });
this.recentlyClosedEditors = this.recentlyClosedEditors.slice(0, 10); // upper bound of recently closed
}
}
}
private onShutdown(): void {
this.save();
......
......@@ -10,7 +10,7 @@ import {Action, IAction} from 'vs/base/common/actions';
import {ActionItem, BaseActionItem, Separator} from 'vs/base/browser/ui/actionbar/actionbar';
import {Scope, IActionBarRegistry, Extensions as ActionBarExtensions, ActionBarContributor} from 'vs/workbench/browser/actionBarRegistry';
import {IEditorInputActionContext, IEditorInputAction, EditorInputActionContributor} from 'vs/workbench/browser/parts/editor/baseEditor';
import {FocusOpenEditorsView, FocusFilesExplorer, OpenPreviousWorkingFile, OpenNextWorkingFile, CloseAllFilesAction, CloseFileAction, CloseOtherFilesAction, GlobalCompareResourcesAction, GlobalNewFileAction, GlobalNewFolderAction, RevertFileAction, SaveFilesAction, SaveAllAction, SaveFileAction, keybindingForAction, MoveFileToTrashAction, TriggerRenameFileAction, PasteFileAction, CopyFileAction, SelectResourceForCompareAction, CompareResourcesAction, NewFolderAction, NewFileAction, ReopenClosedFileAction, OpenToSideAction, ShowActiveFileInExplorer} from 'vs/workbench/parts/files/browser/fileActions';
import {FocusOpenEditorsView, FocusFilesExplorer, OpenPreviousWorkingFile, OpenNextWorkingFile, CloseAllFilesAction, CloseFileAction, CloseOtherFilesAction, GlobalCompareResourcesAction, GlobalNewFileAction, GlobalNewFolderAction, RevertFileAction, SaveFilesAction, SaveAllAction, SaveFileAction, keybindingForAction, MoveFileToTrashAction, TriggerRenameFileAction, PasteFileAction, CopyFileAction, SelectResourceForCompareAction, CompareResourcesAction, NewFolderAction, NewFileAction, OpenToSideAction, ShowActiveFileInExplorer} from 'vs/workbench/parts/files/browser/fileActions';
import {RevertLocalChangesAction, AcceptLocalChangesAction, ConflictResolutionDiffEditorInput} from 'vs/workbench/parts/files/browser/saveErrorHandler';
import {SyncActionDescriptor} from 'vs/platform/actions/common/actions';
import {IWorkbenchActionRegistry, Extensions as ActionExtensions} from 'vs/workbench/common/actionRegistry';
......@@ -172,7 +172,6 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalCompareResources
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseFileAction, CloseFileAction.ID, CloseFileAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_W) }), 'Files: Close File', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseOtherFilesAction, CloseOtherFilesAction.ID, CloseOtherFilesAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_W) }), 'Files: Close Other Files', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(CloseAllFilesAction, CloseAllFilesAction.ID, CloseAllFilesAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_W) }), 'Files: Close All Files', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(ReopenClosedFileAction, ReopenClosedFileAction.ID, ReopenClosedFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_T }), 'Reopen Closed File', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenNextWorkingFile, OpenNextWorkingFile.ID, OpenNextWorkingFile.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.DownArrow) }), 'Files: Open Next Working File', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenPreviousWorkingFile, OpenPreviousWorkingFile.ID, OpenPreviousWorkingFile.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.UpArrow) }), 'Files: Open Previous Working File', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(FocusOpenEditorsView, FocusOpenEditorsView.ID, FocusOpenEditorsView.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_E) }), 'Files: Focus on Working Files', category);
......
......@@ -25,7 +25,7 @@ import {MessageType, IInputValidator} from 'vs/base/browser/ui/inputbox/inputBox
import {ITree, IHighlightEvent} from 'vs/base/parts/tree/browser/tree';
import {dispose, IDisposable} from 'vs/base/common/lifecycle';
import {EventType as WorkbenchEventType, EditorEvent} from 'vs/workbench/common/events';
import {LocalFileChangeEvent, VIEWLET_ID, ITextFileService, TextFileChangeEvent, ITextFileOperationResult, IWorkingFileModelChangeEvent, IWorkingFileEntry, IWorkingFilesModel, EventType as FileEventType} from 'vs/workbench/parts/files/common/files';
import {LocalFileChangeEvent, VIEWLET_ID, ITextFileService, TextFileChangeEvent, ITextFileOperationResult, IWorkingFileModelChangeEvent, EventType as FileEventType} from 'vs/workbench/parts/files/common/files';
import {IFileService, IFileStat, IImportResult} from 'vs/platform/files/common/files';
import {DiffEditorInput, toDiffLabel} from 'vs/workbench/common/editor/diffEditorInput';
import {asFileEditorInput, getUntitledOrFileResource, TextEditorOptions, EditorOptions, UntitledEditorInput, ConfirmResult} from 'vs/workbench/common/editor';
......@@ -41,7 +41,6 @@ import {IUntitledEditorService} from 'vs/workbench/services/untitled/common/unti
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
import {IQuickOpenService} from 'vs/workbench/services/quickopen/common/quickOpenService';
import {IViewletService} from 'vs/workbench/services/viewlet/common/viewletService';
import {IPartService} from 'vs/workbench/services/part/common/partService';
import {IStorageService} from 'vs/platform/storage/common/storage';
import {Position, IEditor} from 'vs/platform/editor/common/editor';
import {IEventService} from 'vs/platform/event/common/event';
......@@ -1741,51 +1740,6 @@ export class RevertFileAction extends Action {
}
}
export class ReopenClosedFileAction extends Action {
public static ID = 'workbench.files.action.reopenClosedFile';
public static LABEL = nls.localize('reopenClosedFile', "Reopen Closed File");
constructor(
id: string,
label: string,
@IPartService private partService: IPartService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IViewletService private viewletService: IViewletService,
@ITextFileService private textFileService: ITextFileService,
@IFileService private fileService: IFileService
) {
super(id, label);
}
public run(): TPromise<any> {
let workingFilesModel: IWorkingFilesModel = this.textFileService.getWorkingFilesModel();
let entry: IWorkingFileEntry = workingFilesModel.popLastClosedEntry();
if (entry === null) {
return TPromise.as(true);
}
// If the current resource is the recently closed resource, run action again
let activeResource = getUntitledOrFileResource(this.editorService.getActiveEditorInput());
if (activeResource && activeResource.path === entry.resource.path) {
return this.run();
}
return this.fileService.existsFile(entry.resource).then((exists) => {
if (!exists) {
return this.run(); // repeat in case the last closed file got deleted meanwhile
}
// Make it a working file again
workingFilesModel.addEntry(entry.resource);
// Open in editor
return this.editorService.openEditor(entry);
});
}
}
export abstract class BaseCloseWorkingFileAction extends Action {
protected model: WorkingFilesModel;
private elements: URI[];
......
......@@ -123,7 +123,6 @@ let descriptor = new AsyncDescriptor<IFileEditorInput>('vs/workbench/parts/files
interface ISerializedFileInput {
resource: string;
mime: string;
}
// Register Editor Input Factory
......@@ -134,8 +133,7 @@ class FileEditorInputFactory implements IEditorInputFactory {
public serialize(editorInput: EditorInput): string {
let fileEditorInput = <FileEditorInput>editorInput;
let fileInput: ISerializedFileInput = {
resource: fileEditorInput.getResource().toString(),
mime: fileEditorInput.getMime()
resource: fileEditorInput.getResource().toString()
};
return JSON.stringify(fileInput);
......@@ -144,7 +142,7 @@ class FileEditorInputFactory implements IEditorInputFactory {
public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
let fileInput: ISerializedFileInput = JSON.parse(serializedEditorInput);
return instantiationService.createInstance(FileEditorInput, URI.parse(fileInput.resource), fileInput.mime, void 0);
return instantiationService.createInstance(FileEditorInput, URI.parse(fileInput.resource), void 0, void 0);
}
}
......
......@@ -76,7 +76,7 @@ function groupListener(group: IEditorGroup): GroupEvents {
};
group.onEditorOpened(e => groupEvents.opened.push(e));
group.onEditorClosed(e => groupEvents.closed.push(e));
group.onEditorClosed(e => groupEvents.closed.push(e.editor));
group.onEditorActivated(e => groupEvents.activated.push(e));
group.onEditorPinned(e => groupEvents.pinned.push(e));
group.onEditorUnpinned(e => groupEvents.unpinned.push(e));
......@@ -94,7 +94,7 @@ class TestEditorInput extends EditorInput {
public resolve() { return null; }
public matches(other: TestEditorInput): boolean {
return this.id === other.id && other instanceof TestEditorInput;
return other && this.id === other.id && other instanceof TestEditorInput;
}
}
......@@ -106,7 +106,7 @@ class NonSerializableTestEditorInput extends EditorInput {
public resolve() { return null; }
public matches(other: TestEditorInput): boolean {
return this.id === other.id && other instanceof NonSerializableTestEditorInput;
return other && this.id === other.id && other instanceof NonSerializableTestEditorInput;
}
}
......@@ -262,7 +262,7 @@ suite('Editor Stacks Model', () => {
test('Groups - Event Aggregation', function () {
const model = create();
let groupEvents:IEditorGroup[] = [];
let groupEvents: IEditorGroup[] = [];
let count = groupEvents.length;
model.onModelChanged(group => {
groupEvents.push(group);
......@@ -529,11 +529,59 @@ suite('Editor Stacks Model', () => {
assert.equal(input3, group.getEditors()[2]);
const input4 = input();
group.openEditor(input4, { pinned: false, active: true}); // this should cause the preview editor to move after input3
group.openEditor(input4, { pinned: false, active: true }); // this should cause the preview editor to move after input3
assert.equal(input4, group.getEditors()[2]);
});
test('Stack - Multiple Editors - Recently Closed Tracking', function () {
let services = new ServiceCollection();
services.set(IStorageService, new TestStorageService());
services.set(IWorkspaceContextService, new TestContextService());
const lifecycle = new TestLifecycleService();
services.set(ILifecycleService, lifecycle);
let inst = new InstantiationService(services);
(<IEditorRegistry>Registry.as(EditorExtensions.Editors)).setInstantiationService(inst);
let model: EditorStacksModel = inst.createInstance(EditorStacksModel);
const group1 = model.openGroup('group1');
const group2 = model.openGroup('group2');
const input1 = input();
const input2 = input();
const input3 = input();
group1.openEditor(input1, { pinned: false, active: true });
group1.openEditor(input2, { pinned: true, active: true });
group1.openEditor(input3, { pinned: true, active: true });
const input4 = input();
const input5 = input();
group2.openEditor(input4, { pinned: true, active: true });
group2.openEditor(input5, { pinned: true, active: true });
assert.ok(!model.popLastClosedEditor());
group1.closeEditor(input1);
assert.ok(!model.popLastClosedEditor()); // preview editors are not recorded
group1.closeEditor(input3);
assert.ok(input3.matches(model.popLastClosedEditor()));
group2.closeAllEditors();
assert.ok(input5.matches(model.popLastClosedEditor()));
assert.ok(input4.matches(model.popLastClosedEditor()));
assert.ok(!model.popLastClosedEditor());
});
test('Stack - Multiple Editors - Pinned and Active (DEFAULT_OPEN_EDITOR_DIRECTION = Direction.LEFT)', function () {
setOpenEditorDirection(Direction.LEFT);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册