mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-29 13:03:42 +01:00
Update tabs model to utilize the new API shape (#142668)
* Change shape of the tabs API * Disable tab tests for now * Add an onDidChangeTabGroup event * Optimize for group activate * Update events to no longer be an array * Further tab optimization
This commit is contained in:
@@ -5,18 +5,15 @@
|
||||
|
||||
import type * as vscode from 'vscode';
|
||||
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { IEditorTabDto, IExtHostEditorTabsShape, MainContext, MainThreadEditorTabsShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { IEditorTabDto, IEditorTabGroupDto, IExtHostEditorTabsShape, MainContext, MainThreadEditorTabsShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ViewColumn } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { raceTimeout } from 'vs/base/common/async';
|
||||
|
||||
export interface IEditorTab {
|
||||
label: string;
|
||||
viewColumn: ViewColumn;
|
||||
index: number;
|
||||
resource: vscode.Uri | undefined;
|
||||
viewId: string | undefined;
|
||||
isActive: boolean;
|
||||
@@ -25,12 +22,21 @@ export interface IEditorTab {
|
||||
close(): Promise<void>;
|
||||
}
|
||||
|
||||
export interface IEditorTabGroup {
|
||||
isActive: boolean;
|
||||
viewColumn: ViewColumn;
|
||||
activeTab: IEditorTab | undefined;
|
||||
tabs: IEditorTab[];
|
||||
}
|
||||
|
||||
export interface IEditorTabGroups {
|
||||
all: IEditorTabGroup[];
|
||||
onDidChangeTabGroup: Event<void>;
|
||||
}
|
||||
|
||||
export interface IExtHostEditorTabs extends IExtHostEditorTabsShape {
|
||||
readonly _serviceBrand: undefined;
|
||||
tabs: readonly IEditorTab[];
|
||||
activeTab: IEditorTab | undefined;
|
||||
onDidChangeActiveTab: Event<IEditorTab | undefined>;
|
||||
onDidChangeTabs: Event<IEditorTab[]>;
|
||||
tabGroups: IEditorTabGroups;
|
||||
}
|
||||
|
||||
export const IExtHostEditorTabs = createDecorator<IExtHostEditorTabs>('IExtHostEditorTabs');
|
||||
@@ -39,61 +45,64 @@ export class ExtHostEditorTabs implements IExtHostEditorTabs {
|
||||
readonly _serviceBrand: undefined;
|
||||
private readonly _proxy: MainThreadEditorTabsShape;
|
||||
|
||||
private readonly _onDidChangeTabs = new Emitter<IEditorTab[]>();
|
||||
readonly onDidChangeTabs: Event<IEditorTab[]> = this._onDidChangeTabs.event;
|
||||
private readonly _onDidChangeTabGroup = new Emitter<void>();
|
||||
readonly onDidChangeTabGroup: Event<void> = this._onDidChangeTabGroup.event;
|
||||
|
||||
private readonly _onDidChangeActiveTab = new Emitter<IEditorTab | undefined>();
|
||||
readonly onDidChangeActiveTab: Event<IEditorTab | undefined> = this._onDidChangeActiveTab.event;
|
||||
|
||||
private _tabs: IEditorTab[] = [];
|
||||
private _activeTab: IEditorTab | undefined;
|
||||
private _tabGroups: IEditorTabGroups = {
|
||||
all: [],
|
||||
onDidChangeTabGroup: this._onDidChangeTabGroup.event
|
||||
};
|
||||
|
||||
constructor(@IExtHostRpcService extHostRpc: IExtHostRpcService) {
|
||||
this._proxy = extHostRpc.getProxy(MainContext.MainThreadEditorTabs);
|
||||
}
|
||||
|
||||
get tabs(): readonly IEditorTab[] {
|
||||
return this._tabs;
|
||||
get tabGroups(): IEditorTabGroups {
|
||||
return this._tabGroups;
|
||||
}
|
||||
|
||||
get activeTab(): IEditorTab | undefined {
|
||||
return this._activeTab;
|
||||
}
|
||||
|
||||
$acceptEditorTabs(tabs: IEditorTabDto[]): void {
|
||||
let activeIndex = -1;
|
||||
this._tabs = tabs.map((dto, index) => {
|
||||
if (dto.isActive) {
|
||||
activeIndex = index;
|
||||
}
|
||||
return Object.freeze({
|
||||
label: dto.label,
|
||||
viewColumn: typeConverters.ViewColumn.to(dto.viewColumn),
|
||||
index,
|
||||
resource: URI.revive(dto.resource),
|
||||
additionalResourcesAndViewIds: dto.additionalResourcesAndViewIds.map(({ resource, viewId }) => ({ resource: URI.revive(resource), viewId })),
|
||||
viewId: dto.editorId,
|
||||
isActive: dto.isActive,
|
||||
move: async (index: number, viewColumn: ViewColumn) => {
|
||||
this._proxy.$moveTab(dto, index, typeConverters.ViewColumn.from(viewColumn));
|
||||
await raceTimeout(Event.toPromise(this._onDidChangeTabs.event), 1000);
|
||||
return;
|
||||
},
|
||||
close: async () => {
|
||||
await this._proxy.$closeTab(dto);
|
||||
await raceTimeout(Event.toPromise(this._onDidChangeTabs.event), 1000);
|
||||
return;
|
||||
$acceptEditorTabModel(tabGroups: IEditorTabGroupDto[]): void {
|
||||
// Clears the tab groups array
|
||||
this._tabGroups.all.length = 0;
|
||||
for (const group of tabGroups) {
|
||||
let activeTab: IEditorTab | undefined;
|
||||
const tabs = group.tabs.map(tab => {
|
||||
const extHostTab = this.createExtHostTabObject(tab);
|
||||
if (tab.isActive) {
|
||||
activeTab = extHostTab;
|
||||
}
|
||||
return extHostTab;
|
||||
});
|
||||
});
|
||||
this._tabs = this._tabs.sort((t1, t2) => {
|
||||
return t1.viewColumn === t2.viewColumn ? t1.index - t2.index : t1.viewColumn - t2.viewColumn;
|
||||
});
|
||||
const oldActiveTab = this._activeTab;
|
||||
this._activeTab = activeIndex === -1 ? undefined : this._tabs[activeIndex];
|
||||
if (this._activeTab !== oldActiveTab) {
|
||||
this._onDidChangeActiveTab.fire(this._activeTab);
|
||||
this._tabGroups.all.push(Object.freeze({
|
||||
isActive: group.isActive,
|
||||
viewColumn: typeConverters.ViewColumn.to(group.viewColumn),
|
||||
activeTab,
|
||||
tabs
|
||||
}));
|
||||
}
|
||||
this._onDidChangeTabs.fire(this._tabs);
|
||||
this._onDidChangeTabGroup.fire();
|
||||
}
|
||||
|
||||
private createExtHostTabObject(tabDto: IEditorTabDto) {
|
||||
return Object.freeze({
|
||||
label: tabDto.label,
|
||||
viewColumn: typeConverters.ViewColumn.to(tabDto.viewColumn),
|
||||
resource: URI.revive(tabDto.resource),
|
||||
additionalResourcesAndViewIds: tabDto.additionalResourcesAndViewIds.map(({ resource, viewId }) => ({ resource: URI.revive(resource), viewId })),
|
||||
viewId: tabDto.editorId,
|
||||
isActive: tabDto.isActive,
|
||||
move: async (index: number, viewColumn: ViewColumn) => {
|
||||
this._proxy.$moveTab(tabDto, index, typeConverters.ViewColumn.from(viewColumn));
|
||||
// TODO: Need an on did change tab event at the group level
|
||||
// await raceTimeout(Event.toPromise(this._onDidChangeTabs.event), 1000);
|
||||
return;
|
||||
},
|
||||
close: async () => {
|
||||
await this._proxy.$closeTab(tabDto);
|
||||
// TODO: Need an on did change tab event at the group level
|
||||
// await raceTimeout(Event.toPromise(this._onDidChangeTabs.event), 1000);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user