diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index d282da2eb65..ba726952b2a 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -3127,6 +3127,7 @@ declare module 'vscode' { export interface OpenEditorInfo { name: string; resource: Uri; + isActive: boolean; } export namespace window { diff --git a/src/vs/workbench/api/browser/mainThreadEditorTabs.ts b/src/vs/workbench/api/browser/mainThreadEditorTabs.ts index 2e6aaffa5e4..1a42fad7034 100644 --- a/src/vs/workbench/api/browser/mainThreadEditorTabs.ts +++ b/src/vs/workbench/api/browser/mainThreadEditorTabs.ts @@ -9,6 +9,7 @@ import { ExtHostContext, IExtHostEditorTabsShape, IExtHostContext, MainContext, import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { Verbosity } from 'vs/workbench/common/editor'; import { GroupChangeKind, IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; export interface ITabInfo { name: string; @@ -27,6 +28,7 @@ export class MainThreadEditorTabs { constructor( extHostContext: IExtHostContext, @IEditorGroupsService private readonly _editorGroupsService: IEditorGroupsService, + @IEditorService editorService: IEditorService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostEditorTabs); @@ -41,6 +43,7 @@ export class MainThreadEditorTabs { this._pushEditorTabs(); } })); + this._dispoables.add(editorService.onDidActiveEditorChange(this._pushEditorTabs, this)); this._pushEditorTabs(); } @@ -69,7 +72,8 @@ export class MainThreadEditorTabs { tabs.push({ group: group.id, name: editor.getTitle(Verbosity.SHORT) ?? '', - resource: editor.resource + resource: editor.resource, + isActive: (this._editorGroupsService.activeGroup === group) && group.isActive(editor) }); } } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 1789e58e0ef..ad6c84bc650 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -82,7 +82,7 @@ import { IExtHostFileSystemInfo } from 'vs/workbench/api/common/extHostFileSyste import { ExtHostTesting } from 'vs/workbench/api/common/extHostTesting'; import { ExtHostUriOpeners } from 'vs/workbench/api/common/extHostUriOpener'; import { IExtHostSecretState } from 'vs/workbench/api/common/exHostSecretState'; -import { ExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs'; +import { IExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs'; import { IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry'; import { ExtHostNotebookKernels } from 'vs/workbench/api/common/extHostNotebookKernels'; import { RemoteTrustOption } from 'vs/platform/remote/common/remoteAuthorityResolver'; @@ -114,6 +114,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I const extHostApiDeprecation = accessor.get(IExtHostApiDeprecationService); const extHostWindow = accessor.get(IExtHostWindow); const extHostSecretState = accessor.get(IExtHostSecretState); + const extHostEditorTabs = accessor.get(IExtHostEditorTabs); // register addressable instances rpcProtocol.set(ExtHostContext.ExtHostFileSystemInfo, extHostFileSystemInfo); @@ -126,6 +127,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I rpcProtocol.set(ExtHostContext.ExtHostWindow, extHostWindow); rpcProtocol.set(ExtHostContext.ExtHostSecretState, extHostSecretState); rpcProtocol.set(ExtHostContext.ExtHostTelemetry, extHostTelemetry); + rpcProtocol.set(ExtHostContext.ExtHostEditorTabs, extHostEditorTabs); // automatically create and register addressable instances const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, accessor.get(IExtHostDecorations)); @@ -138,7 +140,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, accessor.get(IExtHostOutputService)); // manually create and register addressable instances - const extHostEditorTabs = rpcProtocol.set(ExtHostContext.ExtHostEditorTabs, new ExtHostEditorTabs()); const extHostUrls = rpcProtocol.set(ExtHostContext.ExtHostUrls, new ExtHostUrls(rpcProtocol)); const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors)); const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService)); diff --git a/src/vs/workbench/api/common/extHost.common.services.ts b/src/vs/workbench/api/common/extHost.common.services.ts index bf894f0cfb4..1ff423101e9 100644 --- a/src/vs/workbench/api/common/extHost.common.services.ts +++ b/src/vs/workbench/api/common/extHost.common.services.ts @@ -23,6 +23,7 @@ import { IExtHostConsumerFileSystem, ExtHostConsumerFileSystem } from 'vs/workbe import { IExtHostFileSystemInfo, ExtHostFileSystemInfo } from 'vs/workbench/api/common/extHostFileSystemInfo'; import { IExtHostSecretState, ExtHostSecretState } from 'vs/workbench/api/common/exHostSecretState'; import { ExtHostTelemetry, IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry'; +import { ExtHostEditorTabs, IExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs'; registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths); registerSingleton(IExtHostApiDeprecationService, ExtHostApiDeprecationService); @@ -43,3 +44,4 @@ registerSingleton(IExtHostWindow, ExtHostWindow); registerSingleton(IExtHostWorkspace, ExtHostWorkspace); registerSingleton(IExtHostSecretState, ExtHostSecretState); registerSingleton(IExtHostTelemetry, ExtHostTelemetry); +registerSingleton(IExtHostEditorTabs, ExtHostEditorTabs); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index a23e4f3310b..7b4b03fe9f6 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -622,7 +622,8 @@ export interface MainThreadEditorTabsShape extends IDisposable { export interface IEditorTabDto { group: number; name: string; - resource: UriComponents + resource: UriComponents; + isActive: boolean; } export interface IExtHostEditorTabsShape { diff --git a/src/vs/workbench/api/common/extHostDebugService.ts b/src/vs/workbench/api/common/extHostDebugService.ts index 67477c58c5c..7dfe656ec43 100644 --- a/src/vs/workbench/api/common/extHostDebugService.ts +++ b/src/vs/workbench/api/common/extHostDebugService.ts @@ -31,6 +31,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { withNullAsUndefined } from 'vs/base/common/types'; import * as process from 'vs/base/common/process'; +import { IExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs'; export const IExtHostDebugService = createDecorator('IExtHostDebugService'); @@ -109,6 +110,7 @@ export abstract class ExtHostDebugServiceBase implements IExtHostDebugService, E @IExtHostExtensionService private _extensionService: IExtHostExtensionService, @IExtHostDocumentsAndEditors private _editorsService: IExtHostDocumentsAndEditors, @IExtHostConfiguration protected _configurationService: IExtHostConfiguration, + @IExtHostEditorTabs protected _editorTabs: IExtHostEditorTabs ) { this._configProviderHandleCounter = 0; this._configProviders = []; @@ -930,7 +932,21 @@ export class ExtHostDebugConsole { export class ExtHostVariableResolverService extends AbstractVariableResolverService { - constructor(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors | undefined, configurationService: ExtHostConfigProvider, workspaceService?: IExtHostWorkspace) { + constructor(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors | undefined, configurationService: ExtHostConfigProvider, editorTabs: IExtHostEditorTabs, workspaceService?: IExtHostWorkspace) { + function getActiveUri(): URI | undefined { + if (editorService) { + const activeEditor = editorService.activeEditor(); + if (activeEditor) { + return activeEditor.document.uri; + } + const tabs = editorTabs.tabs.filter(tab => tab.isActive); + if (tabs.length > 0) { + return tabs[0].resource; + } + } + return undefined; + } + super({ getFolderUri: (folderName: string): URI | undefined => { const found = folders.filter(f => f.name === folderName); @@ -952,19 +968,17 @@ export class ExtHostVariableResolverService extends AbstractVariableResolverServ return process.env['VSCODE_EXEC_PATH']; }, getFilePath: (): string | undefined => { - if (editorService) { - const activeEditor = editorService.activeEditor(); - if (activeEditor) { - return path.normalize(activeEditor.document.uri.fsPath); - } + const activeUri = getActiveUri(); + if (activeUri) { + return path.normalize(activeUri.fsPath); } return undefined; }, getWorkspaceFolderPathForFile: (): string | undefined => { - if (editorService && workspaceService) { - const activeEditor = editorService.activeEditor(); - if (activeEditor) { - const ws = workspaceService.getWorkspaceFolder(activeEditor.document.uri); + if (workspaceService) { + const activeUri = getActiveUri(); + if (activeUri) { + const ws = workspaceService.getWorkspaceFolder(activeUri); if (ws) { return path.normalize(ws.uri.fsPath); } @@ -1076,12 +1090,13 @@ export class WorkerExtHostDebugService extends ExtHostDebugServiceBase { @IExtHostWorkspace workspaceService: IExtHostWorkspace, @IExtHostExtensionService extensionService: IExtHostExtensionService, @IExtHostDocumentsAndEditors editorsService: IExtHostDocumentsAndEditors, - @IExtHostConfiguration configurationService: IExtHostConfiguration + @IExtHostConfiguration configurationService: IExtHostConfiguration, + @IExtHostEditorTabs editorTabs: IExtHostEditorTabs ) { - super(extHostRpcService, workspaceService, extensionService, editorsService, configurationService); + super(extHostRpcService, workspaceService, extensionService, editorsService, configurationService, editorTabs); } protected createVariableResolver(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider): AbstractVariableResolverService { - return new ExtHostVariableResolverService(folders, editorService, configurationService); + return new ExtHostVariableResolverService(folders, editorService, configurationService, this._editorTabs); } } diff --git a/src/vs/workbench/api/common/extHostEditorTabs.ts b/src/vs/workbench/api/common/extHostEditorTabs.ts index 2d0f7b4c697..1662754fd85 100644 --- a/src/vs/workbench/api/common/extHostEditorTabs.ts +++ b/src/vs/workbench/api/common/extHostEditorTabs.ts @@ -7,15 +7,25 @@ import type * as vscode from 'vscode'; import { IEditorTabDto, IExtHostEditorTabsShape } 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'; export interface IEditorTab { name: string; group: number; resource: vscode.Uri + isActive: boolean } -export class ExtHostEditorTabs implements IExtHostEditorTabsShape { +export interface IExtHostEditorTabs extends IExtHostEditorTabsShape { + readonly _serviceBrand: undefined; + tabs: readonly IEditorTab[]; + onDidChangeTabs: Event; +} + +export const IExtHostEditorTabs = createDecorator('IExtHostEditorTabs'); + +export class ExtHostEditorTabs implements IExtHostEditorTabs { + readonly _serviceBrand: undefined; private readonly _onDidChangeTabs = new Emitter(); readonly onDidChangeTabs: Event = this._onDidChangeTabs.event; @@ -31,7 +41,8 @@ export class ExtHostEditorTabs implements IExtHostEditorTabsShape { return { name: dto.name, group: dto.group, - resource: URI.revive(dto.resource) + resource: URI.revive(dto.resource), + isActive: dto.isActive }; }); this._onDidChangeTabs.fire(); diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index 12e894b4960..05299c522f7 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -24,6 +24,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/common/variableResolver'; import { createCancelablePromise, firstParallel } from 'vs/base/common/async'; import { hasChildProcesses, prepareCommand, runInExternalTerminal } from 'vs/workbench/contrib/debug/node/terminals'; +import { IExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs'; export class ExtHostDebugService extends ExtHostDebugServiceBase { @@ -38,9 +39,10 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase { @IExtHostExtensionService extensionService: IExtHostExtensionService, @IExtHostDocumentsAndEditors editorsService: IExtHostDocumentsAndEditors, @IExtHostConfiguration configurationService: IExtHostConfiguration, - @IExtHostTerminalService private _terminalService: IExtHostTerminalService + @IExtHostTerminalService private _terminalService: IExtHostTerminalService, + @IExtHostEditorTabs editorTabs: IExtHostEditorTabs ) { - super(extHostRpcService, workspaceService, extensionService, editorsService, configurationService); + super(extHostRpcService, workspaceService, extensionService, editorsService, configurationService, editorTabs); } protected override createDebugAdapter(adapter: IAdapterDescriptor, session: ExtHostDebugSession): AbstractDebugAdapter | undefined { @@ -145,7 +147,7 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase { } protected createVariableResolver(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider): AbstractVariableResolverService { - return new ExtHostVariableResolverService(folders, editorService, configurationService, this._workspaceService); + return new ExtHostVariableResolverService(folders, editorService, configurationService, this._editorTabs, this._workspaceService); } } diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 8d6652775fa..1c0b73b77e5 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -23,6 +23,7 @@ import { ExtHostTaskBase, TaskHandleDTO, TaskDTO, CustomExecutionDTO, HandlerDat import { Schemas } from 'vs/base/common/network'; import { ILogService } from 'vs/platform/log/common/log'; import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService'; +import { IExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs'; export class ExtHostTask extends ExtHostTaskBase { private _variableResolver: ExtHostVariableResolverService | undefined; @@ -35,7 +36,8 @@ export class ExtHostTask extends ExtHostTaskBase { @IExtHostConfiguration configurationService: IExtHostConfiguration, @IExtHostTerminalService extHostTerminalService: IExtHostTerminalService, @ILogService logService: ILogService, - @IExtHostApiDeprecationService deprecationService: IExtHostApiDeprecationService + @IExtHostApiDeprecationService deprecationService: IExtHostApiDeprecationService, + @IExtHostEditorTabs private readonly editorTabs: IExtHostEditorTabs ) { super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService, logService, deprecationService); if (initData.remote.isRemote && initData.remote.authority) { @@ -127,7 +129,7 @@ export class ExtHostTask extends ExtHostTaskBase { private async getVariableResolver(workspaceFolders: vscode.WorkspaceFolder[]): Promise { if (this._variableResolver === undefined) { const configProvider = await this._configurationService.getConfigProvider(); - this._variableResolver = new ExtHostVariableResolverService(workspaceFolders, this._editorService, configProvider, this.workspaceService); + this._variableResolver = new ExtHostVariableResolverService(workspaceFolders, this._editorService, configProvider, this.editorTabs, this.workspaceService); } return this._variableResolver; } diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 6cd875992d2..bcc42ad685c 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -14,6 +14,7 @@ import { IShellAndArgsDto } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfigProvider, ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { ExtHostVariableResolverService } from 'vs/workbench/api/common/extHostDebugService'; import { ExtHostDocumentsAndEditors, IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; +import { IExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { BaseExtHostTerminalService, ExtHostTerminal } from 'vs/workbench/api/common/extHostTerminalService'; import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; @@ -35,7 +36,8 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { @IExtHostConfiguration private _extHostConfiguration: ExtHostConfiguration, @IExtHostWorkspace private _extHostWorkspace: ExtHostWorkspace, @IExtHostDocumentsAndEditors private _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors, - @ILogService private _logService: ILogService + @ILogService private _logService: ILogService, + @IExtHostEditorTabs private _extHostEditorTabs: IExtHostEditorTabs ) { super(true, extHostRpc); @@ -113,7 +115,7 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { private async _updateVariableResolver(): Promise { const configProvider = await this._extHostConfiguration.getConfigProvider(); const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); - this._variableResolver = new ExtHostVariableResolverService(workspaceFolders || [], this._extHostDocumentsAndEditors, configProvider); + this._variableResolver = new ExtHostVariableResolverService(workspaceFolders || [], this._extHostDocumentsAndEditors, configProvider, this._extHostEditorTabs); return this._variableResolver; }