Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/vscode.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/vs/workbench/api/common/extHostEditorTabs.ts')
-rw-r--r--src/vs/workbench/api/common/extHostEditorTabs.ts165
1 files changed, 126 insertions, 39 deletions
diff --git a/src/vs/workbench/api/common/extHostEditorTabs.ts b/src/vs/workbench/api/common/extHostEditorTabs.ts
index cbd2effae0c..1fbc2d487de 100644
--- a/src/vs/workbench/api/common/extHostEditorTabs.ts
+++ b/src/vs/workbench/api/common/extHostEditorTabs.ts
@@ -9,9 +9,10 @@ import { IEditorTabDto, IEditorTabGroupDto, IExtHostEditorTabsShape, MainContext
import { URI } from 'vs/base/common/uri';
import { Emitter } from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
-import { CustomEditorTabInput, NotebookDiffEditorTabInput, NotebookEditorTabInput, TerminalEditorTabInput, TextDiffTabInput, TextTabInput, ViewColumn, WebviewEditorTabInput } from 'vs/workbench/api/common/extHostTypes';
+import { CustomEditorTabInput, NotebookDiffEditorTabInput, NotebookEditorTabInput, TerminalEditorTabInput, TextDiffTabInput, TextTabInput, WebviewEditorTabInput } from 'vs/workbench/api/common/extHostTypes';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { assertIsDefined } from 'vs/base/common/types';
+import { diffSets } from 'vs/base/common/collections';
export interface IExtHostEditorTabs extends IExtHostEditorTabsShape {
readonly _serviceBrand: undefined;
@@ -47,7 +48,7 @@ class ExtHostEditorTab {
get label() {
return that._dto.label;
},
- get kind() {
+ get input() {
return that._input;
},
get isDirty() {
@@ -174,6 +175,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) {
@@ -201,8 +213,8 @@ export class ExtHostEditorTabs implements IExtHostEditorTabs {
readonly _serviceBrand: undefined;
private readonly _proxy: MainThreadEditorTabsShape;
- private readonly _onDidChangeTabs = new Emitter<vscode.Tab[]>();
- private readonly _onDidChangeTabGroups = new Emitter<vscode.TabGroup[]>();
+ private readonly _onDidChangeTabs = new Emitter<vscode.TabChangeEvent>();
+ private readonly _onDidChangeTabGroups = new Emitter<vscode.TabGroupChangeEvent>();
// Have to use ! because this gets initialized via an RPC proxy
private _activeGroupId!: number;
@@ -223,7 +235,7 @@ export class ExtHostEditorTabs implements IExtHostEditorTabs {
onDidChangeTabGroups: that._onDidChangeTabGroups.event,
onDidChangeTabs: that._onDidChangeTabs.event,
// dynamic -> getters
- get groups() {
+ get all() {
return Object.freeze(that._extHostTabGroups.map(group => group.apiObject));
},
get activeTabGroup() {
@@ -231,47 +243,51 @@ export class ExtHostEditorTabs implements IExtHostEditorTabs {
const activeTabGroup = assertIsDefined(that._extHostTabGroups.find(candidate => candidate.groupId === activeTabGroupId)?.apiObject);
return activeTabGroup;
},
- close: async (tab: vscode.Tab | vscode.Tab[], preserveFocus?: boolean) => {
- const tabs = Array.isArray(tab) ? tab : [tab];
- const extHostTabIds: string[] = [];
- for (const tab of tabs) {
- const extHostTab = this._findExtHostTabFromApi(tab);
- if (!extHostTab) {
- throw new Error('Tab close: Invalid tab not found!');
- }
- extHostTabIds.push(extHostTab.tabId);
+ close: async (tabOrTabGroup: vscode.Tab | readonly vscode.Tab[] | vscode.TabGroup | readonly vscode.TabGroup[], preserveFocus?: boolean) => {
+ const tabsOrTabGroups = Array.isArray(tabOrTabGroup) ? tabOrTabGroup : [tabOrTabGroup];
+ if (!tabsOrTabGroups.length) {
+ return true;
}
- return this._proxy.$closeTab(extHostTabIds, preserveFocus);
- },
- move: async (tab: vscode.Tab, viewColumn: ViewColumn, index: number, preservceFocus?: boolean) => {
- const extHostTab = this._findExtHostTabFromApi(tab);
- if (!extHostTab) {
- throw new Error('Invalid tab');
+ // Check which type was passed in and call the appropriate close
+ // Casting is needed as typescript doesn't seem to infer enough from this
+ if (isTabGroup(tabsOrTabGroups[0])) {
+ return this._closeGroups(tabsOrTabGroups as vscode.TabGroup[], preserveFocus);
+ } else {
+ return this._closeTabs(tabsOrTabGroups as vscode.Tab[], preserveFocus);
}
- this._proxy.$moveTab(extHostTab.tabId, index, typeConverters.ViewColumn.from(viewColumn), preservceFocus);
- return;
- }
+ },
+ // move: async (tab: vscode.Tab, viewColumn: ViewColumn, index: number, preservceFocus?: boolean) => {
+ // const extHostTab = this._findExtHostTabFromApi(tab);
+ // if (!extHostTab) {
+ // throw new Error('Invalid tab');
+ // }
+ // this._proxy.$moveTab(extHostTab.tabId, index, typeConverters.ViewColumn.from(viewColumn), preservceFocus);
+ // return;
+ // }
};
this._apiObject = Object.freeze(obj);
}
return this._apiObject;
}
- private _findExtHostTabFromApi(apiTab: vscode.Tab): ExtHostEditorTab | undefined {
- for (const group of this._extHostTabGroups) {
- for (const tab of group.tabs) {
- if (tab.apiObject === apiTab) {
- return tab;
- }
- }
- }
- return;
- }
-
$acceptEditorTabModel(tabGroups: IEditorTabGroupDto[]): void {
+ const groupIdsBefore = new Set(this._extHostTabGroups.map(group => group.groupId));
+ const groupIdsAfter = new Set(tabGroups.map(dto => dto.groupId));
+ const diff = diffSets(groupIdsBefore, groupIdsAfter);
+
+ const closed: vscode.TabGroup[] = this._extHostTabGroups.filter(group => diff.removed.includes(group.groupId)).map(group => group.apiObject);
+ const opened: vscode.TabGroup[] = [];
+ const changed: vscode.TabGroup[] = [];
+
+
this._extHostTabGroups = tabGroups.map(tabGroup => {
const group = new ExtHostEditorTabGroup(tabGroup, this._proxy, () => this._activeGroupId);
+ if (diff.added.includes(group.groupId)) {
+ opened.push(group.apiObject);
+ } else {
+ changed.push(group.apiObject);
+ }
return group;
});
@@ -280,7 +296,7 @@ export class ExtHostEditorTabs implements IExtHostEditorTabs {
if (activeTabGroupId !== undefined && this._activeGroupId !== activeTabGroupId) {
this._activeGroupId = activeTabGroupId;
}
- this._onDidChangeTabGroups.fire(this._extHostTabGroups.map(g => g.apiObject));
+ this._onDidChangeTabGroups.fire(Object.freeze({ opened, closed, changed }));
}
$acceptTabGroupUpdate(groupDto: IEditorTabGroupDto) {
@@ -292,7 +308,7 @@ export class ExtHostEditorTabs implements IExtHostEditorTabs {
if (groupDto.isActive) {
this._activeGroupId = groupDto.groupId;
}
- this._onDidChangeTabGroups.fire([group.apiObject]);
+ this._onDidChangeTabGroups.fire(Object.freeze({ changed: [group.apiObject], opened: [], closed: [] }));
}
$acceptTabOperation(operation: TabOperation) {
@@ -301,9 +317,80 @@ export class ExtHostEditorTabs implements IExtHostEditorTabs {
throw new Error('Update Tabs IPC call received before group creation.');
}
const tab = group.acceptTabOperation(operation);
- // We don't want to fire a change event with a closed tab to prevent an invalid tabs from being received
- if (operation.kind !== TabModelOperationKind.TAB_CLOSE) {
- this._onDidChangeTabs.fire([tab.apiObject]);
+
+ // Construct the tab change event based on the operation
+ switch (operation.kind) {
+ case TabModelOperationKind.TAB_OPEN:
+ this._onDidChangeTabs.fire(Object.freeze({
+ opened: [tab.apiObject],
+ closed: [],
+ changed: []
+ }));
+ return;
+ case TabModelOperationKind.TAB_CLOSE:
+ this._onDidChangeTabs.fire(Object.freeze({
+ opened: [],
+ closed: [tab.apiObject],
+ changed: []
+ }));
+ return;
+ case TabModelOperationKind.TAB_MOVE:
+ case TabModelOperationKind.TAB_UPDATE:
+ this._onDidChangeTabs.fire(Object.freeze({
+ opened: [],
+ closed: [],
+ changed: [tab.apiObject]
+ }));
+ return;
}
}
+
+ private _findExtHostTabFromApi(apiTab: vscode.Tab): ExtHostEditorTab | undefined {
+ for (const group of this._extHostTabGroups) {
+ for (const tab of group.tabs) {
+ if (tab.apiObject === apiTab) {
+ return tab;
+ }
+ }
+ }
+ return;
+ }
+
+ private _findExtHostTabGroupFromApi(apiTabGroup: vscode.TabGroup): ExtHostEditorTabGroup | undefined {
+ return this._extHostTabGroups.find(candidate => candidate.apiObject === apiTabGroup);
+ }
+
+ private async _closeTabs(tabs: vscode.Tab[], preserveFocus?: boolean): Promise<boolean> {
+ const extHostTabIds: string[] = [];
+ for (const tab of tabs) {
+ const extHostTab = this._findExtHostTabFromApi(tab);
+ if (!extHostTab) {
+ throw new Error('Tab close: Invalid tab not found!');
+ }
+ extHostTabIds.push(extHostTab.tabId);
+ }
+ return this._proxy.$closeTab(extHostTabIds, preserveFocus);
+ }
+
+ private async _closeGroups(groups: vscode.TabGroup[], preserverFoucs?: boolean): Promise<boolean> {
+ const extHostGroupIds: number[] = [];
+ for (const group of groups) {
+ const extHostGroup = this._findExtHostTabGroupFromApi(group);
+ if (!extHostGroup) {
+ throw new Error('Group close: Invalid group not found!');
+ }
+ extHostGroupIds.push(extHostGroup.groupId);
+ }
+ return this._proxy.$closeGroup(extHostGroupIds, preserverFoucs);
+ }
+}
+
+//#region Utils
+function isTabGroup(obj: unknown): obj is vscode.TabGroup {
+ const tabGroup = obj as vscode.TabGroup;
+ if (tabGroup.tabs !== undefined) {
+ return true;
+ }
+ return false;
}
+//#endregion