On the fly tab model construction (#133025)
* Enrich the change event * Initial tab model building * Work in progress model construction * Add pauseable emitter * Attempt using microtask * Make tests pass * Update active tab logic * Fix layering issue * event rename * PR feedback * Remove stray new line * Add test for microtask emitter * Add move event * Add mmerge functionality to Microtask emitter * Fix compilation errrors * Fix tests * Add tests to address feedback * Change editor change event to an array * Add array support to editorsChangeEvent * Update src/vs/workbench/common/editor/editorGroupModel.ts Co-authored-by: Benjamin Pasero <benjpas@microsoft.com> * Switch to a less efficient array method * Add console.log for debugging * Test with different notebook * Fix notebook URI * For now split up file open for better debugging * Don't use notebook in test for now * Cleanup event * Fix tests Co-authored-by: Benjamin Pasero <benjamin.pasero@microsoft.com> Co-authored-by: Benjamin Pasero <benjpas@microsoft.com>
This commit is contained in:
parent
c78811c1a7
commit
76c3eb94c9
|
@ -49,7 +49,8 @@ const CORE_TYPES = [
|
|||
'decode',
|
||||
'self',
|
||||
'trimLeft',
|
||||
'trimRight'
|
||||
'trimRight',
|
||||
'queueMicrotask'
|
||||
];
|
||||
// Types that are defined in a common layer but are known to be only
|
||||
// available in native environments should not be allowed in browser
|
||||
|
|
|
@ -50,7 +50,8 @@ const CORE_TYPES = [
|
|||
'decode',
|
||||
'self',
|
||||
'trimLeft',
|
||||
'trimRight'
|
||||
'trimRight',
|
||||
'queueMicrotask'
|
||||
];
|
||||
|
||||
// Types that are defined in a common layer but are known to be only
|
||||
|
|
|
@ -348,33 +348,30 @@ suite('vscode API - window', () => {
|
|||
});
|
||||
|
||||
//#region Tabs API tests
|
||||
test.skip('Tabs - Ensure tabs getter is correct', async () => {
|
||||
assert.ok(workspace.workspaceFolders);
|
||||
const workspaceRoot = workspace.workspaceFolders[0].uri;
|
||||
const [docA, docB, docC, notebookDoc] = await Promise.all([
|
||||
workspace.openTextDocument(await createRandomFile()),
|
||||
workspace.openTextDocument(await createRandomFile()),
|
||||
workspace.openTextDocument(await createRandomFile()),
|
||||
workspace.openNotebookDocument(Uri.joinPath(workspaceRoot, 'test.ipynb'))
|
||||
]);
|
||||
test('Tabs - Ensure tabs getter is correct', async () => {
|
||||
const docA = await workspace.openTextDocument(await createRandomFile());
|
||||
const docB = await workspace.openTextDocument(await createRandomFile());
|
||||
const docC = await workspace.openTextDocument(await createRandomFile());
|
||||
// Add back actual notebook doc once stuck promise is figured out
|
||||
//const notebookDoc = await workspace.openNotebookDocument(await createRandomFile('', undefined, '.vsctestnb'));
|
||||
const notebookDoc = await workspace.openTextDocument(await createRandomFile());
|
||||
// const [docA, docB, docC, notebookDoc] = await Promise.all([
|
||||
// workspace.openTextDocument(await createRandomFile()),
|
||||
// workspace.openTextDocument(await createRandomFile()),
|
||||
// workspace.openTextDocument(await createRandomFile()),
|
||||
// workspace.openNotebookDocument(await createRandomFile('', undefined, '.vsctestnb'))
|
||||
// ]);
|
||||
|
||||
await window.showTextDocument(docA, { viewColumn: ViewColumn.One, preview: false });
|
||||
await window.showTextDocument(docB, { viewColumn: ViewColumn.Two, preview: false });
|
||||
await window.showTextDocument(docC, { viewColumn: ViewColumn.Three, preview: false });
|
||||
await window.showNotebookDocument(notebookDoc, { viewColumn: ViewColumn.One, preview: false });
|
||||
await window.showTextDocument(notebookDoc, { viewColumn: ViewColumn.One, preview: false });
|
||||
//await window.showNotebookDocument(notebookDoc, { viewColumn: ViewColumn.One, preview: false });
|
||||
|
||||
const leftDiff = await createRandomFile();
|
||||
const rightDiff = await createRandomFile();
|
||||
await commands.executeCommand('vscode.diff', leftDiff, rightDiff, 'Diff', { viewColumn: ViewColumn.Three, preview: false });
|
||||
|
||||
// Wait for the tab change event to fire
|
||||
await new Promise<void>((resolve) => {
|
||||
const dispsable = window.onDidChangeTabs(() => {
|
||||
dispsable.dispose();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
const tabs = window.tabs;
|
||||
assert.strictEqual(tabs.length, 5);
|
||||
|
||||
|
@ -393,16 +390,8 @@ suite('vscode API - window', () => {
|
|||
assert.strictEqual(tabs[4].viewColumn, ViewColumn.Three);
|
||||
});
|
||||
|
||||
test.skip('Tabs - ensure active tab is correct', async () => {
|
||||
test('Tabs - ensure active tab is correct', async () => {
|
||||
|
||||
function createActiveTabListenerPromise(): Promise<void> {
|
||||
return new Promise<void>((resolve) => {
|
||||
const dispsable = window.onDidChangeActiveTab(() => {
|
||||
dispsable.dispose();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
const [docA, docB, docC] = await Promise.all([
|
||||
workspace.openTextDocument(await createRandomFile()),
|
||||
workspace.openTextDocument(await createRandomFile()),
|
||||
|
@ -410,24 +399,20 @@ suite('vscode API - window', () => {
|
|||
]);
|
||||
|
||||
await window.showTextDocument(docA, { viewColumn: ViewColumn.One, preview: false });
|
||||
await createActiveTabListenerPromise();
|
||||
assert.ok(window.activeTab);
|
||||
assert.strictEqual(window.activeTab.resource?.toString(), docA.uri.toString());
|
||||
|
||||
await window.showTextDocument(docB, { viewColumn: ViewColumn.Two, preview: false });
|
||||
await createActiveTabListenerPromise();
|
||||
assert.ok(window.activeTab);
|
||||
assert.strictEqual(window.activeTab.resource?.toString(), docB.uri.toString());
|
||||
|
||||
await window.showTextDocument(docC, { viewColumn: ViewColumn.Three, preview: false });
|
||||
await createActiveTabListenerPromise();
|
||||
assert.ok(window.activeTab);
|
||||
assert.strictEqual(window.activeTab.resource?.toString(), docC.uri.toString());
|
||||
|
||||
await commands.executeCommand('workbench.action.closeActiveEditor');
|
||||
await commands.executeCommand('workbench.action.closeActiveEditor');
|
||||
await commands.executeCommand('workbench.action.closeActiveEditor');
|
||||
await createActiveTabListenerPromise();
|
||||
|
||||
assert.ok(!window.activeTab);
|
||||
|
||||
|
|
|
@ -732,6 +732,33 @@ export class DebounceEmitter<T> extends PauseableEmitter<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An emitter which queue all events and then process them at the
|
||||
* end of the event loop.
|
||||
*/
|
||||
export class MicrotaskEmitter<T> extends Emitter<T> {
|
||||
private _queuedEvents: T[] = [];
|
||||
private _mergeFn?: (input: T[]) => T;
|
||||
|
||||
constructor(options?: EmitterOptions & { merge?: (input: T[]) => T }) {
|
||||
super(options);
|
||||
this._mergeFn = options?.merge;
|
||||
}
|
||||
override fire(event: T): void {
|
||||
this._queuedEvents.push(event);
|
||||
if (this._queuedEvents.length === 1) {
|
||||
queueMicrotask(() => {
|
||||
if (this._mergeFn) {
|
||||
super.fire(this._mergeFn(this._queuedEvents));
|
||||
} else {
|
||||
this._queuedEvents.forEach(e => super.fire(e));
|
||||
}
|
||||
this._queuedEvents = [];
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class EventMultiplexer<T> implements IDisposable {
|
||||
|
||||
private readonly emitter: Emitter<T>;
|
||||
|
|
|
@ -6,7 +6,7 @@ import * as assert from 'assert';
|
|||
import { timeout } from 'vs/base/common/async';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { errorHandler, setUnexpectedErrorHandler } from 'vs/base/common/errors';
|
||||
import { AsyncEmitter, DebounceEmitter, Emitter, Event, EventBufferer, EventMultiplexer, IWaitUntil, PauseableEmitter, Relay } from 'vs/base/common/event';
|
||||
import { AsyncEmitter, DebounceEmitter, Emitter, Event, EventBufferer, EventMultiplexer, IWaitUntil, MicrotaskEmitter, PauseableEmitter, Relay } from 'vs/base/common/event';
|
||||
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
namespace Samples {
|
||||
|
@ -274,6 +274,29 @@ suite('Event', function () {
|
|||
assert.strictEqual(sum, 3);
|
||||
});
|
||||
|
||||
test('Microtask Emitter', (done) => {
|
||||
let count = 0;
|
||||
assert.strictEqual(count, 0);
|
||||
const emitter = new MicrotaskEmitter<void>();
|
||||
const listener = emitter.event(() => {
|
||||
count++;
|
||||
});
|
||||
emitter.fire();
|
||||
assert.strictEqual(count, 0);
|
||||
emitter.fire();
|
||||
assert.strictEqual(count, 0);
|
||||
// Should wait until the event loop ends and therefore be the last thing called
|
||||
setTimeout(() => {
|
||||
assert.strictEqual(count, 3);
|
||||
done();
|
||||
}, 0);
|
||||
queueMicrotask(() => {
|
||||
assert.strictEqual(count, 2);
|
||||
count++;
|
||||
listener.dispose();
|
||||
});
|
||||
});
|
||||
|
||||
test('Emitter - In Order Delivery', function () {
|
||||
const a = new Emitter<string>();
|
||||
const listener2Events: string[] = [];
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ExtHostContext, IExtHostEditorTabsShape, IExtHostContext, MainContext, IEditorTabDto } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { EditorResourceAccessor, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||
import { EditorResourceAccessor, IEditorsChangeEvent, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
|
||||
import { editorGroupToColumn } from 'vs/workbench/services/editor/common/editorGroupColumn';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { GroupChangeKind, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
|
||||
|
@ -18,6 +19,9 @@ export class MainThreadEditorTabs {
|
|||
|
||||
private readonly _dispoables = new DisposableStore();
|
||||
private readonly _proxy: IExtHostEditorTabsShape;
|
||||
private readonly _tabModel: Map<number, IEditorTabDto[]> = new Map<number, IEditorTabDto[]>();
|
||||
private _currentlyActiveTab: { groupId: number, tab: IEditorTabDto } | undefined = undefined;
|
||||
private _oldTabModel: IEditorTabDto[] = [];
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
|
@ -27,31 +31,171 @@ export class MainThreadEditorTabs {
|
|||
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostEditorTabs);
|
||||
|
||||
this._dispoables.add(editorService.onDidEditorsChange(this._pushEditorTabs, this));
|
||||
this._editorGroupsService.whenReady.then(() => this._pushEditorTabs());
|
||||
// Queue all events that arrive on the same event loop and then send them as a batch
|
||||
this._dispoables.add(editorService.onDidEditorsChange((events) => this._updateTabsModel(events)));
|
||||
this._editorGroupsService.whenReady.then(() => this._createTabsModel());
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._dispoables.dispose();
|
||||
}
|
||||
|
||||
private _pushEditorTabs(): void {
|
||||
const tabs: IEditorTabDto[] = [];
|
||||
private _createTabsModel(): void {
|
||||
this._tabModel.clear();
|
||||
let tabs: IEditorTabDto[] = [];
|
||||
for (const group of this._editorGroupsService.groups) {
|
||||
for (const editor of group.editors) {
|
||||
if (editor.isDisposed()) {
|
||||
continue;
|
||||
}
|
||||
tabs.push({
|
||||
const tab = {
|
||||
viewColumn: editorGroupToColumn(this._editorGroupsService, group),
|
||||
label: editor.getName(),
|
||||
resource: editor instanceof SideBySideEditorInput ? EditorResourceAccessor.getCanonicalUri(editor, { supportSideBySide: SideBySideEditor.PRIMARY }) : EditorResourceAccessor.getCanonicalUri(editor),
|
||||
editorId: editor.editorId,
|
||||
isActive: (this._editorGroupsService.activeGroup === group) && group.isActive(editor)
|
||||
});
|
||||
};
|
||||
if (tab.isActive) {
|
||||
this._currentlyActiveTab = { groupId: group.id, tab };
|
||||
}
|
||||
tabs.push(tab);
|
||||
}
|
||||
this._tabModel.set(group.id, tabs);
|
||||
}
|
||||
|
||||
this._proxy.$acceptEditorTabs(tabs);
|
||||
}
|
||||
|
||||
private _onDidTabOpen(event: IEditorsChangeEvent): void {
|
||||
if (event.kind !== GroupChangeKind.EDITOR_OPEN || !event.editor || event.editorIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
if (!this._tabModel.has(event.groupId)) {
|
||||
this._tabModel.set(event.groupId, []);
|
||||
}
|
||||
const editor = event.editor;
|
||||
const tab = {
|
||||
viewColumn: editorGroupToColumn(this._editorGroupsService, event.groupId),
|
||||
label: editor.getName(),
|
||||
resource: editor instanceof SideBySideEditorInput ? EditorResourceAccessor.getCanonicalUri(editor, { supportSideBySide: SideBySideEditor.PRIMARY }) : EditorResourceAccessor.getCanonicalUri(editor),
|
||||
editorId: editor.editorId,
|
||||
isActive: (this._editorGroupsService.activeGroup.id === event.groupId) && this._editorGroupsService.activeGroup.isActive(editor)
|
||||
};
|
||||
this._tabModel.get(event.groupId)?.splice(event.editorIndex, 0, tab);
|
||||
// Update the currently active tab which may or may not be the opened one
|
||||
if (tab.isActive) {
|
||||
if (this._currentlyActiveTab) {
|
||||
this._currentlyActiveTab.tab.isActive = (this._editorGroupsService.activeGroup.id === this._currentlyActiveTab.groupId) && this._editorGroupsService.activeGroup.isActive({ resource: URI.revive(this._currentlyActiveTab.tab.resource), options: { override: this._currentlyActiveTab.tab.editorId } });
|
||||
}
|
||||
this._currentlyActiveTab = { groupId: event.groupId, tab };
|
||||
}
|
||||
}
|
||||
|
||||
private _onDidTabClose(event: IEditorsChangeEvent): void {
|
||||
if (event.kind !== GroupChangeKind.EDITOR_CLOSE || event.editorIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
this._tabModel.get(event.groupId)?.splice(event.editorIndex, 1);
|
||||
this._findAndUpdateActiveTab();
|
||||
|
||||
// Remove any empty groups
|
||||
if (this._tabModel.get(event.groupId)?.length === 0) {
|
||||
this._tabModel.delete(event.groupId);
|
||||
}
|
||||
}
|
||||
|
||||
private _onDidTabMove(event: IEditorsChangeEvent): void {
|
||||
if (event.kind !== GroupChangeKind.EDITOR_MOVE || event.editorIndex === undefined || event.previousEditorIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
const movedTab = this._tabModel.get(event.groupId)?.splice(event.previousEditorIndex, 1);
|
||||
if (movedTab === undefined) {
|
||||
return;
|
||||
}
|
||||
this._tabModel.get(event.groupId)?.splice(event.previousEditorIndex, 0, movedTab[0]);
|
||||
movedTab[0].isActive = (this._editorGroupsService.activeGroup.id === event.groupId) && this._editorGroupsService.activeGroup.isActive({ resource: URI.revive(movedTab[0].resource), options: { override: movedTab[0].editorId } });
|
||||
// Update the currently active tab
|
||||
if (movedTab[0].isActive) {
|
||||
if (this._currentlyActiveTab) {
|
||||
this._currentlyActiveTab.tab.isActive = (this._editorGroupsService.activeGroup.id === this._currentlyActiveTab.groupId) && this._editorGroupsService.activeGroup.isActive({ resource: URI.revive(this._currentlyActiveTab.tab.resource), options: { override: this._currentlyActiveTab.tab.editorId } });
|
||||
}
|
||||
this._currentlyActiveTab = { groupId: event.groupId, tab: movedTab[0] };
|
||||
}
|
||||
}
|
||||
|
||||
private _onDidGroupActivate(event: IEditorsChangeEvent): void {
|
||||
if (event.kind !== GroupChangeKind.GROUP_INDEX) {
|
||||
return;
|
||||
}
|
||||
this._findAndUpdateActiveTab();
|
||||
}
|
||||
|
||||
private _findAndUpdateActiveTab() {
|
||||
// Go to the active group and update the active tab
|
||||
const activeGroupId = this._editorGroupsService.activeGroup.id;
|
||||
this._tabModel.get(activeGroupId)?.forEach(t => {
|
||||
if (t.resource) {
|
||||
t.isActive = this._editorGroupsService.activeGroup.isActive({ resource: URI.revive(t.resource), options: { override: t.editorId } });
|
||||
}
|
||||
if (t.isActive) {
|
||||
if (this._currentlyActiveTab) {
|
||||
this._currentlyActiveTab.tab.isActive = (this._editorGroupsService.activeGroup.id === this._currentlyActiveTab.groupId) && this._editorGroupsService.activeGroup.isActive({ resource: URI.revive(this._currentlyActiveTab.tab.resource), options: { override: this._currentlyActiveTab.tab.editorId } });
|
||||
}
|
||||
this._currentlyActiveTab = { groupId: activeGroupId, tab: t };
|
||||
return;
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to compare previous tab model to current one
|
||||
* @param current The current tab model to compare to the previous mode
|
||||
* @returns True if they're equivalent, false otherwise
|
||||
*/
|
||||
private _compareTabsModel(current: IEditorTabDto[]): boolean {
|
||||
if (this._oldTabModel.length !== current.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < current.length; i++) {
|
||||
if (this._oldTabModel[i].resource !== current[i].resource && this._oldTabModel[i].editorId !== current[i].editorId) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private _updateTabsModel(events: IEditorsChangeEvent[]): void {
|
||||
events.forEach(event => {
|
||||
// Call the correct function for the change type
|
||||
switch (event.kind) {
|
||||
case GroupChangeKind.EDITOR_OPEN:
|
||||
this._onDidTabOpen(event);
|
||||
break;
|
||||
case GroupChangeKind.EDITOR_CLOSE:
|
||||
this._onDidTabClose(event);
|
||||
break;
|
||||
case GroupChangeKind.GROUP_ACTIVE:
|
||||
if (this._editorGroupsService.activeGroup.id !== event.groupId) {
|
||||
return;
|
||||
}
|
||||
this._onDidGroupActivate(event);
|
||||
break;
|
||||
case GroupChangeKind.GROUP_INDEX:
|
||||
this._createTabsModel();
|
||||
// Here we stop the loop as no need to process other events
|
||||
break;
|
||||
case GroupChangeKind.EDITOR_MOVE:
|
||||
this._onDidTabMove(event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
// Flatten the map into a singular array to send the ext host
|
||||
let allTabs: IEditorTabDto[] = [];
|
||||
this._tabModel.forEach((tabs) => allTabs = allTabs.concat(tabs));
|
||||
if (!this._compareTabsModel(allTabs)) {
|
||||
this._proxy.$acceptEditorTabs(allTabs);
|
||||
this._oldTabModel = allTabs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/editorgroupview';
|
||||
import { EditorGroupModel, IEditorOpenOptions, EditorCloseEvent, ISerializedEditorGroupModel, isSerializedEditorGroupModel } from 'vs/workbench/common/editor/editorGroupModel';
|
||||
import { EditorGroupModel, IEditorOpenOptions, EditorCloseEvent, ISerializedEditorGroupModel, isSerializedEditorGroupModel, EditorMoveEvent, EditorOpenEvent } from 'vs/workbench/common/editor/editorGroupModel';
|
||||
import { GroupIdentifier, CloseDirection, IEditorCloseEvent, ActiveEditorDirtyContext, IEditorPane, EditorGroupEditorsCountContext, SaveReason, IEditorPartOptionsChangeEvent, EditorsOrder, IVisibleEditorPane, ActiveEditorStickyContext, ActiveEditorPinnedContext, EditorResourceAccessor, IEditorMoveEvent, EditorInputCapabilities, IEditorOpenEvent, IUntypedEditorInput, DEFAULT_EDITOR_ASSOCIATION, ActiveEditorGroupLockedContext, SideBySideEditor, EditorCloseContext } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
|
||||
|
@ -525,6 +525,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
this._register(this.model.onDidChangeLocked(() => this.onDidChangeGroupLocked()));
|
||||
this._register(this.model.onDidChangeEditorPinned(editor => this.onDidChangeEditorPinned(editor)));
|
||||
this._register(this.model.onDidChangeEditorSticky(editor => this.onDidChangeEditorSticky(editor)));
|
||||
this._register(this.model.onDidMoveEditor(event => this.onDidMoveEditor(event)));
|
||||
this._register(this.model.onDidOpenEditor(editor => this.onDidOpenEditor(editor)));
|
||||
this._register(this.model.onDidCloseEditor(editor => this.handleOnDidCloseEditor(editor)));
|
||||
this._register(this.model.onWillDisposeEditor(editor => this.onWillDisposeEditor(editor)));
|
||||
|
@ -551,7 +552,11 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_STICKY, editor });
|
||||
}
|
||||
|
||||
private onDidOpenEditor(editor: EditorInput): void {
|
||||
private onDidMoveEditor(event: EditorMoveEvent): void {
|
||||
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_MOVE, editor: event.editor, previousEditorIndex: event.index, editorIndex: event.newIndex });
|
||||
}
|
||||
|
||||
private onDidOpenEditor({ editor, index }: EditorOpenEvent): void {
|
||||
|
||||
/* __GDPR__
|
||||
"editorOpened" : {
|
||||
|
@ -566,7 +571,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
this.updateContainer();
|
||||
|
||||
// Event
|
||||
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_OPEN, editor });
|
||||
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_OPEN, editor, editorIndex: index });
|
||||
}
|
||||
|
||||
private handleOnDidCloseEditor(event: EditorCloseEvent): void {
|
||||
|
@ -929,9 +934,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
const newIndexOfEditor = this.getIndexOfEditor(editor);
|
||||
if (newIndexOfEditor !== oldIndexOfEditor) {
|
||||
this.titleAreaControl.moveEditor(editor, oldIndexOfEditor, newIndexOfEditor);
|
||||
|
||||
// Event
|
||||
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_MOVE, editor });
|
||||
}
|
||||
|
||||
// Forward sticky state to title control
|
||||
|
@ -1290,9 +1292,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
|||
// Forward to title area
|
||||
this.titleAreaControl.moveEditor(editor, currentIndex, moveToIndex);
|
||||
this.titleAreaControl.pinEditor(editor);
|
||||
|
||||
// Event
|
||||
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_MOVE, editor });
|
||||
}
|
||||
|
||||
private doMoveOrCopyEditorAcrossGroups(editor: EditorInput, target: EditorGroupView, openOptions?: IEditorOpenOptions, internalOptions?: IInternalMoveCopyOptions): void {
|
||||
|
|
|
@ -15,7 +15,7 @@ import { IInstantiationService, IConstructorSignature0, ServicesAccessor, Brande
|
|||
import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IEncodingSupport, IModeSupport } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorGroup, IGroupChangeEvent } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { ICompositeControl, IComposite } from 'vs/workbench/common/composite';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IPathData } from 'vs/platform/windows/common/windows';
|
||||
|
@ -763,6 +763,10 @@ export interface IEditorCloseEvent extends IEditorIdentifier {
|
|||
sticky: boolean;
|
||||
}
|
||||
|
||||
export interface IEditorsChangeEvent extends IGroupChangeEvent {
|
||||
groupId: GroupIdentifier;
|
||||
}
|
||||
|
||||
export interface IEditorMoveEvent extends IEditorIdentifier {
|
||||
target: GroupIdentifier;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IEditorFactoryRegistry, IEditorIdentifier, IEditorCloseEvent, GroupIdentifier, EditorsOrder, EditorExtensions, IUntypedEditorInput, SideBySideEditor, EditorCloseContext } from 'vs/workbench/common/editor';
|
||||
import { IEditorFactoryRegistry, IEditorIdentifier, IEditorCloseEvent, GroupIdentifier, EditorsOrder, EditorExtensions, IUntypedEditorInput, SideBySideEditor, IEditorMoveEvent, IEditorOpenEvent, EditorCloseContext } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
@ -24,6 +24,17 @@ export interface EditorCloseEvent extends IEditorCloseEvent {
|
|||
readonly editor: EditorInput;
|
||||
}
|
||||
|
||||
export interface EditorOpenEvent extends IEditorOpenEvent {
|
||||
readonly editor: EditorInput;
|
||||
readonly index: number;
|
||||
}
|
||||
|
||||
export interface EditorMoveEvent extends IEditorMoveEvent {
|
||||
readonly editor: EditorInput;
|
||||
readonly index: number;
|
||||
readonly newIndex: number;
|
||||
}
|
||||
|
||||
export interface EditorIdentifier extends IEditorIdentifier {
|
||||
readonly groupId: GroupIdentifier;
|
||||
readonly editor: EditorInput;
|
||||
|
@ -91,7 +102,7 @@ export class EditorGroupModel extends Disposable {
|
|||
private readonly _onDidActivateEditor = this._register(new Emitter<EditorInput>());
|
||||
readonly onDidActivateEditor = this._onDidActivateEditor.event;
|
||||
|
||||
private readonly _onDidOpenEditor = this._register(new Emitter<EditorInput>());
|
||||
private readonly _onDidOpenEditor = this._register(new Emitter<EditorOpenEvent>());
|
||||
readonly onDidOpenEditor = this._onDidOpenEditor.event;
|
||||
|
||||
private readonly _onDidCloseEditor = this._register(new Emitter<EditorCloseEvent>());
|
||||
|
@ -109,7 +120,7 @@ export class EditorGroupModel extends Disposable {
|
|||
private readonly _onDidChangeEditorCapabilities = this._register(new Emitter<EditorInput>());
|
||||
readonly onDidChangeEditorCapabilities = this._onDidChangeEditorCapabilities.event;
|
||||
|
||||
private readonly _onDidMoveEditor = this._register(new Emitter<EditorInput>());
|
||||
private readonly _onDidMoveEditor = this._register(new Emitter<EditorMoveEvent>());
|
||||
readonly onDidMoveEditor = this._onDidMoveEditor.event;
|
||||
|
||||
private readonly _onDidChangeEditorPinned = this._register(new Emitter<EditorInput>());
|
||||
|
@ -295,7 +306,7 @@ export class EditorGroupModel extends Disposable {
|
|||
this.registerEditorListeners(newEditor);
|
||||
|
||||
// Event
|
||||
this._onDidOpenEditor.fire(newEditor);
|
||||
this._onDidOpenEditor.fire({ editor: newEditor, groupId: this.id, index: targetIndex });
|
||||
|
||||
// Handle active
|
||||
if (makeActive) {
|
||||
|
@ -475,7 +486,7 @@ export class EditorGroupModel extends Disposable {
|
|||
this.editors.splice(toIndex, 0, editor);
|
||||
|
||||
// Event
|
||||
this._onDidMoveEditor.fire(editor);
|
||||
this._onDidMoveEditor.fire({ editor, groupId: this.id, index, newIndex: toIndex, target: this.id });
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IResourceEditorInput, IEditorOptions, EditorActivation, EditorResolution, IResourceEditorInputIdentifier, ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { SideBySideEditor, IEditorPane, GroupIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInputWithOptions, isEditorInputWithOptions, IEditorIdentifier, IEditorCloseEvent, ITextDiffEditorPane, IRevertOptions, SaveReason, EditorsOrder, IWorkbenchEditorConfiguration, EditorResourceAccessor, IVisibleEditorPane, EditorInputCapabilities, isResourceDiffEditorInput, IUntypedEditorInput, isResourceEditorInput, isEditorInput, isEditorInputWithOptionsAndGroup } from 'vs/workbench/common/editor';
|
||||
import { SideBySideEditor, IEditorPane, GroupIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInputWithOptions, isEditorInputWithOptions, IEditorIdentifier, IEditorCloseEvent, ITextDiffEditorPane, IRevertOptions, SaveReason, EditorsOrder, IWorkbenchEditorConfiguration, EditorResourceAccessor, IVisibleEditorPane, EditorInputCapabilities, isResourceDiffEditorInput, IUntypedEditorInput, isResourceEditorInput, isEditorInput, isEditorInputWithOptionsAndGroup, IEditorsChangeEvent } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { IFileService, FileOperationEvent, FileOperation, FileChangesEvent, FileChangeType } from 'vs/platform/files/common/files';
|
||||
import { Event, Emitter, DebounceEmitter } from 'vs/base/common/event';
|
||||
import { Event, Emitter, MicrotaskEmitter } from 'vs/base/common/event';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
|
@ -47,7 +47,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
private readonly _onDidVisibleEditorsChange = this._register(new Emitter<void>());
|
||||
readonly onDidVisibleEditorsChange = this._onDidVisibleEditorsChange.event;
|
||||
|
||||
private readonly _onDidEditorsChange = this._register(new DebounceEmitter<void>({ delay: 0, merge: () => undefined }));
|
||||
private readonly _onDidEditorsChange = this._register(new MicrotaskEmitter<IEditorsChangeEvent[]>({ merge: (events) => events.flat(1) }));
|
||||
readonly onDidEditorsChange = this._onDidEditorsChange.event;
|
||||
|
||||
private readonly _onDidCloseEditor = this._register(new Emitter<IEditorCloseEvent>());
|
||||
|
@ -87,7 +87,6 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
this.editorGroupService.whenReady.then(() => this.onEditorGroupsReady());
|
||||
this.editorGroupService.onDidChangeActiveGroup(group => this.handleActiveEditorChange(group));
|
||||
this.editorGroupService.onDidAddGroup(group => this.registerGroupListeners(group as IEditorGroupView));
|
||||
this.editorGroupService.onDidMoveGroup(group => this.handleGroupMove(group));
|
||||
this.editorsObserver.onDidMostRecentlyActiveEditorsChange(() => this._onDidMostRecentlyActiveEditorsChange.fire());
|
||||
|
||||
// Out of workspace file watchers
|
||||
|
@ -123,14 +122,6 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
}
|
||||
}
|
||||
|
||||
private handleGroupMove(group: IEditorGroup): void {
|
||||
if (group.isEmpty) {
|
||||
return; // empty groups do not change structure of editors
|
||||
}
|
||||
|
||||
this._onDidEditorsChange.fire();
|
||||
}
|
||||
|
||||
private handleActiveEditorChange(group: IEditorGroup): void {
|
||||
if (group !== this.editorGroupService.activeGroup) {
|
||||
return; // ignore if not the active group
|
||||
|
@ -151,7 +142,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
|
||||
// Fire event to outside parties
|
||||
this._onDidActiveEditorChange.fire();
|
||||
this._onDidEditorsChange.fire();
|
||||
this._onDidEditorsChange.fire([{ groupId: activeGroup.id, editor: this.lastActiveEditor, kind: GroupChangeKind.EDITOR_ACTIVE }]);
|
||||
}
|
||||
|
||||
private registerGroupListeners(group: IEditorGroupView): void {
|
||||
|
@ -163,10 +154,8 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
this.handleActiveEditorChange(group);
|
||||
this._onDidVisibleEditorsChange.fire();
|
||||
break;
|
||||
case GroupChangeKind.EDITOR_CLOSE:
|
||||
case GroupChangeKind.EDITOR_OPEN:
|
||||
case GroupChangeKind.EDITOR_MOVE:
|
||||
this._onDidEditorsChange.fire();
|
||||
default:
|
||||
this._onDidEditorsChange.fire([{ groupId: group.id, ...e }]);
|
||||
break;
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -418,6 +418,11 @@ export interface IGroupChangeEvent {
|
|||
kind: GroupChangeKind;
|
||||
editor?: EditorInput;
|
||||
editorIndex?: number;
|
||||
/**
|
||||
* For EDITOR_MOVE only. Signifies the index the editor is moving from.
|
||||
* editorIndex will contain the index the editor is moving to.
|
||||
*/
|
||||
previousEditorIndex?: number;
|
||||
}
|
||||
|
||||
export const enum OpenEditorContext {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IResourceEditorInput, IEditorOptions, IResourceEditorInputIdentifier, ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { IEditorPane, GroupIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, ITextDiffEditorPane, IEditorIdentifier, ISaveOptions, IRevertOptions, EditorsOrder, IVisibleEditorPane, IEditorCloseEvent, IUntypedEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IEditorPane, GroupIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, ITextDiffEditorPane, IEditorIdentifier, ISaveOptions, IRevertOptions, EditorsOrder, IVisibleEditorPane, IEditorCloseEvent, IUntypedEditorInput, IEditorsChangeEvent } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IEditor, IDiffEditor } from 'vs/editor/common/editorCommon';
|
||||
|
@ -105,7 +105,7 @@ export interface IEditorService {
|
|||
* - editors moving
|
||||
* - groups moving (unless they are empty)
|
||||
*/
|
||||
readonly onDidEditorsChange: Event<void>;
|
||||
readonly onDidEditorsChange: Event<IEditorsChangeEvent[]>;
|
||||
|
||||
/**
|
||||
* Emitted when an editor is closed.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { EditorGroupModel, ISerializedEditorGroupModel, EditorCloseEvent } from 'vs/workbench/common/editor/editorGroupModel';
|
||||
import { EditorGroupModel, ISerializedEditorGroupModel, EditorCloseEvent, EditorMoveEvent, EditorOpenEvent } from 'vs/workbench/common/editor/editorGroupModel';
|
||||
import { EditorExtensions, IEditorFactoryRegistry, IFileEditorInput, IEditorSerializer, CloseDirection, EditorsOrder, IResourceDiffEditorInput, IResourceSideBySideEditorInput, SideBySideEditor, EditorCloseContext } from 'vs/workbench/common/editor';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TestLifecycleService, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
|
@ -80,14 +80,14 @@ suite('EditorGroupModel', () => {
|
|||
|
||||
interface GroupEvents {
|
||||
locked: number[],
|
||||
opened: EditorInput[];
|
||||
opened: EditorOpenEvent[];
|
||||
activated: EditorInput[];
|
||||
closed: EditorCloseEvent[];
|
||||
pinned: EditorInput[];
|
||||
unpinned: EditorInput[];
|
||||
sticky: EditorInput[];
|
||||
unsticky: EditorInput[];
|
||||
moved: EditorInput[];
|
||||
moved: EditorMoveEvent[];
|
||||
disposed: EditorInput[];
|
||||
}
|
||||
|
||||
|
@ -746,7 +746,7 @@ suite('EditorGroupModel', () => {
|
|||
assert.strictEqual(group.isPinned(input1), true);
|
||||
assert.strictEqual(group.isPinned(0), true);
|
||||
|
||||
assert.strictEqual(events.opened[0], input1);
|
||||
assert.strictEqual(events.opened[0].editor, input1);
|
||||
assert.strictEqual(events.activated[0], input1);
|
||||
|
||||
let index = group.indexOf(input1);
|
||||
|
@ -771,7 +771,7 @@ suite('EditorGroupModel', () => {
|
|||
assert.strictEqual(group.isPinned(input2), false);
|
||||
assert.strictEqual(group.isPinned(0), false);
|
||||
|
||||
assert.strictEqual(events.opened[1], input2);
|
||||
assert.strictEqual(events.opened[1].editor, input2);
|
||||
assert.strictEqual(events.activated[1], input2);
|
||||
|
||||
group.closeEditor(input2);
|
||||
|
@ -800,7 +800,7 @@ suite('EditorGroupModel', () => {
|
|||
assert.strictEqual(group.isPinned(input3), true);
|
||||
assert.strictEqual(group.isPinned(0), true);
|
||||
|
||||
assert.strictEqual(events.opened[2], input3);
|
||||
assert.strictEqual(events.opened[2].editor, input3);
|
||||
assert.strictEqual(events.activated[2], input3);
|
||||
|
||||
group.closeEditor(input3);
|
||||
|
@ -809,7 +809,7 @@ suite('EditorGroupModel', () => {
|
|||
assert.strictEqual(group.activeEditor, null);
|
||||
assert.strictEqual(events.closed[2].editor, input3);
|
||||
|
||||
assert.strictEqual(events.opened[2], input3);
|
||||
assert.strictEqual(events.opened[2].editor, input3);
|
||||
assert.strictEqual(events.activated[2], input3);
|
||||
|
||||
group.closeEditor(input3);
|
||||
|
@ -829,7 +829,7 @@ suite('EditorGroupModel', () => {
|
|||
assert.strictEqual(group.isPinned(input4), false);
|
||||
assert.strictEqual(group.isPinned(0), false);
|
||||
|
||||
assert.strictEqual(events.opened[3], input4);
|
||||
assert.strictEqual(events.opened[3].editor, input4);
|
||||
assert.strictEqual(events.activated[3], input4);
|
||||
|
||||
group.closeEditor(input4);
|
||||
|
@ -870,9 +870,9 @@ suite('EditorGroupModel', () => {
|
|||
assert.strictEqual(group.isActive(input3), true);
|
||||
assert.strictEqual(group.isPinned(input3), true);
|
||||
|
||||
assert.strictEqual(events.opened[0], input1);
|
||||
assert.strictEqual(events.opened[1], input2);
|
||||
assert.strictEqual(events.opened[2], input3);
|
||||
assert.strictEqual(events.opened[0].editor, input1);
|
||||
assert.strictEqual(events.opened[1].editor, input2);
|
||||
assert.strictEqual(events.opened[2].editor, input3);
|
||||
|
||||
assert.strictEqual(events.activated[0], input1);
|
||||
assert.strictEqual(events.activated[1], input2);
|
||||
|
@ -902,7 +902,7 @@ suite('EditorGroupModel', () => {
|
|||
assert.strictEqual(events.unsticky[0], input1);
|
||||
|
||||
group.moveEditor(sameInput1, 1);
|
||||
assert.strictEqual(events.moved[0], input1);
|
||||
assert.strictEqual(events.moved[0].editor, input1);
|
||||
|
||||
group.closeEditor(sameInput1);
|
||||
assert.strictEqual(events.closed[0].editor, input1);
|
||||
|
@ -1018,9 +1018,9 @@ suite('EditorGroupModel', () => {
|
|||
assert.strictEqual(group.isPinned(input3), false);
|
||||
assert.strictEqual(!group.isPinned(input3), true);
|
||||
|
||||
assert.strictEqual(events.opened[0], input1);
|
||||
assert.strictEqual(events.opened[1], input2);
|
||||
assert.strictEqual(events.opened[2], input3);
|
||||
assert.strictEqual(events.opened[0].editor, input1);
|
||||
assert.strictEqual(events.opened[1].editor, input2);
|
||||
assert.strictEqual(events.opened[2].editor, input3);
|
||||
assert.strictEqual(events.closed[0].editor, input1);
|
||||
assert.strictEqual(events.closed[1].editor, input2);
|
||||
assert.strictEqual(events.closed[0].context === EditorCloseContext.REPLACE, true);
|
||||
|
@ -1237,7 +1237,7 @@ suite('EditorGroupModel', () => {
|
|||
|
||||
group.moveEditor(input1, 1);
|
||||
|
||||
assert.strictEqual(events.moved[0], input1);
|
||||
assert.strictEqual(events.moved[0].editor, input1);
|
||||
assert.strictEqual(group.getEditors(EditorsOrder.SEQUENTIAL)[0], input2);
|
||||
assert.strictEqual(group.getEditors(EditorsOrder.SEQUENTIAL)[1], input1);
|
||||
|
||||
|
@ -1248,7 +1248,7 @@ suite('EditorGroupModel', () => {
|
|||
|
||||
group.moveEditor(input4, 0);
|
||||
|
||||
assert.strictEqual(events.moved[1], input4);
|
||||
assert.strictEqual(events.moved[1].editor, input4);
|
||||
assert.strictEqual(group.getEditors(EditorsOrder.SEQUENTIAL)[0], input4);
|
||||
assert.strictEqual(group.getEditors(EditorsOrder.SEQUENTIAL)[1], input2);
|
||||
assert.strictEqual(group.getEditors(EditorsOrder.SEQUENTIAL)[2], input1);
|
||||
|
@ -2117,4 +2117,64 @@ suite('EditorGroupModel', () => {
|
|||
assert.strictEqual(group.indexOf(input3), 3);
|
||||
assert.strictEqual(group.indexOf(input4), 2);
|
||||
});
|
||||
|
||||
test('onDidMoveEditor Event', () => {
|
||||
const group1 = createEditorGroupModel();
|
||||
const group2 = createEditorGroupModel();
|
||||
|
||||
const input1group1 = input();
|
||||
const input2group1 = input();
|
||||
const input1group2 = input();
|
||||
const input2group2 = input();
|
||||
|
||||
// Open all the editors
|
||||
group1.openEditor(input1group1, { pinned: true, active: true, index: 0 });
|
||||
group1.openEditor(input2group1, { pinned: true, active: false, index: 1 });
|
||||
group2.openEditor(input1group2, { pinned: true, active: true, index: 0 });
|
||||
group2.openEditor(input2group2, { pinned: true, active: false, index: 1 });
|
||||
|
||||
const group1Events = groupListener(group1);
|
||||
const group2Events = groupListener(group2);
|
||||
|
||||
group1.moveEditor(input1group1, 1);
|
||||
assert.strictEqual(group1Events.moved[0].editor, input1group1);
|
||||
assert.strictEqual(group1Events.moved[0].index, 0);
|
||||
assert.strictEqual(group1Events.moved[0].newIndex, 1);
|
||||
|
||||
group2.moveEditor(input1group2, 1);
|
||||
assert.strictEqual(group2Events.moved[0].editor, input1group2);
|
||||
assert.strictEqual(group2Events.moved[0].index, 0);
|
||||
assert.strictEqual(group2Events.moved[0].newIndex, 1);
|
||||
});
|
||||
|
||||
test('onDidOpeneditor Event', () => {
|
||||
const group1 = createEditorGroupModel();
|
||||
const group2 = createEditorGroupModel();
|
||||
|
||||
const group1Events = groupListener(group1);
|
||||
const group2Events = groupListener(group2);
|
||||
|
||||
const input1group1 = input();
|
||||
const input2group1 = input();
|
||||
const input1group2 = input();
|
||||
const input2group2 = input();
|
||||
|
||||
// Open all the editors
|
||||
group1.openEditor(input1group1, { pinned: true, active: true, index: 0 });
|
||||
group1.openEditor(input2group1, { pinned: true, active: false, index: 1 });
|
||||
group2.openEditor(input1group2, { pinned: true, active: true, index: 0 });
|
||||
group2.openEditor(input2group2, { pinned: true, active: false, index: 1 });
|
||||
|
||||
assert.strictEqual(group1Events.opened.length, 2);
|
||||
assert.strictEqual(group1Events.opened[0].editor, input1group1);
|
||||
assert.strictEqual(group1Events.opened[0].index, 0);
|
||||
assert.strictEqual(group1Events.opened[1].editor, input2group1);
|
||||
assert.strictEqual(group1Events.opened[1].index, 1);
|
||||
|
||||
assert.strictEqual(group2Events.opened.length, 2);
|
||||
assert.strictEqual(group2Events.opened[0].editor, input1group2);
|
||||
assert.strictEqual(group2Events.opened[0].index, 0);
|
||||
assert.strictEqual(group2Events.opened[1].editor, input2group2);
|
||||
assert.strictEqual(group2Events.opened[1].index, 1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri';
|
|||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { IEditorInputWithOptions, IEditorIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorPane, IEditorCloseEvent, IEditorPartOptions, IRevertOptions, GroupIdentifier, EditorsOrder, IFileEditorInput, IEditorFactoryRegistry, IEditorSerializer, EditorExtensions, ISaveOptions, IMoveResult, ITextDiffEditorPane, IVisibleEditorPane, IEditorOpenContext, IEditorMoveEvent, EditorExtensions as Extensions, EditorInputCapabilities, IEditorOpenEvent, IUntypedEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IEditorInputWithOptions, IEditorIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorPane, IEditorCloseEvent, IEditorPartOptions, IRevertOptions, GroupIdentifier, EditorsOrder, IFileEditorInput, IEditorFactoryRegistry, IEditorSerializer, EditorExtensions, ISaveOptions, IMoveResult, ITextDiffEditorPane, IVisibleEditorPane, IEditorOpenContext, IEditorMoveEvent, EditorExtensions as Extensions, EditorInputCapabilities, IEditorOpenEvent, IUntypedEditorInput, IEditorsChangeEvent } from 'vs/workbench/common/editor';
|
||||
import { EditorServiceImpl, IEditorGroupView, IEditorGroupsAccessor, IEditorGroupTitleHeight } from 'vs/workbench/browser/parts/editor/editor';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IResolvedWorkingCopyBackup, IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/common/workingCopyBackup';
|
||||
|
@ -805,7 +805,7 @@ export class TestEditorService implements EditorServiceImpl {
|
|||
|
||||
onDidActiveEditorChange: Event<void> = Event.None;
|
||||
onDidVisibleEditorsChange: Event<void> = Event.None;
|
||||
onDidEditorsChange: Event<void> = Event.None;
|
||||
onDidEditorsChange: Event<IEditorsChangeEvent[]> = Event.None;
|
||||
onDidCloseEditor: Event<IEditorCloseEvent> = Event.None;
|
||||
onDidOpenEditorFail: Event<IEditorIdentifier> = Event.None;
|
||||
onDidMostRecentlyActiveEditorsChange: Event<void> = Event.None;
|
||||
|
|
Loading…
Reference in a new issue