This commit is contained in:
Logan Ramos
2022-04-11 10:48:34 -04:00
parent e78ca55def
commit 2cbe5991f9
5 changed files with 75 additions and 26 deletions
@@ -11,7 +11,7 @@ import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { columnToEditorGroup, EditorGroupColumn, editorGroupToColumn } from 'vs/workbench/services/editor/common/editorGroupColumn';
import { GroupDirection, IEditorGroup, IEditorGroupsService, preferredSideBySideGroupDirection } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorsChangeEvent, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IEditorsChangeEvent, IEditorService, IEditorsMoveEvent, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
import { CustomEditorInput } from 'vs/workbench/contrib/customEditor/browser/customEditorInput';
@@ -22,7 +22,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
import { isEqual } from 'vs/base/common/resources';
interface TabInfo {
tab: IEditorTabDto;
group: IEditorGroup;
@@ -386,6 +385,32 @@ export class MainThreadEditorTabs implements MainThreadEditorTabsShape {
});
}
private _onDidTabMove(groupId: number, editorIndex: number, oldEditorIndex: number, editor: EditorInput) {
const tabs = this._groupLookup.get(groupId)?.tabs;
// Something wrong with the model state so we rebuild
if (!tabs) {
console.error('Invalid model for move change, rebuilding');
this._createTabsModel();
return;
}
// Move tab from old index to new index
const removedTab = tabs.splice(oldEditorIndex, 1);
if (removedTab.length === 0) {
return;
}
tabs.splice(editorIndex, 0, removedTab[0]);
// Notify exthost of move
this._proxy.$acceptTabOperation({
kind: TabModelOperationKind.TAB_MOVE,
groupId,
tabDto: removedTab[0],
index: editorIndex,
oldIndex: oldEditorIndex
});
}
/**
* Builds the model from scratch based on the current state of the editor service.
*/
@@ -421,30 +446,31 @@ export class MainThreadEditorTabs implements MainThreadEditorTabsShape {
}
// TODOD @lramos15 Remove this after done finishing the tab model code
// private _eventToString(event: IEditorsChangeEvent): string {
// let eventString = '';
// switch (event.kind) {
// case GroupModelChangeKind.GROUP_INDEX: eventString += 'GROUP_INDEX'; break;
// case GroupModelChangeKind.EDITOR_ACTIVE: eventString += 'EDITOR_ACTIVE'; break;
// case GroupModelChangeKind.EDITOR_PIN: eventString += 'EDITOR_PIN'; break;
// case GroupModelChangeKind.EDITOR_OPEN: eventString += 'EDITOR_OPEN'; break;
// case GroupModelChangeKind.EDITOR_CLOSE: eventString += 'EDITOR_CLOSE'; break;
// case GroupModelChangeKind.EDITOR_MOVE: eventString += 'EDITOR_MOVE'; break;
// case GroupModelChangeKind.EDITOR_LABEL: eventString += 'EDITOR_LABEL'; break;
// case GroupModelChangeKind.GROUP_ACTIVE: eventString += 'GROUP_ACTIVE'; break;
// case GroupModelChangeKind.GROUP_LOCKED: eventString += 'GROUP_LOCKED'; break;
// case GroupModelChangeKind.EDITOR_DIRTY: eventString += 'EDITOR_DIRTY'; break;
// case GroupModelChangeKind.EDITOR_STICKY: eventString += 'EDITOR_STICKY'; break;
// default: eventString += `UNKNOWN: ${event.kind}`; break;
// }
// return eventString;
// }
private _eventToString(event: IEditorsChangeEvent | IEditorsMoveEvent): string {
let eventString = '';
switch (event.kind) {
case GroupModelChangeKind.GROUP_INDEX: eventString += 'GROUP_INDEX'; break;
case GroupModelChangeKind.EDITOR_ACTIVE: eventString += 'EDITOR_ACTIVE'; break;
case GroupModelChangeKind.EDITOR_PIN: eventString += 'EDITOR_PIN'; break;
case GroupModelChangeKind.EDITOR_OPEN: eventString += 'EDITOR_OPEN'; break;
case GroupModelChangeKind.EDITOR_CLOSE: eventString += 'EDITOR_CLOSE'; break;
case GroupModelChangeKind.EDITOR_MOVE: eventString += 'EDITOR_MOVE'; break;
case GroupModelChangeKind.EDITOR_LABEL: eventString += 'EDITOR_LABEL'; break;
case GroupModelChangeKind.GROUP_ACTIVE: eventString += 'GROUP_ACTIVE'; break;
case GroupModelChangeKind.GROUP_LOCKED: eventString += 'GROUP_LOCKED'; break;
case GroupModelChangeKind.EDITOR_DIRTY: eventString += 'EDITOR_DIRTY'; break;
case GroupModelChangeKind.EDITOR_STICKY: eventString += 'EDITOR_STICKY'; break;
default: eventString += `UNKNOWN: ${event.kind}`; break;
}
return eventString;
}
/**
* The main handler for the tab events
* @param events The list of events to process
*/
private _updateTabsModel(event: IEditorsChangeEvent): void {
private _updateTabsModel(event: IEditorsChangeEvent | IEditorsMoveEvent): void {
console.log(this._eventToString(event));
switch (event.kind) {
case GroupModelChangeKind.GROUP_ACTIVE:
if (event.groupId === this._editorGroupsService.activeGroup.id) {
@@ -488,6 +514,11 @@ export class MainThreadEditorTabs implements MainThreadEditorTabsShape {
this._onDidTabPreviewChange(event.groupId, event.editorIndex, event.editor);
break;
}
case GroupModelChangeKind.EDITOR_MOVE:
if (event.editor && event.editorIndex !== undefined && (event as IEditorsMoveEvent).oldEditorIndex !== undefined) {
this._onDidTabMove(event.groupId, event.editorIndex, (event as IEditorsMoveEvent).oldEditorIndex, event.editor);
break;
}
default:
// If it's not an optimized case we rebuild the tabs model from scratch
this._createTabsModel();
@@ -625,7 +625,8 @@ export const enum TabInputKind {
export const enum TabModelOperationKind {
TAB_OPEN,
TAB_CLOSE,
TAB_UPDATE
TAB_UPDATE,
TAB_MOVE
}
export interface UnknownInputDto {
@@ -690,11 +691,12 @@ export interface IEditorTabGroupDto {
}
export interface TabOperation {
readonly kind: TabModelOperationKind.TAB_OPEN | TabModelOperationKind.TAB_CLOSE | TabModelOperationKind.TAB_UPDATE;
readonly kind: TabModelOperationKind.TAB_OPEN | TabModelOperationKind.TAB_CLOSE | TabModelOperationKind.TAB_UPDATE | TabModelOperationKind.TAB_MOVE;
// TODO @lramos15 Possibly get rid of index for tab update, it's only needed for open and close
readonly index: number;
readonly tabDto: IEditorTabDto;
readonly groupId: number;
readonly oldIndex?: number;
}
export interface IEditorTabDto {
@@ -174,6 +174,17 @@ class ExtHostEditorTabGroup {
this._activeTabId = '';
}
return tab;
} else if (operation.kind === TabModelOperationKind.TAB_MOVE) {
if (operation.oldIndex === undefined) {
throw new Error('Invalid old index on move IPC');
}
// Splice to remove at old index and insert at new index === moving the tab
const tab = this._tabs.splice(operation.oldIndex, 1)[0];
if (!tab) {
throw new Error(`Tab move updated received for index ${operation.oldIndex} which does not exist`);
}
this._tabs.splice(operation.index, 0, tab);
return tab;
}
const tab = this._tabs.find(extHostTab => extHostTab.tabId === operation.tabDto.id);
if (!tab) {
@@ -308,6 +319,7 @@ export class ExtHostEditorTabs implements IExtHostEditorTabs {
changed: []
});
return;
case TabModelOperationKind.TAB_MOVE:
case TabModelOperationKind.TAB_UPDATE:
this._onDidChangeTabs.fire({
added: [],
@@ -15,7 +15,7 @@ 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, isEditorReplacement, ICloseEditorOptions } 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 { IUntypedEditorReplacement, IEditorService, ISaveEditorsOptions, ISaveAllEditorsOptions, IRevertAllEditorsOptions, IBaseSaveRevertAllEditorOptions, IOpenEditorsOptions, PreferredGroup, isPreferredGroup, IEditorsChangeEvent, IEditorsMoveEvent } 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';
import { coalesce, distinct } from 'vs/base/common/arrays';
@@ -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 Emitter<IEditorsChangeEvent>());
private readonly _onDidEditorsChange = this._register(new Emitter<IEditorsChangeEvent | IEditorsMoveEvent>());
readonly onDidEditorsChange = this._onDidEditorsChange.event;
private readonly _onDidCloseEditor = this._register(new Emitter<IEditorCloseEvent>());
@@ -11,7 +11,7 @@ import { Event } from 'vs/base/common/event';
import { IEditor, IDiffEditor } from 'vs/editor/common/editorCommon';
import { ICloseEditorOptions, IEditorGroup, isEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { URI } from 'vs/base/common/uri';
import { IGroupModelChangeEvent } from 'vs/workbench/common/editor/editorGroupModel';
import { IGroupEditorMoveEvent, IGroupModelChangeEvent } from 'vs/workbench/common/editor/editorGroupModel';
export const IEditorService = createDecorator<IEditorService>('editorService');
@@ -92,6 +92,10 @@ export interface IEditorsChangeEvent extends IGroupModelChangeEvent {
groupId: GroupIdentifier;
}
export interface IEditorsMoveEvent extends IGroupEditorMoveEvent {
groupId: GroupIdentifier;
}
export interface IEditorService {
readonly _serviceBrand: undefined;