Compare commits

...

20 commits

Author SHA1 Message Date
Logan Ramos 6ce7f83df2
Merge branch 'main' into lramos15/modelEvent 2021-11-24 14:25:55 -05:00
Benjamin Pasero ffb24d1410
fix reexport issue 2021-11-24 13:58:32 +01:00
Benjamin Pasero 900ab0d01c
clean up events 2021-11-24 13:53:03 +01:00
Benjamin Pasero da6123dfa1
simplify events 2021-11-24 11:59:29 +01:00
Benjamin Pasero eaba92f5a1
further avoid types 2021-11-24 11:38:43 +01:00
Benjamin Pasero 84cdf9f9f9
avoid IEditorCloseEvent 2021-11-24 11:30:54 +01:00
Benjamin Pasero e93ffebdf4
one more 2021-11-24 11:16:59 +01:00
Benjamin Pasero bfc916ade3
editors - for now keep `GroupChangeKind' accessible via groups service 2021-11-24 11:15:46 +01:00
Logan Ramos 04ca7c7589
Merge branch 'main' into lramos15/modelEvent 2021-11-23 13:58:57 -05:00
Logan Ramos 4657621129
Address comments 2021-11-23 13:52:00 -05:00
Logan Ramos f8e8f76611
Move group change to belong to the model 2021-11-23 13:47:10 -05:00
Logan Ramos 72e66332eb
Merge branch 'main' into lramos15/modelEvent 2021-11-22 13:17:43 -05:00
Logan Ramos 200755ff64
Merge branch 'main' into lramos15/modelEvent 2021-11-17 16:42:46 -05:00
Logan Ramos 6e42bf706e
Introduce an onDidModelChange 2021-11-17 15:16:49 -05:00
Logan Ramos c37587ee2d
Switch to using GroupChange event 2021-11-17 13:59:46 -05:00
Logan Ramos 70c528430e
Merge branch 'main' into lramos15/modelEvent 2021-11-17 10:16:47 -05:00
Logan Ramos 3b203b53d4
Use GroupChangeKind instead 2021-11-11 15:15:28 -05:00
Logan Ramos 22218e385d
Switch to aggregate model events 2021-11-11 13:04:46 -05:00
Logan Ramos 816dc4c28e
Merge branch 'main' into lramos15/modelEvent 2021-11-11 11:00:39 -05:00
Logan Ramos 351162ef3a
Add aggregate model event 2021-11-09 15:20:55 -05:00
14 changed files with 374 additions and 180 deletions

View file

@ -7,12 +7,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, IUntypedEditorInput, SideBySideEditor } from 'vs/workbench/common/editor';
import { EditorResourceAccessor, IUntypedEditorInput, SideBySideEditor, GroupChangeKind } from 'vs/workbench/common/editor';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { isGroupEditorCloseEvent, isGroupEditorMoveEvent, isGroupEditorOpenEvent } from 'vs/workbench/common/editor/editorGroupModel';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
import { columnToEditorGroup, EditorGroupColumn, editorGroupToColumn } from 'vs/workbench/services/editor/common/editorGroupColumn';
import { GroupChangeKind, GroupDirection, IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { GroupDirection, IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorsChangeEvent, IEditorService } from 'vs/workbench/services/editor/common/editorService';
@ -105,7 +106,7 @@ export class MainThreadEditorTabs {
}
private _onDidTabOpen(event: IEditorsChangeEvent): void {
if (event.kind !== GroupChangeKind.EDITOR_OPEN || !event.editor || event.editorIndex === undefined) {
if (!isGroupEditorOpenEvent(event)) {
return;
}
if (!this._tabModel.has(event.groupId)) {
@ -124,7 +125,7 @@ export class MainThreadEditorTabs {
}
private _onDidTabClose(event: IEditorsChangeEvent): void {
if (event.kind !== GroupChangeKind.EDITOR_CLOSE || event.editorIndex === undefined) {
if (!isGroupEditorCloseEvent(event)) {
return;
}
this._tabModel.get(event.groupId)?.splice(event.editorIndex, 1);
@ -137,7 +138,7 @@ export class MainThreadEditorTabs {
}
private _onDidTabMove(event: IEditorsChangeEvent): void {
if (event.kind !== GroupChangeKind.EDITOR_MOVE || event.editorIndex === undefined || event.oldEditorIndex === undefined) {
if (!isGroupEditorMoveEvent(event)) {
return;
}
const movedTab = this._tabModel.get(event.groupId)?.splice(event.oldEditorIndex, 1);

View file

@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/editorgroupview';
import { EditorGroupModel, IEditorOpenOptions, ISerializedEditorGroupModel, isSerializedEditorGroupModel } 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, IEditorWillMoveEvent, IEditorWillOpenEvent } from 'vs/workbench/common/editor';
import { EditorGroupModel, IEditorOpenOptions, IGroupChangeEvent, IGroupEditorCloseEvent, IGroupEditorMoveEvent, IGroupEditorOpenEvent, ISerializedEditorGroupModel, isGroupEditorCloseEvent, isGroupEditorMoveEvent, isGroupEditorOpenEvent, isSerializedEditorGroupModel } from 'vs/workbench/common/editor/editorGroupModel';
import { GroupIdentifier, CloseDirection, IEditorCloseEvent, ActiveEditorDirtyContext, IEditorPane, EditorGroupEditorsCountContext, SaveReason, IEditorPartOptionsChangeEvent, EditorsOrder, IVisibleEditorPane, ActiveEditorStickyContext, ActiveEditorPinnedContext, EditorResourceAccessor, EditorInputCapabilities, IUntypedEditorInput, DEFAULT_EDITOR_ASSOCIATION, ActiveEditorGroupLockedContext, SideBySideEditor, EditorCloseContext, IEditorWillMoveEvent, IEditorWillOpenEvent, GroupChangeKind } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
import { Event, Emitter, Relay } from 'vs/base/common/event';
@ -18,7 +18,7 @@ import { attachProgressBarStyler } from 'vs/platform/theme/common/styler';
import { IThemeService, registerThemingParticipant, Themable } from 'vs/platform/theme/common/themeService';
import { editorBackground, contrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { EDITOR_GROUP_HEADER_TABS_BACKGROUND, EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND, EDITOR_GROUP_EMPTY_BACKGROUND, EDITOR_GROUP_FOCUSED_EMPTY_BORDER, EDITOR_GROUP_HEADER_BORDER } from 'vs/workbench/common/theme';
import { ICloseEditorsFilter, IGroupChangeEvent, GroupChangeKind, GroupsOrder, ICloseEditorOptions, ICloseAllEditorsOptions, IEditorReplacement } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ICloseEditorsFilter, GroupsOrder, ICloseEditorOptions, ICloseAllEditorsOptions, IEditorReplacement } from 'vs/workbench/services/editor/common/editorGroupsService';
import { TabsTitleControl } from 'vs/workbench/browser/parts/editor/tabsTitleControl';
import { EditorPanes } from 'vs/workbench/browser/parts/editor/editorPanes';
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
@ -90,6 +90,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
private readonly _onDidGroupChange = this._register(new Emitter<IGroupChangeEvent>());
readonly onDidGroupChange = this._onDidGroupChange.event;
private readonly _onDidModelChange = this._register(new Emitter<IGroupChangeEvent>());
readonly onDidModelChange = this._onDidModelChange.event;
private readonly _onDidOpenEditorFail = this._register(new Emitter<EditorInput>());
readonly onDidOpenEditorFail = this._onDidOpenEditorFail.event;
@ -523,16 +526,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
private registerListeners(): void {
// Model Events
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)));
this._register(this.model.onDidChangeEditorDirty(editor => this.onDidChangeEditorDirty(editor)));
this._register(this.model.onDidChangeEditorLabel(editor => this.onDidChangeEditorLabel(editor)));
this._register(this.model.onDidChangeEditorCapabilities(editor => this.onDidChangeEditorCapabilities(editor)));
this._register(this.model.onDidModelChange(e => this.onDidGroupModelChange(e)));
// Option Changes
this._register(this.accessor.onDidChangeEditorPartOptions(e => this.onDidChangeEditorPartOptions(e)));
@ -541,6 +535,59 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
this._register(this.accessor.onDidVisibilityChange(e => this.onDidVisibilityChange(e)));
}
private onDidGroupModelChange(e: IGroupChangeEvent): void {
// Re-emit to outside
this._onDidModelChange.fire(e);
// Handle within
if (e.kind === GroupChangeKind.GROUP_LOCKED) {
this.onDidChangeGroupLocked();
return;
}
if (!e.editor) {
return;
}
switch (e.kind) {
case GroupChangeKind.EDITOR_PIN:
this.onDidChangeEditorPinned(e.editor);
break;
case GroupChangeKind.EDITOR_STICKY:
this.onDidChangeEditorSticky(e.editor);
break;
case GroupChangeKind.EDITOR_MOVE:
if (isGroupEditorMoveEvent(e)) {
this.onDidMoveEditor(e.editor, e.oldEditorIndex, e.editorIndex);
}
break;
case GroupChangeKind.EDITOR_OPEN:
if (isGroupEditorOpenEvent(e)) {
this.onDidOpenEditor(e.editor, e.editorIndex);
}
break;
case GroupChangeKind.EDITOR_CLOSE:
if (isGroupEditorCloseEvent(e)) {
this.handleOnDidCloseEditor(e.editor, e.editorIndex, e.context, e.sticky);
}
break;
case GroupChangeKind.EDITOR_WILL_DISPOSE:
this.onWillDisposeEditor(e.editor);
break;
case GroupChangeKind.EDITOR_DIRTY:
this.onDidChangeEditorDirty(e.editor);
break;
case GroupChangeKind.EDITOR_LABEL:
this.onDidChangeEditorLabel(e.editor);
break;
case GroupChangeKind.EDITOR_CAPABILITIES:
this.onDidChangeEditorCapabilities(e.editor);
break;
}
}
private onDidChangeGroupLocked(): void {
this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_LOCKED });
}
@ -553,11 +600,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_STICKY, editor });
}
private onDidMoveEditor({ editor, index, newIndex }: IEditorMoveEvent): void {
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_MOVE, editor, oldEditorIndex: index, editorIndex: newIndex });
private onDidMoveEditor(editor: EditorInput, oldEditorIndex: number, editorIndex: number): void {
const event: IGroupEditorMoveEvent = { kind: GroupChangeKind.EDITOR_MOVE, editor, oldEditorIndex, editorIndex };
this._onDidGroupChange.fire(event);
}
private onDidOpenEditor({ editor, index }: IEditorOpenEvent): void {
private onDidOpenEditor(editor: EditorInput, editorIndex: number): void {
/* __GDPR__
"editorOpened" : {
@ -572,16 +620,16 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
this.updateContainer();
// Event
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_OPEN, editor, editorIndex: index });
const event: IGroupEditorOpenEvent = { kind: GroupChangeKind.EDITOR_OPEN, editor, editorIndex };
this._onDidGroupChange.fire(event);
}
private handleOnDidCloseEditor(event: IEditorCloseEvent): void {
private handleOnDidCloseEditor(editor: EditorInput, editorIndex: number, context: EditorCloseContext, sticky: boolean): void {
// Before close
this._onWillCloseEditor.fire(event);
this._onWillCloseEditor.fire({ groupId: this.id, editor, context, index: editorIndex, sticky });
// Handle event
const editor = event.editor;
const editorsToClose: EditorInput[] = [editor];
// Include both sides of side by side editors when being closed
@ -606,14 +654,15 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
]
}
*/
this.telemetryService.publicLog('editorClosed', this.toEditorTelemetryDescriptor(event.editor));
this.telemetryService.publicLog('editorClosed', this.toEditorTelemetryDescriptor(editor));
// Update container
this.updateContainer();
// Event
this._onDidCloseEditor.fire(event);
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_CLOSE, editor, editorIndex: event.index });
this._onDidCloseEditor.fire({ groupId: this.id, editor, context, index: editorIndex, sticky });
const event: IGroupEditorCloseEvent = { kind: GroupChangeKind.EDITOR_CLOSE, editor, editorIndex, context, sticky };
this._onDidGroupChange.fire(event);
}
private canDispose(editor: EditorInput): boolean {
@ -794,6 +843,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
if (this._index !== newIndex) {
this._index = newIndex;
this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_INDEX });
// TODO @lramos15 ENRICH THE MODEL TO LEARN ABOUT INDEX CHANGES THIS IS A HACK
this._onDidModelChange.fire({ kind: GroupChangeKind.GROUP_INDEX });
}
}
@ -1439,7 +1490,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
// Update model
let index: number | undefined = undefined;
if (editorToClose) {
index = this.model.closeEditor(editorToClose, internalOptions?.context)?.index;
index = this.model.closeEditor(editorToClose, internalOptions?.context)?.editorIndex;
}
// Open next active if there are more to show
@ -1509,7 +1560,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
private doCloseInactiveEditor(editor: EditorInput, internalOptions?: IInternalEditorCloseOptions): number | undefined {
// Update model
return this.model.closeEditor(editor, internalOptions?.context)?.index;
return this.model.closeEditor(editor, internalOptions?.context)?.editorIndex;
}
private async handleDirtyClosing(editors: EditorInput[]): Promise<boolean /* veto */> {

View file

@ -8,10 +8,10 @@ import { Part } from 'vs/workbench/browser/part';
import { Dimension, isAncestor, $, EventHelper, addDisposableGenericMouseDownListner } from 'vs/base/browser/dom';
import { Event, Emitter, Relay } from 'vs/base/common/event';
import { contrastBorder, editorBackground } from 'vs/platform/theme/common/colorRegistry';
import { GroupDirection, IAddGroupOptions, GroupsArrangement, GroupOrientation, IMergeGroupOptions, MergeGroupMode, GroupsOrder, GroupChangeKind, GroupLocation, IFindGroupScope, EditorGroupLayout, GroupLayoutArgument, IEditorGroupsService, IEditorSideGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { GroupDirection, IAddGroupOptions, GroupsArrangement, GroupOrientation, IMergeGroupOptions, MergeGroupMode, GroupsOrder, GroupLocation, IFindGroupScope, EditorGroupLayout, GroupLayoutArgument, IEditorGroupsService, IEditorSideGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IView, orthogonal, LayoutPriority, IViewSize, Direction, SerializableGrid, Sizing, ISerializedGrid, Orientation, GridBranchNode, isGridBranchNode, GridNode, createSerializedGrid, Grid } from 'vs/base/browser/ui/grid/grid';
import { GroupIdentifier, EditorInputWithOptions, IEditorPartOptions, IEditorPartOptionsChangeEvent } from 'vs/workbench/common/editor';
import { GroupIdentifier, EditorInputWithOptions, IEditorPartOptions, IEditorPartOptionsChangeEvent, GroupChangeKind } from 'vs/workbench/common/editor';
import { EDITOR_GROUP_BORDER, EDITOR_PANE_BACKGROUND } from 'vs/workbench/common/theme';
import { distinct, coalesce, firstOrDefault } from 'vs/base/common/arrays';
import { IEditorGroupsAccessor, IEditorGroupView, getEditorPartOptions, impactsEditorPartOptions, IEditorPartCreationOptions } from 'vs/workbench/browser/parts/editor/editor';

View file

@ -3,14 +3,14 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IEditorFactoryRegistry, IEditorIdentifier, GroupIdentifier, EditorExtensions, IEditorPartOptionsChangeEvent, EditorsOrder } from 'vs/workbench/common/editor';
import { IEditorFactoryRegistry, IEditorIdentifier, GroupIdentifier, EditorExtensions, IEditorPartOptionsChangeEvent, EditorsOrder, GroupChangeKind } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
import { dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { Registry } from 'vs/platform/registry/common/platform';
import { Event, Emitter } from 'vs/base/common/event';
import { IEditorGroupsService, IEditorGroup, GroupChangeKind, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorGroupsService, IEditorGroup, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
import { coalesce } from 'vs/base/common/arrays';
import { LinkedMap, Touch, ResourceMap } from 'vs/base/common/map';
import { equals } from 'vs/base/common/objects';

View file

@ -823,6 +823,26 @@ export interface IEditorOpenEvent extends IEditorIdentifier {
export type GroupIdentifier = number;
export const enum GroupChangeKind {
/* Group Changes */
GROUP_ACTIVE,
GROUP_INDEX,
GROUP_LOCKED,
/* Editor Changes */
EDITOR_OPEN,
EDITOR_CLOSE,
EDITOR_MOVE,
EDITOR_ACTIVE,
EDITOR_LABEL,
EDITOR_CAPABILITIES,
EDITOR_PIN,
EDITOR_STICKY,
EDITOR_DIRTY,
EDITOR_WILL_DISPOSE
}
export interface IWorkbenchEditorConfiguration {
workbench?: {
editor?: IEditorPartConfiguration,

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Event, Emitter } from 'vs/base/common/event';
import { IEditorFactoryRegistry, GroupIdentifier, EditorsOrder, EditorExtensions, IUntypedEditorInput, SideBySideEditor, IEditorMoveEvent, IEditorOpenEvent, EditorCloseContext, IEditorCloseEvent } from 'vs/workbench/common/editor';
import { IEditorFactoryRegistry, GroupIdentifier, EditorsOrder, EditorExtensions, IUntypedEditorInput, SideBySideEditor, EditorCloseContext, GroupChangeKind } 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';
@ -60,14 +60,108 @@ export interface IMatchOptions {
* By default, side by side editors will not be considered
* as matching, even if the editor is opened in one of the sides.
*/
supportSideBySide?: SideBySideEditor.ANY | SideBySideEditor.BOTH;
readonly supportSideBySide?: SideBySideEditor.ANY | SideBySideEditor.BOTH;
/**
* Only consider an editor to match when the
* `candidate === editor` but not when
* `candidate.matches(editor)`.
*/
strictEquals?: boolean;
readonly strictEquals?: boolean;
}
export interface IGroupChangeEvent {
/**
* The kind of change that occured in the group.
*/
readonly kind: GroupChangeKind;
/**
* Only applies when editors change providing
* access to the editor the event is about.
*/
readonly editor?: EditorInput;
}
export interface IGroupEditorChangeEvent extends IGroupChangeEvent {
readonly editor: EditorInput;
}
export interface IGroupEditorOpenEvent extends IGroupEditorChangeEvent {
readonly kind: GroupChangeKind.EDITOR_OPEN;
/**
* Identifies the index of the editor in the group.
*/
readonly editorIndex: number;
}
export function isGroupEditorOpenEvent(e: IGroupChangeEvent): e is IGroupEditorOpenEvent {
const candidate = e as IGroupEditorOpenEvent;
return candidate.kind === GroupChangeKind.EDITOR_OPEN && candidate.editorIndex !== undefined;
}
export interface IGroupEditorMoveEvent extends IGroupEditorChangeEvent {
readonly kind: GroupChangeKind.EDITOR_MOVE;
/**
* Identifies the index of the editor in the group.
*/
readonly editorIndex: number;
/**
* Signifies the index the editor is moving from.
* `editorIndex` will contain the index the editor
* is moving to.
*/
readonly oldEditorIndex: number;
}
export function isGroupEditorMoveEvent(e: IGroupChangeEvent): e is IGroupEditorMoveEvent {
const candidate = e as IGroupEditorMoveEvent;
return candidate.kind === GroupChangeKind.EDITOR_MOVE && candidate.editorIndex !== undefined && candidate.oldEditorIndex !== undefined;
}
export interface IGroupEditorCloseEvent extends IGroupEditorChangeEvent {
readonly kind: GroupChangeKind.EDITOR_CLOSE;
/**
* Identifies the index of the editor in the group.
*/
readonly editorIndex: number;
/**
* Signifies the context in which the editor
* is being closed. This allows for understanding
* if a replace or reopen is occuring
*/
readonly context: EditorCloseContext;
/**
* Signifies whether or not the closed editor was
* sticky. This is necessary becasue state is lost
* after closing.
*/
readonly sticky: boolean;
}
export function isGroupEditorCloseEvent(e: IGroupChangeEvent): e is IGroupEditorCloseEvent {
const candidate = e as IGroupEditorCloseEvent;
return candidate.kind === GroupChangeKind.EDITOR_CLOSE && candidate.editorIndex !== undefined && candidate.context !== undefined && candidate.sticky !== undefined;
}
interface IEditorCloseResult {
readonly editor: EditorInput;
readonly context: EditorCloseContext;
readonly editorIndex: number;
readonly sticky: boolean;
}
export class EditorGroupModel extends Disposable {
@ -76,38 +170,8 @@ export class EditorGroupModel extends Disposable {
//#region events
private readonly _onDidChangeLocked = this._register(new Emitter<void>());
readonly onDidChangeLocked = this._onDidChangeLocked.event;
private readonly _onDidActivateEditor = this._register(new Emitter<EditorInput>());
readonly onDidActivateEditor = this._onDidActivateEditor.event;
private readonly _onDidOpenEditor = this._register(new Emitter<IEditorOpenEvent>());
readonly onDidOpenEditor = this._onDidOpenEditor.event;
private readonly _onDidCloseEditor = this._register(new Emitter<IEditorCloseEvent>());
readonly onDidCloseEditor = this._onDidCloseEditor.event;
private readonly _onWillDisposeEditor = this._register(new Emitter<EditorInput>());
readonly onWillDisposeEditor = this._onWillDisposeEditor.event;
private readonly _onDidChangeEditorDirty = this._register(new Emitter<EditorInput>());
readonly onDidChangeEditorDirty = this._onDidChangeEditorDirty.event;
private readonly _onDidChangeEditorLabel = this._register(new Emitter<EditorInput>());
readonly onDidChangeEditorLabel = this._onDidChangeEditorLabel.event;
private readonly _onDidChangeEditorCapabilities = this._register(new Emitter<EditorInput>());
readonly onDidChangeEditorCapabilities = this._onDidChangeEditorCapabilities.event;
private readonly _onDidMoveEditor = this._register(new Emitter<IEditorMoveEvent>());
readonly onDidMoveEditor = this._onDidMoveEditor.event;
private readonly _onDidChangeEditorPinned = this._register(new Emitter<EditorInput>());
readonly onDidChangeEditorPinned = this._onDidChangeEditorPinned.event;
private readonly _onDidChangeEditorSticky = this._register(new Emitter<EditorInput>());
readonly onDidChangeEditorSticky = this._onDidChangeEditorSticky.event;
private readonly _onDidModelChange = this._register(new Emitter<IGroupChangeEvent>());
readonly onDidModelChange = this._onDidModelChange.event;
//#endregion
@ -286,7 +350,12 @@ export class EditorGroupModel extends Disposable {
this.registerEditorListeners(newEditor);
// Event
this._onDidOpenEditor.fire({ editor: newEditor, groupId: this.id, index: targetIndex });
const event: IGroupEditorOpenEvent = {
kind: GroupChangeKind.EDITOR_OPEN,
editor: newEditor,
editorIndex: targetIndex
};
this._onDidModelChange.fire(event);
// Handle active
if (makeActive) {
@ -337,59 +406,79 @@ export class EditorGroupModel extends Disposable {
// Re-emit disposal of editor input as our own event
listeners.add(Event.once(editor.onWillDispose)(() => {
if (this.indexOf(editor) >= 0) {
this._onWillDisposeEditor.fire(editor);
this._onDidModelChange.fire({
kind: GroupChangeKind.EDITOR_WILL_DISPOSE,
editor
});
}
}));
// Re-Emit dirty state changes
listeners.add(editor.onDidChangeDirty(() => {
this._onDidChangeEditorDirty.fire(editor);
this._onDidModelChange.fire({
kind: GroupChangeKind.EDITOR_DIRTY,
editor
});
}));
// Re-Emit label changes
listeners.add(editor.onDidChangeLabel(() => {
this._onDidChangeEditorLabel.fire(editor);
this._onDidModelChange.fire({
kind: GroupChangeKind.EDITOR_LABEL,
editor
});
}));
// Re-Emit capability changes
listeners.add(editor.onDidChangeCapabilities(() => {
this._onDidChangeEditorCapabilities.fire(editor);
this._onDidModelChange.fire({
kind: GroupChangeKind.EDITOR_CAPABILITIES,
editor
});
}));
// Clean up dispose listeners once the editor gets closed
listeners.add(this.onDidCloseEditor(event => {
if (event.editor.matches(editor)) {
listeners.add(this.onDidModelChange(event => {
if (event.kind === GroupChangeKind.EDITOR_CLOSE && event.editor?.matches(editor)) {
dispose(listeners);
}
}));
}
private replaceEditor(toReplace: EditorInput, replaceWith: EditorInput, replaceIndex: number, openNext = true): void {
const event = this.doCloseEditor(toReplace, EditorCloseContext.REPLACE, openNext); // optimization to prevent multiple setActive() in one call
const closeResult = this.doCloseEditor(toReplace, EditorCloseContext.REPLACE, openNext); // optimization to prevent multiple setActive() in one call
// We want to first add the new editor into our model before emitting the close event because
// firing the close event can trigger a dispose on the same editor that is now being added.
// This can lead into opening a disposed editor which is not what we want.
this.splice(replaceIndex, false, replaceWith);
if (event) {
this._onDidCloseEditor.fire(event);
if (closeResult) {
const event: IGroupEditorCloseEvent = {
kind: GroupChangeKind.EDITOR_CLOSE,
...closeResult
};
this._onDidModelChange.fire(event);
}
}
closeEditor(candidate: EditorInput, context = EditorCloseContext.UNKNOWN, openNext = true): IEditorCloseEvent | undefined {
const event = this.doCloseEditor(candidate, context, openNext);
closeEditor(candidate: EditorInput, context = EditorCloseContext.UNKNOWN, openNext = true): IEditorCloseResult | undefined {
const closeResult = this.doCloseEditor(candidate, context, openNext);
if (event) {
this._onDidCloseEditor.fire(event);
if (closeResult) {
const event: IGroupEditorCloseEvent = {
kind: GroupChangeKind.EDITOR_CLOSE,
...closeResult
};
this._onDidModelChange.fire(event);
return event;
return closeResult;
}
return undefined;
}
private doCloseEditor(candidate: EditorInput, context: EditorCloseContext, openNext: boolean): IEditorCloseEvent | undefined {
private doCloseEditor(candidate: EditorInput, context: EditorCloseContext, openNext: boolean): IEditorCloseResult | undefined {
const index = this.indexOf(candidate);
if (index === -1) {
return undefined; // not found
@ -432,7 +521,7 @@ export class EditorGroupModel extends Disposable {
this.splice(index, true);
// Event
return { editor, sticky, index, groupId: this.id, context };
return { editor, sticky, editorIndex: index, context };
}
moveEditor(candidate: EditorInput, toIndex: number): EditorInput | undefined {
@ -466,7 +555,13 @@ export class EditorGroupModel extends Disposable {
this.editors.splice(toIndex, 0, editor);
// Event
this._onDidMoveEditor.fire({ editor, groupId: this.id, index, newIndex: toIndex, target: this.id });
const event: IGroupEditorMoveEvent = {
kind: GroupChangeKind.EDITOR_MOVE,
editor,
oldEditorIndex: index,
editorIndex: toIndex,
};
this._onDidModelChange.fire(event);
return editor;
}
@ -497,7 +592,10 @@ export class EditorGroupModel extends Disposable {
this.mru.unshift(editor);
// Event
this._onDidActivateEditor.fire(editor);
this._onDidModelChange.fire({
kind: GroupChangeKind.EDITOR_ACTIVE,
editor
});
}
pin(candidate: EditorInput): EditorInput | undefined {
@ -522,7 +620,10 @@ export class EditorGroupModel extends Disposable {
this.preview = null;
// Event
this._onDidChangeEditorPinned.fire(editor);
this._onDidModelChange.fire({
kind: GroupChangeKind.EDITOR_PIN,
editor
});
}
unpin(candidate: EditorInput): EditorInput | undefined {
@ -548,7 +649,10 @@ export class EditorGroupModel extends Disposable {
this.preview = editor;
// Event
this._onDidChangeEditorPinned.fire(editor);
this._onDidModelChange.fire({
kind: GroupChangeKind.EDITOR_PIN,
editor
});
// Close old preview editor if any
if (oldPreview) {
@ -595,7 +699,10 @@ export class EditorGroupModel extends Disposable {
this.sticky++;
// Event
this._onDidChangeEditorSticky.fire(editor);
this._onDidModelChange.fire({
kind: GroupChangeKind.EDITOR_STICKY,
editor
});
}
unstick(candidate: EditorInput): EditorInput | undefined {
@ -623,7 +730,10 @@ export class EditorGroupModel extends Disposable {
this.sticky--;
// Event
this._onDidChangeEditorSticky.fire(editor);
this._onDidModelChange.fire({
kind: GroupChangeKind.EDITOR_STICKY,
editor
});
}
isSticky(candidateOrIndex: EditorInput | number): boolean {
@ -774,7 +884,7 @@ export class EditorGroupModel extends Disposable {
if (this.isLocked !== locked) {
this.locked = locked;
this._onDidChangeLocked.fire();
this._onDidModelChange.fire({ kind: GroupChangeKind.GROUP_LOCKED });
}
}

View file

@ -10,10 +10,10 @@ import { IAction, ActionRunner, WorkbenchActionExecutedEvent, WorkbenchActionExe
import * as dom from 'vs/base/browser/dom';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IEditorGroupsService, IEditorGroup, GroupChangeKind, GroupsOrder, GroupOrientation } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupOrientation } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { Verbosity, EditorResourceAccessor, SideBySideEditor, EditorInputCapabilities, IEditorIdentifier } from 'vs/workbench/common/editor';
import { Verbosity, EditorResourceAccessor, SideBySideEditor, EditorInputCapabilities, IEditorIdentifier, GroupChangeKind } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { SaveAllInGroupAction, CloseGroupAction } from 'vs/workbench/contrib/files/browser/fileActions';
import { OpenEditorsFocusedContext, ExplorerFocusedContext, IFilesConfiguration, OpenEditor } from 'vs/workbench/contrib/files/common/files';

View file

@ -6,14 +6,14 @@
import { ResourceMap } from 'vs/base/common/map';
import { getDefaultNotebookCreationOptions, NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidget';
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { IEditorGroupsService, IEditorGroup, GroupChangeKind } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { isCompositeNotebookEditorInput, NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
import { IBorrowValue, INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService';
import { INotebookEditor, INotebookEditorCreationOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { Emitter } from 'vs/base/common/event';
import { INotebookDecorationRenderOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { GroupIdentifier } from 'vs/workbench/common/editor';
import { GroupIdentifier, GroupChangeKind } from 'vs/workbench/common/editor';
export class NotebookEditorWidgetService implements INotebookEditorService {

View file

@ -5,7 +5,7 @@
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, EditorInputWithOptions, 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, EditorInputWithOptions, isEditorInputWithOptions, IEditorIdentifier, IEditorCloseEvent, ITextDiffEditorPane, IRevertOptions, SaveReason, EditorsOrder, IWorkbenchEditorConfiguration, EditorResourceAccessor, IVisibleEditorPane, EditorInputCapabilities, isResourceDiffEditorInput, IUntypedEditorInput, isResourceEditorInput, isEditorInput, isEditorInputWithOptionsAndGroup, GroupChangeKind } 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';
@ -14,7 +14,7 @@ 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';
import { IEditorGroupsService, IEditorGroup, GroupsOrder, IEditorReplacement, GroupChangeKind, isEditorReplacement } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorGroupsService, IEditorGroup, GroupsOrder, IEditorReplacement, isEditorReplacement } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IUntypedEditorReplacement, IEditorService, ISaveEditorsOptions, ISaveAllEditorsOptions, IRevertAllEditorsOptions, IBaseSaveRevertAllEditorOptions, IOpenEditorsOptions, PreferredGroup, isPreferredGroup, IEditorsChangeEvent } from 'vs/workbench/services/editor/common/editorService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { Disposable, IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
@ -147,14 +147,12 @@ export class EditorService extends Disposable implements EditorServiceImpl {
private registerGroupListeners(group: IEditorGroupView): void {
const groupDisposables = new DisposableStore();
groupDisposables.add(group.onDidGroupChange(e => {
groupDisposables.add(group.onDidModelChange(e => {
switch (e.kind) {
case GroupChangeKind.EDITOR_ACTIVE:
if (group.activeEditor) {
this._onDidEditorsChange.fire([{ groupId: group.id, editor: group.activeEditor, kind: GroupChangeKind.EDITOR_ACTIVE }]);
}
this.handleActiveEditorChange(group);
this._onDidVisibleEditorsChange.fire();
break;
default:
this._onDidEditorsChange.fire([{ groupId: group.id, ...e }]);
@ -162,6 +160,15 @@ export class EditorService extends Disposable implements EditorServiceImpl {
}
}));
// Need to separatly listen to the group change for things like active editor changing
// as this doesn't always change the model (This could be a bug that needs more investigation)
groupDisposables.add(group.onDidGroupChange(e => {
if (e.kind === GroupChangeKind.EDITOR_ACTIVE) {
this.handleActiveEditorChange(group);
this._onDidVisibleEditorsChange.fire();
}
}));
groupDisposables.add(group.onDidCloseEditor(event => {
this._onDidCloseEditor.fire(event);
}));

View file

@ -13,6 +13,7 @@ import { IDimension } from 'vs/editor/common/editorCommon';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { URI } from 'vs/base/common/uri';
import { IGroupChangeEvent } from 'vs/workbench/common/editor/editorGroupModel';
export const IEditorGroupsService = createDecorator<IEditorGroupsService>('editorGroupsService');
@ -395,53 +396,6 @@ export interface IEditorGroupsService {
enforcePartOptions(options: IEditorPartOptions): IDisposable;
}
export const enum GroupChangeKind {
/* Group Changes */
GROUP_ACTIVE,
GROUP_INDEX,
GROUP_LOCKED,
/* Editor Changes */
EDITOR_OPEN,
EDITOR_CLOSE,
EDITOR_MOVE,
EDITOR_ACTIVE,
EDITOR_LABEL,
EDITOR_CAPABILITIES,
EDITOR_PIN,
EDITOR_STICKY,
EDITOR_DIRTY
}
export interface IGroupChangeEvent {
/**
* The kind of change that occured in the group.
*/
kind: GroupChangeKind;
/**
* Only applies when editors change providing
* access to the editor the event is about.
*/
editor?: EditorInput;
/**
* Only applies when an editor opens, closes
* or is moved. Identifies the index of the
* editor in the group.
*/
editorIndex?: number;
/**
* For `EDITOR_MOVE` only: Signifies the index the
* editor is moving from. `editorIndex` will contain
* the index the editor is moving to.
*/
oldEditorIndex?: number;
}
export const enum OpenEditorContext {
NEW_EDITOR = 1,
MOVE_EDITOR = 2,
@ -455,6 +409,11 @@ export interface IEditorGroup {
*/
readonly onDidGroupChange: Event<IGroupChangeEvent>;
/**
* An event which fires whenever the underlying group model changes.
*/
readonly onDidModelChange: Event<IGroupChangeEvent>;
/**
* An event that is fired when the group gets disposed.
*/

View file

@ -9,8 +9,9 @@ import { IEditorPane, GroupIdentifier, IUntitledTextResourceEditorInput, IResour
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { Event } from 'vs/base/common/event';
import { IEditor, IDiffEditor } from 'vs/editor/common/editorCommon';
import { IEditorGroup, IEditorReplacement, IGroupChangeEvent, isEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorGroup, IEditorReplacement, isEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { URI } from 'vs/base/common/uri';
import { IGroupChangeEvent } from 'vs/workbench/common/editor/editorGroupModel';
export const IEditorService = createDecorator<IEditorService>('editorService');

View file

@ -5,8 +5,8 @@
import * as assert from 'assert';
import { workbenchInstantiationService, registerTestEditor, TestFileEditorInput, TestEditorPart, ITestInstantiationService, TestServiceAccessor, createEditorPart } from 'vs/workbench/test/browser/workbenchTestServices';
import { GroupDirection, GroupsOrder, MergeGroupMode, GroupOrientation, GroupChangeKind, GroupLocation, isEditorGroup, IEditorGroupsService, IGroupChangeEvent } from 'vs/workbench/services/editor/common/editorGroupsService';
import { CloseDirection, IEditorPartOptions, EditorsOrder, EditorInputCapabilities } from 'vs/workbench/common/editor';
import { GroupDirection, GroupsOrder, MergeGroupMode, GroupOrientation, GroupLocation, isEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { CloseDirection, IEditorPartOptions, EditorsOrder, EditorInputCapabilities, GroupChangeKind } from 'vs/workbench/common/editor';
import { URI } from 'vs/base/common/uri';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { DisposableStore } from 'vs/base/common/lifecycle';
@ -15,6 +15,7 @@ import { ConfirmResult } from 'vs/platform/dialogs/common/dialogs';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
import { IGroupChangeEvent, IGroupEditorMoveEvent, IGroupEditorOpenEvent } from 'vs/workbench/common/editor/editorGroupModel';
suite('EditorGroupsService', () => {
@ -454,8 +455,8 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.count, 2);
assert.strictEqual(editorCapabilitiesCounter, 0);
assert.strictEqual(editorDidOpenCounter, 2);
assert.strictEqual(editorOpenEvents[0].editorIndex, 0);
assert.strictEqual(editorOpenEvents[1].editorIndex, 1);
assert.strictEqual((editorOpenEvents[0] as IGroupEditorOpenEvent).editorIndex, 0);
assert.strictEqual((editorOpenEvents[1] as IGroupEditorOpenEvent).editorIndex, 1);
assert.strictEqual(editorOpenEvents[0].editor, input);
assert.strictEqual(editorOpenEvents[1].editor, inputInactive);
assert.strictEqual(activeEditorChangeCounter, 1);
@ -495,7 +496,7 @@ suite('EditorGroupsService', () => {
assert.strictEqual(activeEditorChangeCounter, 3);
assert.strictEqual(editorCloseCounter, 1);
assert.strictEqual(editorCloseEvents[0].editorIndex, 1);
assert.strictEqual((editorCloseEvents[0] as IGroupEditorOpenEvent).editorIndex, 1);
assert.strictEqual(editorCloseEvents[0].editor, inputInactive);
assert.strictEqual(editorCloseCounter1, 1);
assert.strictEqual(editorWillCloseCounter, 1);
@ -952,16 +953,16 @@ suite('EditorGroupsService', () => {
assert.strictEqual(group.getEditorByIndex(1), inputInactive);
group.moveEditor(inputInactive, group, { index: 0 });
assert.strictEqual(moveEvents.length, 1);
assert.strictEqual(moveEvents[0].editorIndex, 0);
assert.strictEqual(moveEvents[0].oldEditorIndex, 1);
assert.strictEqual((moveEvents[0] as IGroupEditorOpenEvent).editorIndex, 0);
assert.strictEqual((moveEvents[0] as IGroupEditorMoveEvent).oldEditorIndex, 1);
assert.strictEqual(moveEvents[0].editor, inputInactive);
assert.strictEqual(group.getEditorByIndex(0), inputInactive);
assert.strictEqual(group.getEditorByIndex(1), input);
group.moveEditors([{ editor: inputInactive, options: { index: 1 } }], group);
assert.strictEqual(moveEvents.length, 2);
assert.strictEqual(moveEvents[1].editorIndex, 1);
assert.strictEqual(moveEvents[1].oldEditorIndex, 0);
assert.strictEqual((moveEvents[1] as IGroupEditorOpenEvent).editorIndex, 1);
assert.strictEqual((moveEvents[1] as IGroupEditorMoveEvent).oldEditorIndex, 0);
assert.strictEqual(moveEvents[1].editor, inputInactive);
assert.strictEqual(group.getEditorByIndex(0), input);
assert.strictEqual(group.getEditorByIndex(1), inputInactive);

View file

@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { EditorGroupModel, ISerializedEditorGroupModel } from 'vs/workbench/common/editor/editorGroupModel';
import { EditorExtensions, IEditorFactoryRegistry, IFileEditorInput, IEditorSerializer, CloseDirection, EditorsOrder, IResourceDiffEditorInput, IResourceSideBySideEditorInput, SideBySideEditor, EditorCloseContext, IEditorCloseEvent, IEditorOpenEvent, IEditorMoveEvent } from 'vs/workbench/common/editor';
import { EditorGroupModel, ISerializedEditorGroupModel, isGroupEditorCloseEvent, isGroupEditorMoveEvent, isGroupEditorOpenEvent } from 'vs/workbench/common/editor/editorGroupModel';
import { EditorExtensions, IEditorFactoryRegistry, IFileEditorInput, IEditorSerializer, CloseDirection, EditorsOrder, IResourceDiffEditorInput, IResourceSideBySideEditorInput, SideBySideEditor, EditorCloseContext, IEditorCloseEvent, IEditorOpenEvent, IEditorMoveEvent, GroupChangeKind } from 'vs/workbench/common/editor';
import { URI } from 'vs/base/common/uri';
import { TestLifecycleService, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
@ -105,14 +105,44 @@ suite('EditorGroupModel', () => {
disposed: []
};
group.onDidChangeLocked(() => groupEvents.locked.push(group.id));
group.onDidOpenEditor(e => groupEvents.opened.push(e));
group.onDidCloseEditor(e => groupEvents.closed.push(e));
group.onDidActivateEditor(e => groupEvents.activated.push(e));
group.onDidChangeEditorPinned(e => group.isPinned(e) ? groupEvents.pinned.push(e) : groupEvents.unpinned.push(e));
group.onDidChangeEditorSticky(e => group.isSticky(e) ? groupEvents.sticky.push(e) : groupEvents.unsticky.push(e));
group.onDidMoveEditor(e => groupEvents.moved.push(e));
group.onWillDisposeEditor(e => groupEvents.disposed.push(e));
group.onDidModelChange(e => {
if (e.kind === GroupChangeKind.GROUP_LOCKED) {
groupEvents.locked.push(group.id);
return;
}
if (!e.editor) {
return;
}
switch (e.kind) {
case GroupChangeKind.EDITOR_OPEN:
if (isGroupEditorOpenEvent(e)) {
groupEvents.opened.push({ editor: e.editor, index: e.editorIndex, groupId: group.id });
}
break;
case GroupChangeKind.EDITOR_CLOSE:
if (isGroupEditorCloseEvent(e)) {
groupEvents.closed.push({ editor: e.editor, index: e.editorIndex, groupId: group.id, context: e.context, sticky: e.sticky });
}
break;
case GroupChangeKind.EDITOR_ACTIVE:
groupEvents.activated.push(e.editor);
break;
case GroupChangeKind.EDITOR_PIN:
group.isPinned(e.editor) ? groupEvents.pinned.push(e.editor) : groupEvents.unpinned.push(e.editor);
break;
case GroupChangeKind.EDITOR_STICKY:
group.isSticky(e.editor) ? groupEvents.sticky.push(e.editor) : groupEvents.unsticky.push(e.editor);
break;
case GroupChangeKind.EDITOR_MOVE:
if (isGroupEditorMoveEvent(e)) {
groupEvents.moved.push({ editor: e.editor, index: e.oldEditorIndex, newIndex: e.editorIndex, target: group.id, groupId: group.id });
}
break;
case GroupChangeKind.EDITOR_WILL_DISPOSE:
groupEvents.disposed.push(e.editor);
break;
}
});
return groupEvents;
}
@ -278,7 +308,11 @@ suite('EditorGroupModel', () => {
assert.strictEqual(clone.isLocked, false); // locking does not clone over
let didEditorLabelChange = false;
const toDispose = clone.onDidChangeEditorLabel(() => didEditorLabelChange = true);
const toDispose = clone.onDidModelChange((e) => {
if (e.kind === GroupChangeKind.EDITOR_LABEL) {
didEditorLabelChange = true;
}
});
input1.setLabel();
assert.ok(didEditorLabelChange);
@ -754,7 +788,7 @@ suite('EditorGroupModel', () => {
let index = group.indexOf(input1);
let event = group.closeEditor(input1, EditorCloseContext.UNPIN);
assert.strictEqual(event?.editor, input1);
assert.strictEqual(event?.index, index);
assert.strictEqual(event?.editorIndex, index);
assert.strictEqual(group.count, 0);
assert.strictEqual(group.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE).length, 0);
assert.strictEqual(group.activeEditor, null);
@ -1825,23 +1859,31 @@ suite('EditorGroupModel', () => {
group2.openEditor(input2, { pinned: true, active: true });
let dirty1Counter = 0;
group1.onDidChangeEditorDirty(() => {
dirty1Counter++;
group1.onDidModelChange((e) => {
if (e.kind === GroupChangeKind.EDITOR_DIRTY) {
dirty1Counter++;
}
});
let dirty2Counter = 0;
group2.onDidChangeEditorDirty(() => {
dirty2Counter++;
group2.onDidModelChange((e) => {
if (e.kind === GroupChangeKind.EDITOR_DIRTY) {
dirty2Counter++;
}
});
let label1ChangeCounter = 0;
group1.onDidChangeEditorLabel(() => {
label1ChangeCounter++;
group1.onDidModelChange((e) => {
if (e.kind === GroupChangeKind.EDITOR_LABEL) {
label1ChangeCounter++;
}
});
let label2ChangeCounter = 0;
group2.onDidChangeEditorLabel(() => {
label2ChangeCounter++;
group2.onDidModelChange((e) => {
if (e.kind === GroupChangeKind.EDITOR_LABEL) {
label2ChangeCounter++;
}
});
(<TestEditorInput>input1).setDirty();

View file

@ -51,7 +51,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IDecorationsService, IResourceDecorationChangeEvent, IDecoration, IDecorationData, IDecorationsProvider } from 'vs/workbench/services/decorations/common/decorations';
import { IDisposable, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupsArrangement, GroupDirection, IAddGroupOptions, IMergeGroupOptions, IEditorReplacement, IGroupChangeEvent, IFindGroupScope, EditorGroupLayout, ICloseEditorOptions, GroupOrientation, ICloseAllEditorsOptions, ICloseEditorsFilter } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupsArrangement, GroupDirection, IAddGroupOptions, IMergeGroupOptions, IEditorReplacement, IFindGroupScope, EditorGroupLayout, ICloseEditorOptions, GroupOrientation, ICloseAllEditorsOptions, ICloseEditorsFilter } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorService, ISaveEditorsOptions, IRevertAllEditorsOptions, PreferredGroup, IEditorsChangeEvent } from 'vs/workbench/services/editor/common/editorService';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { IEditorPaneRegistry, EditorPaneDescriptor } from 'vs/workbench/browser/editor';
@ -144,6 +144,7 @@ import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/te
import { FindReplaceState } from 'vs/editor/contrib/find/findState';
import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput';
import { DeserializedTerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorSerializer';
import { IGroupChangeEvent } from 'vs/workbench/common/editor/editorGroupModel';
import { env } from 'vs/base/common/process';
export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
@ -817,6 +818,7 @@ export class TestEditorGroupView implements IEditorGroupView {
onWillDispose: Event<void> = Event.None;
onDidGroupChange: Event<IGroupChangeEvent> = Event.None;
onDidModelChange: Event<IGroupChangeEvent> = Event.None;
onWillCloseEditor: Event<IEditorCloseEvent> = Event.None;
onDidCloseEditor: Event<IEditorCloseEvent> = Event.None;
onDidOpenEditorFail: Event<EditorInput> = Event.None;