From a869f863fd61a232f17b33251899add6293000b3 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 16 Aug 2021 10:48:06 -0700 Subject: [PATCH 01/24] start #45407 --- src/vs/platform/terminal/common/terminal.ts | 6 ++-- src/vs/vscode.proposed.d.ts | 34 +++++++++++++++++++ .../workbench/api/common/extHost.api.impl.ts | 4 +++ .../workbench/api/common/extHost.protocol.ts | 2 ++ .../api/common/extHostTerminalService.ts | 3 +- src/vs/workbench/api/common/extHostTypes.ts | 5 +++ .../terminal/browser/terminalActions.ts | 2 +- .../terminal/browser/terminalEditor.ts | 2 +- .../contrib/terminal/browser/terminalMenus.ts | 2 +- .../terminal/browser/terminalService.ts | 6 ++-- .../terminal/browser/terminalTabsList.ts | 2 +- .../contrib/terminal/browser/terminalView.ts | 9 +++-- .../terminal/common/terminalConfiguration.ts | 2 +- 13 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 11f01e129baca..fe078f9762d48 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -395,9 +395,9 @@ export interface ICreateContributedTerminalProfileOptions { isSplitTerminal?: boolean; } -export const enum TerminalLocation { - TerminalView = 'view', - Editor = 'editor' +export enum TerminalLocation { + Panel = 0, + Editor = 1, } export type TerminalIcon = ThemeIcon | URI | { light: URI; dark: URI }; diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 5b664caa6cdcb..e3d56edb55b88 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -917,6 +917,40 @@ declare module 'vscode' { readonly state: TerminalState; } + export interface TerminalOptions { + location?: TerminalLocation | TerminalEditorLocationOptions | TerminalSplitLocationOptions; + } + + export enum TerminalLocation { + Panel = 0, + Editor = 1, + } + + export interface TerminalEditorLocationOptions { + /** + * A view column in which the {@link Terminal terminal} should be shown in the editor area. + * Use {@link ViewColumn.Active active} to open in the active editor group, other values are + * adjusted to be `Min(column, columnCount + 1)`, the + * {@link ViewColumn.Active active}-column is not adjusted. Use + * {@linkcode ViewColumn.Beside} to open the editor to the side of the currently active one. + */ + viewColumn: ViewColumn; + /** + * An optional flag that when `true` will stop the {@link Terminal} from taking focus. + */ + preserveFocus?: boolean; + } + + export interface TerminalSplitLocationOptions { + /** + * The parent terminal to split this terminal beside. This works whether the parent terminal + * is in the panel or the editor area. + */ + parentTerminal: Terminal; + + // TODO: Do we need to specify a side? + } + /** * An event representing a change in a {@link Terminal.state terminal's state}. */ diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index b093f1fdf84f2..01111a744dc71 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -649,6 +649,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I if ('pty' in nameOrOptions) { return extHostTerminalService.createExtensionTerminal(nameOrOptions); } + if (nameOrOptions.location) { + checkProposedApiEnabled(extension); + } return extHostTerminalService.createTerminalFromOptions(nameOrOptions); } return extHostTerminalService.createTerminal(nameOrOptions, shellPath, shellArgs); @@ -1234,6 +1237,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I TaskRevealKind: extHostTypes.TaskRevealKind, TaskScope: extHostTypes.TaskScope, TerminalLink: extHostTypes.TerminalLink, + TerminalLocation: extHostTypes.TerminalLocation, TerminalProfile: extHostTypes.TerminalProfile, TextDocumentSaveReason: extHostTypes.TextDocumentSaveReason, TextEdit: extHostTypes.TextEdit, diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index eaf0a2e9c0871..c8e8fb5429026 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -69,6 +69,7 @@ import { createExtHostContextProxyIdentifier as createExtId, createMainContextPr import { CandidatePort } from 'vs/workbench/services/remote/common/remoteExplorerService'; import * as search from 'vs/workbench/services/search/common/search'; import * as statusbar from 'vs/workbench/services/statusbar/common/statusbar'; +import { TerminalEditorLocationOptions, TerminalSplitLocationOptions } from 'vscode'; export interface IEnvironment { isExtensionDevelopmentDebug: boolean; @@ -487,6 +488,7 @@ export interface TerminalLaunchConfig { useShellEnvironment?: boolean; isSplitTerminal?: boolean; target?: TerminalLocation; + location?: TerminalLocation | TerminalEditorLocationOptions | TerminalSplitLocationOptions; } export interface MainThreadTerminalServiceShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 5fc90fbe530cd..4e35bb13bdea2 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -148,7 +148,8 @@ export class ExtHostTerminal { isExtensionOwnedTerminal: true, useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), isSplitTerminal: internalOptions?.isSplitTerminal, - target: internalOptions?.target + target: internalOptions?.target, + location: withNullAsUndefined(options.location) }); } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index f1f9795d7f2a2..8c18ecb0a8a83 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -1735,6 +1735,11 @@ export class TerminalLink implements vscode.TerminalLink { } } +export enum TerminalLocation { + Panel = 0, + Editor = 1, +} + export class TerminalProfile implements vscode.TerminalProfile { constructor( public options: vscode.TerminalOptions | vscode.ExtensionTerminalOptions diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 5b1356ad766c1..4688ee9bab942 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -386,7 +386,7 @@ export function registerTerminalActions() { async run(accessor: ServicesAccessor) { const terminalService = accessor.get(ITerminalService); const terminalGroupService = accessor.get(ITerminalGroupService); - const instance = terminalService.activeInstance || await terminalService.createTerminal({ target: TerminalLocation.TerminalView }); + const instance = terminalService.activeInstance || await terminalService.createTerminal({ target: TerminalLocation.Panel }); if (!instance) { return; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts index 3b96d099d469d..5378eddcc561a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts @@ -16,7 +16,6 @@ import { IEditorOptions } from 'vs/platform/editor/common/editor'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { TerminalLocation } from 'vs/platform/terminal/common/terminal'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; import { IEditorOpenContext } from 'vs/workbench/common/editor'; @@ -32,6 +31,7 @@ import { BrowserFeatures } from 'vs/base/browser/canIUse'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { openContextMenu } from 'vs/workbench/contrib/terminal/browser/terminalContextMenu'; import { ICommandService } from 'vs/platform/commands/common/commands'; +import { TerminalLocation } from 'vs/platform/terminal/common/terminal'; const findWidgetSelector = '.simple-find-part-wrapper'; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts index 0468c8df956d3..2832106623e63 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts @@ -651,7 +651,7 @@ export function getTerminalActionBarArgs(target: TerminalLocation, profiles: ITe const primaryAction = instantiationService.createInstance( MenuItemAction, { - id: target === TerminalLocation.TerminalView ? TerminalCommandId.New : TerminalCommandId.CreateTerminalEditor, + id: target === TerminalLocation.Panel ? TerminalCommandId.New : TerminalCommandId.CreateTerminalEditor, title: localize('terminal.new', "New Terminal"), icon: Codicon.plus }, diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 81a714f9ef134..9d0471665e083 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -412,7 +412,7 @@ export class TerminalService implements ITerminalService { // create group and terminal terminalInstance = await this.createTerminal({ config: { attachPersistentProcess: terminalLayout.terminal! }, - target: TerminalLocation.TerminalView + target: TerminalLocation.Panel }); group = this._terminalGroupService.getGroupForInstance(terminalInstance); if (groupLayout.isActive) { @@ -646,7 +646,7 @@ export class TerminalService implements ITerminalService { await this._localTerminalsInitPromise; } if (this._terminalGroupService.groups.length === 0 && this.isProcessSupportRegistered) { - this.createTerminal({ target: TerminalLocation.TerminalView }); + this.createTerminal({ target: TerminalLocation.Panel }); } } @@ -679,7 +679,7 @@ export class TerminalService implements ITerminalService { if (source.target !== TerminalLocation.Editor) { return; } - source.target = TerminalLocation.TerminalView; + source.target = TerminalLocation.Panel; let group: ITerminalGroup | undefined; if (target) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts b/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts index ee3fc4f730cb4..2d327e652a6cb 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts @@ -131,7 +131,7 @@ export class TerminalTabList extends WorkbenchList { this.onMouseDblClick(async e => { const focus = this.getFocus(); if (focus.length === 0) { - const instance = await this._terminalService.createTerminal({ target: TerminalLocation.TerminalView }); + const instance = await this._terminalService.createTerminal({ target: TerminalLocation.Panel }); this._terminalGroupService.setActiveInstance(instance); await instance.focusWhenReady(); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalView.ts b/src/vs/workbench/contrib/terminal/browser/terminalView.ts index e6d7737c1bce4..f138d2a4050fd 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalView.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalView.ts @@ -136,7 +136,7 @@ export class TerminalViewPane extends ViewPane { if (this._terminalService.isProcessSupportRegistered) { if (this._terminalsInitialized) { if (!hadTerminals) { - this._terminalService.createTerminal({ target: TerminalLocation.TerminalView }); + this._terminalService.createTerminal({ target: TerminalLocation.Panel }); } } else { this._terminalsInitialized = true; @@ -204,8 +204,7 @@ export class TerminalViewPane extends ViewPane { this._tabButtons.dispose(); } - const actions = getTerminalActionBarArgs(TerminalLocation.TerminalView, this._terminalService.availableProfiles, this._getDefaultProfileName(), this._terminalContributionService.terminalProfiles, this._instantiationService, this._terminalService, this._contextKeyService, this._commandService, this._dropdownMenu); - + const actions = getTerminalActionBarArgs(TerminalLocation.Panel, this._terminalService.availableProfiles, this._getDefaultProfileName(), this._terminalContributionService.terminalProfiles, this._instantiationService, this._terminalService, this._contextKeyService, this._commandService, this._dropdownMenu); this._tabButtons = new DropdownWithPrimaryActionViewItem(actions.primaryAction, actions.dropdownAction, actions.dropdownMenuActions, actions.className, this._contextMenuService, {}, this._keybindingService, this._notificationService, this._contextKeyService); this._updateTabActionBar(this._terminalService.availableProfiles); return this._tabButtons; @@ -229,7 +228,7 @@ export class TerminalViewPane extends ViewPane { } private _updateTabActionBar(profiles: ITerminalProfile[]): void { - const actions = getTerminalActionBarArgs(TerminalLocation.TerminalView, profiles, this._getDefaultProfileName(), this._terminalContributionService.terminalProfiles, this._instantiationService, this._terminalService, this._contextKeyService, this._commandService, this._dropdownMenu); + const actions = getTerminalActionBarArgs(TerminalLocation.Panel, profiles, this._getDefaultProfileName(), this._terminalContributionService.terminalProfiles, this._instantiationService, this._terminalService, this._contextKeyService, this._commandService, this._dropdownMenu); this._tabButtons?.update(actions.dropdownAction, actions.dropdownMenuActions); } @@ -388,7 +387,7 @@ class SingleTerminalTabActionViewItem extends MenuEntryActionViewItem { override async onClick(event: MouseEvent): Promise { if (event.altKey && this._menuItemAction.alt) { - this._commandService.executeCommand(this._menuItemAction.alt.id, { target: TerminalLocation.TerminalView } as ICreateTerminalOptions); + this._commandService.executeCommand(this._menuItemAction.alt.id, { target: TerminalLocation.Panel } as ICreateTerminalOptions); } else { this._openContextMenu(); } diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 6d6c24c9c30e2..b601aeb16f252 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -78,7 +78,7 @@ const terminalConfiguration: IConfigurationNode = { }, [TerminalSettingId.DefaultLocation]: { type: 'string', - enum: [TerminalLocation.Editor, TerminalLocation.TerminalView], + enum: [TerminalLocation.Editor, TerminalLocation.Panel], enumDescriptions: [ localize('terminal.integrated.defaultLocation.editor', "Create terminals in the editor"), localize('terminal.integrated.defaultLocation.view', "Create terminals in the terminal view") From feb96c259e7cd27a2a00225d7db7d34d90a3041f Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 16 Aug 2021 11:50:06 -0700 Subject: [PATCH 02/24] add editorOptions --- .../api/browser/mainThreadTerminalService.ts | 3 +- .../contrib/terminal/browser/terminal.ts | 9 +++- .../terminal/browser/terminalEditorService.ts | 12 +++-- .../terminal/browser/terminalService.ts | 49 ++++++++++++++++--- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 54703b9df717b..2aa81cc7d61c4 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -150,7 +150,8 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape if (!terminal) { terminal = await this._terminalService.createTerminal({ config: shellLaunchConfig, - target: launchConfig.target + target: launchConfig.target, + location: launchConfig.location }); } r(terminal); diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index cf02ed3a46396..9490fb3587736 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -20,6 +20,7 @@ import { Orientation } from 'vs/base/browser/ui/splitview/splitview'; import { IEditableData } from 'vs/workbench/common/views'; import { DeserializedTerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorSerializer'; import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput'; +import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; export const ITerminalService = createDecorator('terminalService'); export const ITerminalEditorService = createDecorator('terminalEditorService'); @@ -201,7 +202,7 @@ export interface ITerminalEditorService extends ITerminalInstanceHost, ITerminal openEditor(instance: ITerminalInstance, sideGroup?: boolean): Promise; detachActiveEditorInstance(): ITerminalInstance; detachInstance(instance: ITerminalInstance): void; - splitInstance(instanceToSplit: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig): ITerminalInstance; + splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig, editorOptions?: { viewColumn: EditorGroupColumn, preserveFocus?: boolean }): ITerminalInstance; revealActiveEditor(preserveFocus?: boolean): void; resolveResource(instance: ITerminalInstance | URI): URI; reviveInput(deserializedInput: DeserializedTerminalEditorInput): TerminalEditorInput; @@ -236,8 +237,14 @@ export interface ICreateTerminalOptions { * The terminal instance to split */ instanceToSplit?: ITerminalInstance; + + /** + * The location at which to create the terminal + */ + location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: any }; } + /** * This service is responsible for managing terminal groups, that is the terminals that are hosted * within the terminal panel, not in an editor. diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts index 1cd21d81fc364..6d03c91ebbb0f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts @@ -17,6 +17,7 @@ import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/termi import { DeserializedTerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorSerializer'; import { getInstanceFromResource, parseTerminalUri } from 'vs/workbench/contrib/terminal/browser/terminalUri'; import { ILocalTerminalService, IOffProcessTerminalService } from 'vs/workbench/contrib/terminal/common/terminal'; +import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; @@ -234,8 +235,8 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor return getInstanceFromResource(this.instances, resource); } - splitInstance(instanceToSplit: ITerminalInstance, shellLaunchConfig: IShellLaunchConfig = {}): ITerminalInstance { - if (instanceToSplit.target === TerminalLocation.Editor) { + splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig: IShellLaunchConfig = {}, editorOptions?: { viewColumn: EditorGroupColumn, preserveFocus?: boolean }): ITerminalInstance { + if (instanceToSplit?.target === TerminalLocation.Editor) { // Make sure the instance to split's group is active const group = this._editorInputs.get(instanceToSplit.resource.path)?.group; if (group) { @@ -250,10 +251,11 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor options: { pinned: true, - forceReload: true - } + forceReload: true, + preserveFocus: editorOptions?.preserveFocus + }, }, - SIDE_GROUP); + editorOptions?.viewColumn || SIDE_GROUP); } return instance; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 9d0471665e083..4b9fd9a502cde 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -43,6 +43,7 @@ import { ILocalTerminalService, IOffProcessTerminalService, IRemoteTerminalAttac import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; import { ITerminalContributionService } from 'vs/workbench/contrib/terminal/common/terminalExtensionPoints'; import { formatMessageForTerminal, terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; +import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -1164,18 +1165,27 @@ export class TerminalService implements ITerminalService { this._evaluateLocalCwd(shellLaunchConfig); let instance: ITerminalInstance; - const target = options?.target || this.configHelper.config.defaultLocation; - if (options?.instanceToSplit) { - if (target === TerminalLocation.Editor || options?.instanceToSplit?.target === TerminalLocation.Editor) { - instance = this._terminalEditorService.splitInstance(options.instanceToSplit, shellLaunchConfig); + + let target = options?.target || this._getLocation(options?.location) || this.configHelper.config.defaultLocation; + + const splitParent = this._getSplitParent(options?.target); + const parent = options?.instanceToSplit || splitParent; + + const editorOptions = this._getEditorOptions(options?.target); + + if (parent) { + if (target === TerminalLocation.Editor || parent.target === TerminalLocation.Editor) { + instance = this._terminalEditorService.splitInstance(parent, shellLaunchConfig); } else { - const group = this._terminalGroupService.getGroupForInstance(options.instanceToSplit); + const group = this._terminalGroupService.getGroupForInstance(parent); if (!group) { - throw new Error(`Cannot split a terminal without a group ${options.instanceToSplit}`); + throw new Error(`Cannot split a terminal without a group ${parent}`); } instance = group.split(shellLaunchConfig); this._terminalGroupService.groups.forEach((g, i) => g.setVisible(i === this._terminalGroupService.activeGroupIndex)); } + } else if (editorOptions) { + instance = this._terminalEditorService.splitInstance(undefined, shellLaunchConfig, editorOptions); } else { if (target === TerminalLocation.Editor) { instance = this._terminalInstanceService.createInstance(shellLaunchConfig, undefined, options?.resource); @@ -1190,6 +1200,33 @@ export class TerminalService implements ITerminalService { return instance; } + private _getLocation(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: { target: TerminalLocation, processId: number } }): TerminalLocation | undefined { + if (!location) { + return location; + } else if (typeof location === 'object' && 'parentTerminal' in location) { + return location.parentTerminal.target; + } else if (typeof location === 'object' && 'viewColumn' in location) { + // TODO - use + return TerminalLocation.Editor; + } + return location; + } + + private _getSplitParent(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: { target: TerminalLocation, processId: number } }): ITerminalInstance | undefined { + if (location && typeof location === 'object' && 'parentTerminal' in location) { + return this.instances.find(t => t.processId === location.parentTerminal.processId); + } + return undefined; + } + + + private _getEditorOptions(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: { target: TerminalLocation, processId: number } }): { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | undefined { + if (location && typeof location === 'object' && 'viewColumn' in location) { + return location; + } + return undefined; + } + private _evaluateLocalCwd(shellLaunchConfig: IShellLaunchConfig) { // Add welcome message and title annotation for local terminals launched within remote or // virtual workspaces From dc03c75e82c5dc580fc0697f6b5df30d8c50858d Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 16 Aug 2021 12:59:02 -0700 Subject: [PATCH 03/24] works for the basic case --- src/vs/vscode.proposed.d.ts | 4 ++++ .../workbench/api/common/extHost.api.impl.ts | 6 +++--- .../terminal/browser/terminalService.ts | 20 +++++++++---------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index e3d56edb55b88..06b2612f09dc4 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -921,6 +921,10 @@ declare module 'vscode' { location?: TerminalLocation | TerminalEditorLocationOptions | TerminalSplitLocationOptions; } + export interface ExtensionTerminalOptions { + location?: TerminalLocation | TerminalEditorLocationOptions | TerminalSplitLocationOptions; + } + export enum TerminalLocation { Panel = 0, Editor = 1, diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 01111a744dc71..bf22402b631fc 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -646,12 +646,12 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, createTerminal(nameOrOptions?: vscode.TerminalOptions | vscode.ExtensionTerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal { if (typeof nameOrOptions === 'object') { + if ('location' in nameOrOptions) { + checkProposedApiEnabled(extension); + } if ('pty' in nameOrOptions) { return extHostTerminalService.createExtensionTerminal(nameOrOptions); } - if (nameOrOptions.location) { - checkProposedApiEnabled(extension); - } return extHostTerminalService.createTerminalFromOptions(nameOrOptions); } return extHostTerminalService.createTerminal(nameOrOptions, shellPath, shellArgs); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 4b9fd9a502cde..5a79c41f33898 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -1141,15 +1141,6 @@ export class TerminalService implements ITerminalService { shellLaunchConfig.cwd = options.cwd; } - // Use the URI from the base instance if it exists, this will correctly split local terminals - if (options?.instanceToSplit && typeof shellLaunchConfig.cwd !== 'object' && typeof options.instanceToSplit.shellLaunchConfig.cwd === 'object') { - shellLaunchConfig.cwd = URI.from({ - scheme: options.instanceToSplit.shellLaunchConfig.cwd.scheme, - authority: options.instanceToSplit.shellLaunchConfig.cwd.authority, - path: shellLaunchConfig.cwd || options.instanceToSplit.shellLaunchConfig.cwd.path - }); - } - if (!shellLaunchConfig.customPtyImplementation && !this.isProcessSupportRegistered) { throw new Error('Could not create terminal when process support is not registered'); } @@ -1168,9 +1159,18 @@ export class TerminalService implements ITerminalService { let target = options?.target || this._getLocation(options?.location) || this.configHelper.config.defaultLocation; - const splitParent = this._getSplitParent(options?.target); + const splitParent = this._getSplitParent(options?.location); const parent = options?.instanceToSplit || splitParent; + // Use the URI from the base instance if it exists, this will correctly split local terminals + if (parent && typeof shellLaunchConfig.cwd !== 'object' && typeof parent.shellLaunchConfig.cwd === 'object') { + shellLaunchConfig.cwd = URI.from({ + scheme: parent.shellLaunchConfig.cwd.scheme, + authority: parent.shellLaunchConfig.cwd.authority, + path: shellLaunchConfig.cwd || parent.shellLaunchConfig.cwd.path + }); + } + const editorOptions = this._getEditorOptions(options?.target); if (parent) { From d52b5f39a2e77aa1151b21c7780eebeb42509717 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 16 Aug 2021 14:45:41 -0700 Subject: [PATCH 04/24] parentTerminal is a real terminal instance --- .../api/browser/mainThreadTerminalService.ts | 21 +++++++++++++- .../workbench/api/common/extHost.protocol.ts | 4 ++- .../api/common/extHostTerminalService.ts | 6 ++++ .../contrib/terminal/browser/terminal.ts | 2 +- .../terminal/browser/terminalService.ts | 28 +++++++++---------- 5 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 2aa81cc7d61c4..da5143d31a4c2 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -20,6 +20,7 @@ import { IStartExtensionTerminalRequest, ITerminalProcessExtHostProxy, ITerminal import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { withNullAsUndefined } from 'vs/base/common/types'; import { OperatingSystem, OS } from 'vs/base/common/platform'; +import { TerminalEditorLocationOptions, TerminalSplitLocationOptions } from 'vscode'; @extHostNamedCustomer(MainContext.MainThreadTerminalService) export class MainThreadTerminalService implements MainThreadTerminalServiceShape { @@ -151,13 +152,31 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape terminal = await this._terminalService.createTerminal({ config: shellLaunchConfig, target: launchConfig.target, - location: launchConfig.location + location: await this._getLocation(launchConfig.location) }); } r(terminal); })); } + private async _getLocation(location?: TerminalLocation | TerminalEditorLocationOptions | TerminalSplitLocationOptions): Promise { + if (!location) { + return location; + } else if (typeof location === 'object' && 'parentTerminal' in location) { + const extHostTerminal = await this._proxy.$getExtHostTerminal(location.parentTerminal); + if (extHostTerminal) { + const parentTerminal = await this._getTerminalInstance(extHostTerminal?._id); + return parentTerminal ? { parentTerminal } : undefined; + } else { + return undefined; + } + } else if (typeof location === 'object' && 'viewColumn' in location) { + // TODO - use + return TerminalLocation.Editor; + } + return location; + } + public async $show(id: TerminalIdentifier, preserveFocus: boolean): Promise { const terminalInstance = await this._getTerminalInstance(id); if (terminalInstance) { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index c8e8fb5429026..139bc06550a78 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -46,6 +46,7 @@ import { IExtensionIdWithVersion } from 'vs/platform/userDataSync/common/extensi import { WorkspaceTrustRequestOptions } from 'vs/platform/workspace/common/workspaceTrust'; import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtHostInteractive } from 'vs/workbench/api/common/extHostInteractive'; +import { ExtHostTerminal } from 'vs/workbench/api/common/extHostTerminalService'; import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService'; import { DebugConfigurationProviderTriggerKind } from 'vs/workbench/api/common/extHostTypes'; import * as tasks from 'vs/workbench/api/common/shared/tasks'; @@ -69,7 +70,7 @@ import { createExtHostContextProxyIdentifier as createExtId, createMainContextPr import { CandidatePort } from 'vs/workbench/services/remote/common/remoteExplorerService'; import * as search from 'vs/workbench/services/search/common/search'; import * as statusbar from 'vs/workbench/services/statusbar/common/statusbar'; -import { TerminalEditorLocationOptions, TerminalSplitLocationOptions } from 'vscode'; +import { Terminal, TerminalEditorLocationOptions, TerminalSplitLocationOptions } from 'vscode'; export interface IEnvironment { isExtensionDevelopmentDebug: boolean; @@ -1768,6 +1769,7 @@ export interface ExtHostTerminalServiceShape { $initEnvironmentVariableCollections(collections: [string, ISerializableEnvironmentVariableCollection][]): void; $acceptDefaultProfile(profile: ITerminalProfile, automationProfile: ITerminalProfile): void; $createContributedProfileTerminal(id: string, options: ICreateContributedTerminalProfileOptions): Promise; + $getExtHostTerminal(terminal: Terminal): Promise } export interface ExtHostSCMShape { diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 4e35bb13bdea2..dd386e0745fba 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -393,7 +393,9 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I terminal.createExtensionTerminal(internalOptions?.isSplitTerminal, internalOptions?.target, asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { const disposable = this._setupExtHostProcessListeners(id, p); this._terminalProcessDisposables[id] = disposable; + console.log(id); }); + console.log('returning', terminal.value); this._terminals.push(terminal); return terminal.value; } @@ -467,6 +469,10 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I } } + public async $getExtHostTerminal(terminal: vscode.Terminal): Promise { + return this._terminals.find(t => t.value === terminal); + } + public $acceptTerminalOpened(id: number, extHostTerminalId: string | undefined, name: string, shellLaunchConfigDto: IShellLaunchConfigDto): void { if (extHostTerminalId) { // Resolve with the renderer generated id diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 9490fb3587736..340554b148b33 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -241,7 +241,7 @@ export interface ICreateTerminalOptions { /** * The location at which to create the terminal */ - location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: any }; + location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: ITerminalInstance }; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 5a79c41f33898..747a9f5373a13 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -1157,23 +1157,22 @@ export class TerminalService implements ITerminalService { let instance: ITerminalInstance; - let target = options?.target || this._getLocation(options?.location) || this.configHelper.config.defaultLocation; + const target = options?.target || this._getLocation(options?.location) || this.configHelper.config.defaultLocation; const splitParent = this._getSplitParent(options?.location); const parent = options?.instanceToSplit || splitParent; - // Use the URI from the base instance if it exists, this will correctly split local terminals - if (parent && typeof shellLaunchConfig.cwd !== 'object' && typeof parent.shellLaunchConfig.cwd === 'object') { - shellLaunchConfig.cwd = URI.from({ - scheme: parent.shellLaunchConfig.cwd.scheme, - authority: parent.shellLaunchConfig.cwd.authority, - path: shellLaunchConfig.cwd || parent.shellLaunchConfig.cwd.path - }); - } - const editorOptions = this._getEditorOptions(options?.target); if (parent) { + // Use the URI from the base instance if it exists, this will correctly split local terminals + if (typeof shellLaunchConfig.cwd !== 'object' && typeof parent.shellLaunchConfig.cwd === 'object') { + shellLaunchConfig.cwd = URI.from({ + scheme: parent.shellLaunchConfig.cwd.scheme, + authority: parent.shellLaunchConfig.cwd.authority, + path: shellLaunchConfig.cwd || parent.shellLaunchConfig.cwd.path + }); + } if (target === TerminalLocation.Editor || parent.target === TerminalLocation.Editor) { instance = this._terminalEditorService.splitInstance(parent, shellLaunchConfig); } else { @@ -1200,7 +1199,7 @@ export class TerminalService implements ITerminalService { return instance; } - private _getLocation(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: { target: TerminalLocation, processId: number } }): TerminalLocation | undefined { + private _getLocation(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: ITerminalInstance }): TerminalLocation | undefined { if (!location) { return location; } else if (typeof location === 'object' && 'parentTerminal' in location) { @@ -1212,15 +1211,14 @@ export class TerminalService implements ITerminalService { return location; } - private _getSplitParent(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: { target: TerminalLocation, processId: number } }): ITerminalInstance | undefined { + private _getSplitParent(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: ITerminalInstance }): ITerminalInstance | undefined { if (location && typeof location === 'object' && 'parentTerminal' in location) { - return this.instances.find(t => t.processId === location.parentTerminal.processId); + return location.parentTerminal; } return undefined; } - - private _getEditorOptions(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: { target: TerminalLocation, processId: number } }): { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | undefined { + private _getEditorOptions(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: ITerminalInstance }): { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | undefined { if (location && typeof location === 'object' && 'viewColumn' in location) { return location; } From cf10cde5b38e78b2b6038cc67cb4bad53afde64c Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 16 Aug 2021 15:15:12 -0700 Subject: [PATCH 05/24] very ugly, but it works --- .../api/browser/mainThreadTerminalService.ts | 12 ++++++------ .../workbench/api/common/extHost.protocol.ts | 6 ++---- .../api/common/extHostTerminalService.ts | 19 ++++++++++++++++--- .../api/node/extHostTerminalService.ts | 8 ++++++++ 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index da5143d31a4c2..c264cbe730d72 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -20,7 +20,8 @@ import { IStartExtensionTerminalRequest, ITerminalProcessExtHostProxy, ITerminal import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { withNullAsUndefined } from 'vs/base/common/types'; import { OperatingSystem, OS } from 'vs/base/common/platform'; -import { TerminalEditorLocationOptions, TerminalSplitLocationOptions } from 'vscode'; +import { TerminalEditorLocationOptions } from 'vscode'; +import { ExtHostTerminal } from 'vs/workbench/api/common/extHostTerminalService'; @extHostNamedCustomer(MainContext.MainThreadTerminalService) export class MainThreadTerminalService implements MainThreadTerminalServiceShape { @@ -159,14 +160,13 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape })); } - private async _getLocation(location?: TerminalLocation | TerminalEditorLocationOptions | TerminalSplitLocationOptions): Promise { + private async _getLocation(location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }): Promise { if (!location) { return location; } else if (typeof location === 'object' && 'parentTerminal' in location) { - const extHostTerminal = await this._proxy.$getExtHostTerminal(location.parentTerminal); - if (extHostTerminal) { - const parentTerminal = await this._getTerminalInstance(extHostTerminal?._id); - return parentTerminal ? { parentTerminal } : undefined; + const t = await this._extHostTerminals.get(location.parentTerminal._id.toString()); + if (t) { + return { parentTerminal: t }; } else { return undefined; } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 139bc06550a78..cc817d742d864 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -46,7 +46,6 @@ import { IExtensionIdWithVersion } from 'vs/platform/userDataSync/common/extensi import { WorkspaceTrustRequestOptions } from 'vs/platform/workspace/common/workspaceTrust'; import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtHostInteractive } from 'vs/workbench/api/common/extHostInteractive'; -import { ExtHostTerminal } from 'vs/workbench/api/common/extHostTerminalService'; import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService'; import { DebugConfigurationProviderTriggerKind } from 'vs/workbench/api/common/extHostTypes'; import * as tasks from 'vs/workbench/api/common/shared/tasks'; @@ -70,7 +69,7 @@ import { createExtHostContextProxyIdentifier as createExtId, createMainContextPr import { CandidatePort } from 'vs/workbench/services/remote/common/remoteExplorerService'; import * as search from 'vs/workbench/services/search/common/search'; import * as statusbar from 'vs/workbench/services/statusbar/common/statusbar'; -import { Terminal, TerminalEditorLocationOptions, TerminalSplitLocationOptions } from 'vscode'; +import { TerminalEditorLocationOptions } from 'vscode'; export interface IEnvironment { isExtensionDevelopmentDebug: boolean; @@ -489,7 +488,7 @@ export interface TerminalLaunchConfig { useShellEnvironment?: boolean; isSplitTerminal?: boolean; target?: TerminalLocation; - location?: TerminalLocation | TerminalEditorLocationOptions | TerminalSplitLocationOptions; + location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: any }; } export interface MainThreadTerminalServiceShape extends IDisposable { @@ -1769,7 +1768,6 @@ export interface ExtHostTerminalServiceShape { $initEnvironmentVariableCollections(collections: [string, ISerializableEnvironmentVariableCollection][]): void; $acceptDefaultProfile(profile: ITerminalProfile, automationProfile: ITerminalProfile): void; $createContributedProfileTerminal(id: string, options: ICreateContributedTerminalProfileOptions): Promise; - $getExtHostTerminal(terminal: Terminal): Promise } export interface ExtHostSCMShape { diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index dd386e0745fba..f1a904a2484a4 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -53,6 +53,7 @@ export interface ITerminalInternalOptions { useShellEnvironment?: boolean; isSplitTerminal?: boolean; target?: TerminalLocation; + parentTerminal?: ExtHostTerminal; } export const IExtHostTerminalService = createDecorator('IExtHostTerminalService'); @@ -149,10 +150,24 @@ export class ExtHostTerminal { useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), isSplitTerminal: internalOptions?.isSplitTerminal, target: internalOptions?.target, - location: withNullAsUndefined(options.location) + location: this._getLocation(internalOptions?.parentTerminal, withNullAsUndefined(options.location)) }); } + + + private _getLocation(terminal?: ExtHostTerminal, location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal } | undefined { + if (!location) { + return location; + } else if (typeof location === 'object' && 'parentTerminal' in location) { + return terminal ? { parentTerminal: terminal } : undefined; + } else if (typeof location === 'object' && 'viewColumn' in location) { + // TODO - use + return TerminalLocation.Editor; + } + return location; + } + public async createExtensionTerminal(isSplitTerminal?: boolean, target?: TerminalLocation, iconPath?: TerminalIcon, color?: ThemeColor): Promise { if (typeof this._id !== 'string') { throw new Error('Terminal has already been created'); @@ -393,9 +408,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I terminal.createExtensionTerminal(internalOptions?.isSplitTerminal, internalOptions?.target, asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { const disposable = this._setupExtHostProcessListeners(id, p); this._terminalProcessDisposables[id] = disposable; - console.log(id); }); - console.log('returning', terminal.value); this._terminals.push(terminal); return terminal.value; } diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 652223e1a45ed..69ae9c1c5ed28 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -23,6 +23,14 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { public createTerminalFromOptions(options: vscode.TerminalOptions, internalOptions?: ITerminalInternalOptions): vscode.Terminal { const terminal = new ExtHostTerminal(this._proxy, generateUuid(), options, options.name); this._terminals.push(terminal); + if (options.location && typeof options.location === 'object' && 'parentTerminal' in options.location) { + const p = options.location.parentTerminal; + if (p) { + const t = this._terminals.find(t => t.value === p); + internalOptions = internalOptions ? internalOptions : {}; + internalOptions.parentTerminal = t; + } + } terminal.create(options, internalOptions); return terminal.value; } From aa458e043d9ce9c048ab15a4146489ec03b1ed3d Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 17 Aug 2021 08:58:50 -0700 Subject: [PATCH 06/24] clean up --- .../api/browser/mainThreadTerminalService.ts | 9 ++++----- src/vs/workbench/api/common/extHost.protocol.ts | 3 ++- .../api/common/extHostTerminalService.ts | 16 +++++----------- .../workbench/api/node/extHostTerminalService.ts | 8 ++++---- .../contrib/terminal/browser/terminal.ts | 8 ++++++-- .../contrib/terminal/browser/terminalService.ts | 15 ++++++--------- 6 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index c264cbe730d72..1f60a325f0b26 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -164,15 +164,14 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape if (!location) { return location; } else if (typeof location === 'object' && 'parentTerminal' in location) { - const t = await this._extHostTerminals.get(location.parentTerminal._id.toString()); - if (t) { - return { parentTerminal: t }; + const parentTerminal = await this._extHostTerminals.get(location.parentTerminal._id.toString()); + if (parentTerminal) { + return { parentTerminal }; } else { return undefined; } } else if (typeof location === 'object' && 'viewColumn' in location) { - // TODO - use - return TerminalLocation.Editor; + return location; } return location; } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index cc817d742d864..c0a654b107d2e 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -46,6 +46,7 @@ import { IExtensionIdWithVersion } from 'vs/platform/userDataSync/common/extensi import { WorkspaceTrustRequestOptions } from 'vs/platform/workspace/common/workspaceTrust'; import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtHostInteractive } from 'vs/workbench/api/common/extHostInteractive'; +import { ExtHostTerminal } from 'vs/workbench/api/common/extHostTerminalService'; import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService'; import { DebugConfigurationProviderTriggerKind } from 'vs/workbench/api/common/extHostTypes'; import * as tasks from 'vs/workbench/api/common/shared/tasks'; @@ -488,7 +489,7 @@ export interface TerminalLaunchConfig { useShellEnvironment?: boolean; isSplitTerminal?: boolean; target?: TerminalLocation; - location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: any }; + location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }; } export interface MainThreadTerminalServiceShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index f1a904a2484a4..d10466c7a8b3e 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -150,20 +150,18 @@ export class ExtHostTerminal { useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), isSplitTerminal: internalOptions?.isSplitTerminal, target: internalOptions?.target, - location: this._getLocation(internalOptions?.parentTerminal, withNullAsUndefined(options.location)) + location: this._getLocation(withNullAsUndefined(options.location), internalOptions?.parentTerminal) }); } - - - private _getLocation(terminal?: ExtHostTerminal, location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal } | undefined { + private _getLocation(location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminal): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal } | undefined { if (!location) { return location; } else if (typeof location === 'object' && 'parentTerminal' in location) { - return terminal ? { parentTerminal: terminal } : undefined; + // use the ExtHostTerminal with value = to the parentTerminal + return parentTerminal ? { parentTerminal } : undefined; } else if (typeof location === 'object' && 'viewColumn' in location) { - // TODO - use - return TerminalLocation.Editor; + return location; } return location; } @@ -482,10 +480,6 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I } } - public async $getExtHostTerminal(terminal: vscode.Terminal): Promise { - return this._terminals.find(t => t.value === terminal); - } - public $acceptTerminalOpened(id: number, extHostTerminalId: string | undefined, name: string, shellLaunchConfigDto: IShellLaunchConfigDto): void { if (extHostTerminalId) { // Resolve with the renderer generated id diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 69ae9c1c5ed28..a4de15922fee9 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -24,11 +24,11 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { const terminal = new ExtHostTerminal(this._proxy, generateUuid(), options, options.name); this._terminals.push(terminal); if (options.location && typeof options.location === 'object' && 'parentTerminal' in options.location) { - const p = options.location.parentTerminal; - if (p) { - const t = this._terminals.find(t => t.value === p); + const parentTerminal = options.location.parentTerminal; + if (parentTerminal) { + const parentExtHostTerminal = this._terminals.find(t => t.value === parentTerminal); internalOptions = internalOptions ? internalOptions : {}; - internalOptions.parentTerminal = t; + internalOptions.parentTerminal = parentExtHostTerminal; } } terminal.create(options, internalOptions); diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 340554b148b33..722fa54da4d64 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -202,7 +202,7 @@ export interface ITerminalEditorService extends ITerminalInstanceHost, ITerminal openEditor(instance: ITerminalInstance, sideGroup?: boolean): Promise; detachActiveEditorInstance(): ITerminalInstance; detachInstance(instance: ITerminalInstance): void; - splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig, editorOptions?: { viewColumn: EditorGroupColumn, preserveFocus?: boolean }): ITerminalInstance; + splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig, editorOptions?: TerminalEditorLocation): ITerminalInstance; revealActiveEditor(preserveFocus?: boolean): void; resolveResource(instance: ITerminalInstance | URI): URI; reviveInput(deserializedInput: DeserializedTerminalEditorInput): TerminalEditorInput; @@ -241,9 +241,13 @@ export interface ICreateTerminalOptions { /** * The location at which to create the terminal */ - location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: ITerminalInstance }; + location?: TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }; } +export interface TerminalEditorLocation { + viewColumn: EditorGroupColumn, + preserveFocus?: boolean +} /** * This service is responsible for managing terminal groups, that is the terminals that are hosted diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 747a9f5373a13..8116803028f99 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -31,7 +31,7 @@ import { ColorScheme } from 'vs/platform/theme/common/theme'; import { IThemeService, Themable, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { VirtualWorkspaceContext } from 'vs/workbench/browser/contextkeys'; import { IEditableData, IViewsService } from 'vs/workbench/common/views'; -import { ICreateTerminalOptions, IRemoteTerminalService, IRequestAddInstanceToGroupEvent, ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalFindHost, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceHost, ITerminalInstanceService, ITerminalProfileProvider, ITerminalService, TerminalConnectionState } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ICreateTerminalOptions, IRemoteTerminalService, IRequestAddInstanceToGroupEvent, ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalFindHost, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceHost, ITerminalInstanceService, ITerminalProfileProvider, ITerminalService, TerminalConnectionState, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal'; import { refreshTerminalActions } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalEditor } from 'vs/workbench/contrib/terminal/browser/terminalEditor'; @@ -43,7 +43,6 @@ import { ILocalTerminalService, IOffProcessTerminalService, IRemoteTerminalAttac import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; import { ITerminalContributionService } from 'vs/workbench/contrib/terminal/common/terminalExtensionPoints'; import { formatMessageForTerminal, terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; -import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -1157,10 +1156,9 @@ export class TerminalService implements ITerminalService { let instance: ITerminalInstance; - const target = options?.target || this._getLocation(options?.location) || this.configHelper.config.defaultLocation; + const target = options?.target || this._getTarget(options?.location) || this.configHelper.config.defaultLocation; - const splitParent = this._getSplitParent(options?.location); - const parent = options?.instanceToSplit || splitParent; + const parent = options?.instanceToSplit || this._getSplitParent(options?.location); const editorOptions = this._getEditorOptions(options?.target); @@ -1199,26 +1197,25 @@ export class TerminalService implements ITerminalService { return instance; } - private _getLocation(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: ITerminalInstance }): TerminalLocation | undefined { + private _getTarget(location?: TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }): TerminalLocation | undefined { if (!location) { return location; } else if (typeof location === 'object' && 'parentTerminal' in location) { return location.parentTerminal.target; } else if (typeof location === 'object' && 'viewColumn' in location) { - // TODO - use return TerminalLocation.Editor; } return location; } - private _getSplitParent(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: ITerminalInstance }): ITerminalInstance | undefined { + private _getSplitParent(location?: TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }): ITerminalInstance | undefined { if (location && typeof location === 'object' && 'parentTerminal' in location) { return location.parentTerminal; } return undefined; } - private _getEditorOptions(location?: TerminalLocation | { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | { parentTerminal: ITerminalInstance }): { viewColumn: EditorGroupColumn, preserveFocus?: boolean } | undefined { + private _getEditorOptions(location?: TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }): TerminalEditorLocation | undefined { if (location && typeof location === 'object' && 'viewColumn' in location) { return location; } From 0142818eb519298c7074718bbc5429d4fd78c5ea Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 17 Aug 2021 10:37:29 -0700 Subject: [PATCH 07/24] get rid of target --- .../api/browser/mainThreadTerminalService.ts | 1 - .../contrib/terminal/browser/terminal.ts | 4 ---- .../contrib/terminal/browser/terminalActions.ts | 14 +++++++------- .../terminal/browser/terminalEditorService.ts | 1 + .../contrib/terminal/browser/terminalMenus.ts | 12 ++++++------ .../contrib/terminal/browser/terminalService.ts | 16 ++++++++-------- .../contrib/terminal/browser/terminalTabsList.ts | 2 +- .../contrib/terminal/browser/terminalView.ts | 2 +- 8 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 1f60a325f0b26..8f95dd97d3076 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -152,7 +152,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape if (!terminal) { terminal = await this._terminalService.createTerminal({ config: shellLaunchConfig, - target: launchConfig.target, location: await this._getLocation(launchConfig.location) }); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 722fa54da4d64..5188811cd4239 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -220,10 +220,6 @@ export interface ICreateTerminalOptions { * specified. */ cwd?: string | URI; - /** - * Where to create the terminal, when not specified the default target will be used. - */ - target?: TerminalLocation; /** * Creates a split terminal without requiring a terminal instance to split, for example when splitting * a terminal editor diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 4688ee9bab942..083afbd697335 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -122,7 +122,7 @@ export function registerTerminalActions() { const terminalService = accessor.get(ITerminalService); const terminalGroupService = accessor.get(ITerminalGroupService); if (terminalService.isProcessSupportRegistered) { - const instance = await terminalService.createTerminal({ target: terminalService.configHelper.config.defaultLocation }); + const instance = await terminalService.createTerminal({ location: terminalService.configHelper.config.defaultLocation }); if (!instance) { return; } @@ -148,7 +148,7 @@ export function registerTerminalActions() { async run(accessor: ServicesAccessor) { const terminalService = accessor.get(ITerminalService); const instance = await terminalService.createTerminal({ - target: TerminalLocation.Editor + location: TerminalLocation.Editor }); instance.focusWhenReady(); } @@ -167,7 +167,7 @@ export function registerTerminalActions() { async run(accessor: ServicesAccessor) { const terminalService = accessor.get(ITerminalService); const instance = await terminalService.createTerminal({ - target: TerminalLocation.Editor, + location: TerminalLocation.Editor, forceSplit: true }); instance.focusWhenReady(); @@ -386,7 +386,7 @@ export function registerTerminalActions() { async run(accessor: ServicesAccessor) { const terminalService = accessor.get(ITerminalService); const terminalGroupService = accessor.get(ITerminalGroupService); - const instance = terminalService.activeInstance || await terminalService.createTerminal({ target: TerminalLocation.Panel }); + const instance = terminalService.activeInstance || await terminalService.createTerminal({ location: TerminalLocation.Panel }); if (!instance) { return; } @@ -1425,7 +1425,7 @@ export function registerTerminalActions() { const terminalService = accessor.get(ITerminalService); const workspaceContextService = accessor.get(IWorkspaceContextService); const options = convertOptionsOrProfileToOptions(optionsOrProfile); - const activeInstance = terminalService.getInstanceHost(options?.target).activeInstance; + const activeInstance = terminalService.getInstanceHost(options?.location === TerminalLocation.Editor ? TerminalLocation.Editor : TerminalLocation.Panel).activeInstance; if (!activeInstance) { return; } @@ -1433,7 +1433,7 @@ export function registerTerminalActions() { if (cwd === undefined) { return undefined; } - const instance = await terminalService.createTerminal({ instanceToSplit: activeInstance, config: options?.config, cwd, target: activeInstance.target }); + const instance = await terminalService.createTerminal({ instanceToSplit: activeInstance, config: options?.config, cwd, location: activeInstance.target }); if (instance) { if (instance.target === TerminalLocation.Editor) { instance.focusWhenReady(); @@ -1620,7 +1620,7 @@ export function registerTerminalActions() { if (terminalService.isProcessSupportRegistered) { eventOrOptions = !eventOrOptions || eventOrOptions instanceof MouseEvent ? {} : eventOrOptions; - eventOrOptions.target = eventOrOptions.target || terminalService.configHelper.config.defaultLocation; + eventOrOptions.location = eventOrOptions.location || terminalService.configHelper.config.defaultLocation; let instance: ITerminalInstance | undefined; if (folders.length <= 1) { // Allow terminal service to handle the path when there is only a diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts index 6d03c91ebbb0f..44a913b523145 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts @@ -236,6 +236,7 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor } splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig: IShellLaunchConfig = {}, editorOptions?: { viewColumn: EditorGroupColumn, preserveFocus?: boolean }): ITerminalInstance { + console.log(editorOptions); if (instanceToSplit?.target === TerminalLocation.Editor) { // Make sure the instance to split's group is active const group = this._editorInputs.get(instanceToSplit.resource.path)?.group; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts index 2832106623e63..3db9fb8312177 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts @@ -571,7 +571,7 @@ export function setupTerminalMenus(): void { }); } -export function getTerminalActionBarArgs(target: TerminalLocation, profiles: ITerminalProfile[], defaultProfileName: string, contributedProfiles: readonly IExtensionTerminalProfile[], instantiationService: IInstantiationService, terminalService: ITerminalService, contextKeyService: IContextKeyService, commandService: ICommandService, dropdownMenu: IMenu): { +export function getTerminalActionBarArgs(location: TerminalLocation, profiles: ITerminalProfile[], defaultProfileName: string, contributedProfiles: readonly IExtensionTerminalProfile[], instantiationService: IInstantiationService, terminalService: ITerminalService, contextKeyService: IContextKeyService, commandService: ICommandService, dropdownMenu: IMenu): { primaryAction: MenuItemAction, dropdownAction: IAction, dropdownMenuActions: IAction[], @@ -586,7 +586,7 @@ export function getTerminalActionBarArgs(target: TerminalLocation, profiles: ITe const options: IMenuActionOptions = { arg: { config: p, - target + location } as ICreateTerminalOptions, shouldForwardArgs: true }; @@ -609,7 +609,7 @@ export function getTerminalActionBarArgs(target: TerminalLocation, profiles: ITe title }, forceSplit: false, - target + location }))); submenuActions.push(new Action(TerminalCommandId.NewWithProfile, title, undefined, true, () => terminalService.createTerminal({ config: { @@ -618,7 +618,7 @@ export function getTerminalActionBarArgs(target: TerminalLocation, profiles: ITe title }, forceSplit: true, - target + location }))); } @@ -651,7 +651,7 @@ export function getTerminalActionBarArgs(target: TerminalLocation, profiles: ITe const primaryAction = instantiationService.createInstance( MenuItemAction, { - id: target === TerminalLocation.Panel ? TerminalCommandId.New : TerminalCommandId.CreateTerminalEditor, + id: location === TerminalLocation.Panel ? TerminalCommandId.New : TerminalCommandId.CreateTerminalEditor, title: localize('terminal.new', "New Terminal"), icon: Codicon.plus }, @@ -662,7 +662,7 @@ export function getTerminalActionBarArgs(target: TerminalLocation, profiles: ITe }, { shouldForwardArgs: true, - arg: { target } as ICreateTerminalOptions, + arg: { target: location } as ICreateTerminalOptions, }); const dropdownAction = new Action('refresh profiles', 'Launch Profile...', 'codicon-chevron-down', true); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 8116803028f99..7133029a83395 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -412,7 +412,7 @@ export class TerminalService implements ITerminalService { // create group and terminal terminalInstance = await this.createTerminal({ config: { attachPersistentProcess: terminalLayout.terminal! }, - target: TerminalLocation.Panel + location: TerminalLocation.Panel }); group = this._terminalGroupService.getGroupForInstance(terminalInstance); if (groupLayout.isActive) { @@ -646,7 +646,7 @@ export class TerminalService implements ITerminalService { await this._localTerminalsInitPromise; } if (this._terminalGroupService.groups.length === 0 && this.isProcessSupportRegistered) { - this.createTerminal({ target: TerminalLocation.Panel }); + this.createTerminal({ location: TerminalLocation.Panel }); } } @@ -946,7 +946,7 @@ export class TerminalService implements ITerminalService { // create split, only valid if there's an active instance instance = await this.createTerminal({ instanceToSplit: activeInstance, config: value.profile }); } else { - instance = await this.createTerminal({ target: this.configHelper.config.defaultLocation, config: value.profile, cwd }); + instance = await this.createTerminal({ location: this.configHelper.config.defaultLocation, config: value.profile, cwd }); } } @@ -1127,10 +1127,10 @@ export class TerminalService implements ITerminalService { await this._createContributedTerminalProfile(contributedProfile.extensionIdentifier, contributedProfile.id, { isSplitTerminal: options?.forceSplit || !!options?.instanceToSplit, icon: contributedProfile.icon, - target: options?.target, + target: options?.location === TerminalLocation.Editor ? TerminalLocation.Editor : TerminalLocation.Panel, color: contributedProfile.color }); - const instanceHost = options?.target === TerminalLocation.Editor ? this._terminalEditorService : this._terminalGroupService; + const instanceHost = options?.location === TerminalLocation.Editor ? this._terminalEditorService : this._terminalGroupService; const instance = instanceHost.instances[instanceHost.instances.length - 1]; await instance.focusWhenReady(); return instance; @@ -1156,11 +1156,11 @@ export class TerminalService implements ITerminalService { let instance: ITerminalInstance; - const target = options?.target || this._getTarget(options?.location) || this.configHelper.config.defaultLocation; + const target = this._getLocation(options?.location) || this.configHelper.config.defaultLocation; const parent = options?.instanceToSplit || this._getSplitParent(options?.location); - const editorOptions = this._getEditorOptions(options?.target); + const editorOptions = this._getEditorOptions(options?.location); if (parent) { // Use the URI from the base instance if it exists, this will correctly split local terminals @@ -1197,7 +1197,7 @@ export class TerminalService implements ITerminalService { return instance; } - private _getTarget(location?: TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }): TerminalLocation | undefined { + private _getLocation(location?: TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }): TerminalLocation | undefined { if (!location) { return location; } else if (typeof location === 'object' && 'parentTerminal' in location) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts b/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts index 2d327e652a6cb..903d6492599d7 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts @@ -131,7 +131,7 @@ export class TerminalTabList extends WorkbenchList { this.onMouseDblClick(async e => { const focus = this.getFocus(); if (focus.length === 0) { - const instance = await this._terminalService.createTerminal({ target: TerminalLocation.Panel }); + const instance = await this._terminalService.createTerminal({ location: TerminalLocation.Panel }); this._terminalGroupService.setActiveInstance(instance); await instance.focusWhenReady(); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalView.ts b/src/vs/workbench/contrib/terminal/browser/terminalView.ts index f138d2a4050fd..6780b5763c860 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalView.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalView.ts @@ -136,7 +136,7 @@ export class TerminalViewPane extends ViewPane { if (this._terminalService.isProcessSupportRegistered) { if (this._terminalsInitialized) { if (!hadTerminals) { - this._terminalService.createTerminal({ target: TerminalLocation.Panel }); + this._terminalService.createTerminal({ location: TerminalLocation.Panel }); } } else { this._terminalsInitialized = true; From 1ce1f73448757d6978fef52804809a0ea68fcb8c Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 17 Aug 2021 11:25:28 -0700 Subject: [PATCH 08/24] clean up --- .../contrib/terminal/browser/terminal.ts | 4 +- .../terminal/browser/terminalEditorService.ts | 20 +++--- .../terminal/browser/terminalService.ts | 71 +++++++++---------- 3 files changed, 46 insertions(+), 49 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 5188811cd4239..54fd04c6d15a8 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -199,10 +199,10 @@ export interface ITerminalEditorService extends ITerminalInstanceHost, ITerminal /** Gets all _terminal editor_ instances. */ readonly instances: readonly ITerminalInstance[]; - openEditor(instance: ITerminalInstance, sideGroup?: boolean): Promise; + openEditor(instance: ITerminalInstance, sideGroup?: boolean, editorOptions?: TerminalEditorLocation): Promise; detachActiveEditorInstance(): ITerminalInstance; detachInstance(instance: ITerminalInstance): void; - splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig, editorOptions?: TerminalEditorLocation): ITerminalInstance; + splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig): ITerminalInstance; revealActiveEditor(preserveFocus?: boolean): void; resolveResource(instance: ITerminalInstance | URI): URI; reviveInput(deserializedInput: DeserializedTerminalEditorInput): TerminalEditorInput; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts index 44a913b523145..076de8f956426 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts @@ -11,13 +11,12 @@ import { EditorActivation } from 'vs/platform/editor/common/editor'; import { IInstantiationService, optional } from 'vs/platform/instantiation/common/instantiation'; import { IShellLaunchConfig, TerminalLocation } from 'vs/platform/terminal/common/terminal'; import { IEditorInput } from 'vs/workbench/common/editor'; -import { IRemoteTerminalService, ITerminalEditorService, ITerminalInstance, ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { IRemoteTerminalService, ITerminalEditorService, ITerminalInstance, ITerminalInstanceService, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalEditor } from 'vs/workbench/contrib/terminal/browser/terminalEditor'; import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput'; import { DeserializedTerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorSerializer'; import { getInstanceFromResource, parseTerminalUri } from 'vs/workbench/contrib/terminal/browser/terminalUri'; import { ILocalTerminalService, IOffProcessTerminalService } from 'vs/workbench/contrib/terminal/common/terminal'; -import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; @@ -159,7 +158,7 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor this._onDidChangeActiveInstance.fire(this.activeInstance); } - async openEditor(instance: ITerminalInstance, sideGroup: boolean = false): Promise { + async openEditor(instance: ITerminalInstance, sideGroup: boolean = false, editorOptions?: TerminalEditorLocation): Promise { const resource = this.resolveResource(instance); if (resource) { await this._editorService.openEditor({ @@ -167,10 +166,11 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor options: { pinned: true, - forceReload: true + forceReload: true, + preserveFocus: editorOptions?.preserveFocus } }, - sideGroup ? SIDE_GROUP : undefined); + editorOptions?.viewColumn || sideGroup ? SIDE_GROUP : undefined); } } @@ -235,8 +235,7 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor return getInstanceFromResource(this.instances, resource); } - splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig: IShellLaunchConfig = {}, editorOptions?: { viewColumn: EditorGroupColumn, preserveFocus?: boolean }): ITerminalInstance { - console.log(editorOptions); + splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig: IShellLaunchConfig = {}): ITerminalInstance { if (instanceToSplit?.target === TerminalLocation.Editor) { // Make sure the instance to split's group is active const group = this._editorInputs.get(instanceToSplit.resource.path)?.group; @@ -252,11 +251,10 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor options: { pinned: true, - forceReload: true, - preserveFocus: editorOptions?.preserveFocus - }, + forceReload: true + } }, - editorOptions?.viewColumn || SIDE_GROUP); + SIDE_GROUP); } return instance; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 7133029a83395..325e26379b23a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -1153,46 +1153,45 @@ export class TerminalService implements ITerminalService { } this._evaluateLocalCwd(shellLaunchConfig); - - let instance: ITerminalInstance; - - const target = this._getLocation(options?.location) || this.configHelper.config.defaultLocation; - + const location = this._getLocation(options?.location) || this.configHelper.config.defaultLocation; const parent = options?.instanceToSplit || this._getSplitParent(options?.location); + return parent ? this._splitTerminal(shellLaunchConfig, location, parent) : this._createTerminal(shellLaunchConfig, location, options); + } - const editorOptions = this._getEditorOptions(options?.location); - - if (parent) { - // Use the URI from the base instance if it exists, this will correctly split local terminals - if (typeof shellLaunchConfig.cwd !== 'object' && typeof parent.shellLaunchConfig.cwd === 'object') { - shellLaunchConfig.cwd = URI.from({ - scheme: parent.shellLaunchConfig.cwd.scheme, - authority: parent.shellLaunchConfig.cwd.authority, - path: shellLaunchConfig.cwd || parent.shellLaunchConfig.cwd.path - }); - } - if (target === TerminalLocation.Editor || parent.target === TerminalLocation.Editor) { - instance = this._terminalEditorService.splitInstance(parent, shellLaunchConfig); - } else { - const group = this._terminalGroupService.getGroupForInstance(parent); - if (!group) { - throw new Error(`Cannot split a terminal without a group ${parent}`); - } - instance = group.split(shellLaunchConfig); - this._terminalGroupService.groups.forEach((g, i) => g.setVisible(i === this._terminalGroupService.activeGroupIndex)); - } - } else if (editorOptions) { - instance = this._terminalEditorService.splitInstance(undefined, shellLaunchConfig, editorOptions); + private _splitTerminal(shellLaunchConfig: IShellLaunchConfig, location: TerminalLocation, parent: ITerminalInstance): ITerminalInstance { + let instance; + // Use the URI from the base instance if it exists, this will correctly split local terminals + if (typeof shellLaunchConfig.cwd !== 'object' && typeof parent.shellLaunchConfig.cwd === 'object') { + shellLaunchConfig.cwd = URI.from({ + scheme: parent.shellLaunchConfig.cwd.scheme, + authority: parent.shellLaunchConfig.cwd.authority, + path: shellLaunchConfig.cwd || parent.shellLaunchConfig.cwd.path + }); + } + if (location === TerminalLocation.Editor || parent.target === TerminalLocation.Editor) { + instance = this._terminalEditorService.splitInstance(parent, shellLaunchConfig); } else { - if (target === TerminalLocation.Editor) { - instance = this._terminalInstanceService.createInstance(shellLaunchConfig, undefined, options?.resource); - instance.target = TerminalLocation.Editor; - this._terminalEditorService.openEditor(instance, options?.forceSplit || !!options?.instanceToSplit); - } else { - // TODO: pass resource? - const group = this._terminalGroupService.createGroup(shellLaunchConfig); - instance = group.terminalInstances[0]; + const group = this._terminalGroupService.getGroupForInstance(parent); + if (!group) { + throw new Error(`Cannot split a terminal without a group ${parent}`); } + instance = group.split(shellLaunchConfig); + this._terminalGroupService.groups.forEach((g, i) => g.setVisible(i === this._terminalGroupService.activeGroupIndex)); + } + return instance; + } + + private _createTerminal(shellLaunchConfig: IShellLaunchConfig, location: TerminalLocation, options?: ICreateTerminalOptions): ITerminalInstance { + let instance; + const editorOptions = this._getEditorOptions(options?.location); + if (location === TerminalLocation.Editor) { + instance = this._terminalInstanceService.createInstance(shellLaunchConfig, undefined, options?.resource); + instance.target = TerminalLocation.Editor; + this._terminalEditorService.openEditor(instance, options?.forceSplit || !!options?.instanceToSplit, editorOptions); + } else { + // TODO: pass resource? + const group = this._terminalGroupService.createGroup(shellLaunchConfig); + instance = group.terminalInstances[0]; } return instance; } From b48448dc499203db3a8ad0eca4fc8c548ea3a40c Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 17 Aug 2021 11:35:33 -0700 Subject: [PATCH 09/24] clean up --- src/vs/platform/terminal/common/terminal.ts | 2 +- src/vs/vscode.proposed.d.ts | 2 -- .../api/browser/mainThreadTerminalService.ts | 2 -- src/vs/workbench/api/common/extHost.protocol.ts | 3 +-- src/vs/workbench/api/common/extHostTerminalService.ts | 11 +++-------- src/vs/workbench/contrib/terminal/browser/terminal.ts | 2 +- .../contrib/terminal/browser/terminalEditorService.ts | 4 ++-- 7 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index fe078f9762d48..53421209745e5 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -397,7 +397,7 @@ export interface ICreateContributedTerminalProfileOptions { export enum TerminalLocation { Panel = 0, - Editor = 1, + Editor = 1 } export type TerminalIcon = ThemeIcon | URI | { light: URI; dark: URI }; diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 06b2612f09dc4..d9fd368daa1de 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -951,8 +951,6 @@ declare module 'vscode' { * is in the panel or the editor area. */ parentTerminal: Terminal; - - // TODO: Do we need to specify a side? } /** diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 8f95dd97d3076..4ed5306755c24 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -169,8 +169,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } else { return undefined; } - } else if (typeof location === 'object' && 'viewColumn' in location) { - return location; } return location; } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index c0a654b107d2e..3501943eb0c17 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -70,7 +70,6 @@ import { createExtHostContextProxyIdentifier as createExtId, createMainContextPr import { CandidatePort } from 'vs/workbench/services/remote/common/remoteExplorerService'; import * as search from 'vs/workbench/services/search/common/search'; import * as statusbar from 'vs/workbench/services/statusbar/common/statusbar'; -import { TerminalEditorLocationOptions } from 'vscode'; export interface IEnvironment { isExtensionDevelopmentDebug: boolean; @@ -489,7 +488,7 @@ export interface TerminalLaunchConfig { useShellEnvironment?: boolean; isSplitTerminal?: boolean; target?: TerminalLocation; - location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }; + location?: TerminalLocation | { viewColumn: number, preserveFocus?: boolean } | { parentTerminal: ExtHostTerminal }; } export interface MainThreadTerminalServiceShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index d10466c7a8b3e..81ed57533b57b 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -52,7 +52,6 @@ export interface ITerminalInternalOptions { isFeatureTerminal?: boolean; useShellEnvironment?: boolean; isSplitTerminal?: boolean; - target?: TerminalLocation; parentTerminal?: ExtHostTerminal; } @@ -149,7 +148,6 @@ export class ExtHostTerminal { isExtensionOwnedTerminal: true, useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), isSplitTerminal: internalOptions?.isSplitTerminal, - target: internalOptions?.target, location: this._getLocation(withNullAsUndefined(options.location), internalOptions?.parentTerminal) }); } @@ -160,13 +158,11 @@ export class ExtHostTerminal { } else if (typeof location === 'object' && 'parentTerminal' in location) { // use the ExtHostTerminal with value = to the parentTerminal return parentTerminal ? { parentTerminal } : undefined; - } else if (typeof location === 'object' && 'viewColumn' in location) { - return location; } return location; } - public async createExtensionTerminal(isSplitTerminal?: boolean, target?: TerminalLocation, iconPath?: TerminalIcon, color?: ThemeColor): Promise { + public async createExtensionTerminal(isSplitTerminal?: boolean, iconPath?: TerminalIcon, color?: ThemeColor): Promise { if (typeof this._id !== 'string') { throw new Error('Terminal has already been created'); } @@ -175,8 +171,7 @@ export class ExtHostTerminal { isExtensionCustomPtyTerminal: true, icon: iconPath, color: ThemeColor.isThemeColor(color) ? color.id : undefined, - isSplitTerminal, - target + isSplitTerminal }); // At this point, the id has been set via `$acceptTerminalOpened` if (typeof this._id === 'string') { @@ -403,7 +398,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I public createExtensionTerminal(options: vscode.ExtensionTerminalOptions, internalOptions?: ITerminalInternalOptions): vscode.Terminal { const terminal = new ExtHostTerminal(this._proxy, generateUuid(), options, options.name); const p = new ExtHostPseudoterminal(options.pty); - terminal.createExtensionTerminal(internalOptions?.isSplitTerminal, internalOptions?.target, asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { + terminal.createExtensionTerminal(internalOptions?.isSplitTerminal, asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { const disposable = this._setupExtHostProcessListeners(id, p); this._terminalProcessDisposables[id] = disposable; }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 54fd04c6d15a8..5bc76d74458e0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -202,7 +202,7 @@ export interface ITerminalEditorService extends ITerminalInstanceHost, ITerminal openEditor(instance: ITerminalInstance, sideGroup?: boolean, editorOptions?: TerminalEditorLocation): Promise; detachActiveEditorInstance(): ITerminalInstance; detachInstance(instance: ITerminalInstance): void; - splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig): ITerminalInstance; + splitInstance(instanceToSplit: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig): ITerminalInstance; revealActiveEditor(preserveFocus?: boolean): void; resolveResource(instance: ITerminalInstance | URI): URI; reviveInput(deserializedInput: DeserializedTerminalEditorInput): TerminalEditorInput; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts index 076de8f956426..4ab405625f619 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts @@ -235,8 +235,8 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor return getInstanceFromResource(this.instances, resource); } - splitInstance(instanceToSplit?: ITerminalInstance, shellLaunchConfig: IShellLaunchConfig = {}): ITerminalInstance { - if (instanceToSplit?.target === TerminalLocation.Editor) { + splitInstance(instanceToSplit: ITerminalInstance, shellLaunchConfig: IShellLaunchConfig = {}): ITerminalInstance { + if (instanceToSplit.target === TerminalLocation.Editor) { // Make sure the instance to split's group is active const group = this._editorInputs.get(instanceToSplit.resource.path)?.group; if (group) { From fdc5cc2feaa57c047da8e2f054467d686a172127 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 17 Aug 2021 12:26:52 -0700 Subject: [PATCH 10/24] remove some lines --- .../api/browser/mainThreadTerminalService.ts | 14 ++++---------- .../workbench/api/common/extHostTerminalService.ts | 8 +++----- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 4ed5306755c24..db29002750639 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -152,23 +152,17 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape if (!terminal) { terminal = await this._terminalService.createTerminal({ config: shellLaunchConfig, - location: await this._getLocation(launchConfig.location) + location: !launchConfig.location ? undefined : await this._getLocation(launchConfig.location) }); } r(terminal); })); } - private async _getLocation(location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }): Promise { - if (!location) { - return location; - } else if (typeof location === 'object' && 'parentTerminal' in location) { + private async _getLocation(location: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }): Promise { + if (typeof location === 'object' && 'parentTerminal' in location) { const parentTerminal = await this._extHostTerminals.get(location.parentTerminal._id.toString()); - if (parentTerminal) { - return { parentTerminal }; - } else { - return undefined; - } + return parentTerminal ? { parentTerminal } : undefined; } return location; } diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 81ed57533b57b..51ac919967de9 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -148,14 +148,12 @@ export class ExtHostTerminal { isExtensionOwnedTerminal: true, useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), isSplitTerminal: internalOptions?.isSplitTerminal, - location: this._getLocation(withNullAsUndefined(options.location), internalOptions?.parentTerminal) + location: !options.location ? undefined : this._getLocation(options.location, internalOptions?.parentTerminal) }); } - private _getLocation(location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminal): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal } | undefined { - if (!location) { - return location; - } else if (typeof location === 'object' && 'parentTerminal' in location) { + private _getLocation(location: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminal): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal } | undefined { + if (typeof location === 'object' && 'parentTerminal' in location) { // use the ExtHostTerminal with value = to the parentTerminal return parentTerminal ? { parentTerminal } : undefined; } From 0bc2f1f1ec6f5e0cb24169e6dbe72338fcf0d0f4 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 17 Aug 2021 18:28:34 -0400 Subject: [PATCH 11/24] Update src/vs/workbench/api/common/extHostTerminalService.ts Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- src/vs/workbench/api/common/extHostTerminalService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 609f1da32b604..b9c3b98eaaf74 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -148,7 +148,7 @@ export class ExtHostTerminal { isExtensionOwnedTerminal: true, useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), isSplitTerminal: internalOptions?.isSplitTerminal, - location: !options.location ? undefined : this._getLocation(options.location, internalOptions?.parentTerminal) + location: options.location ? this._getLocation(options.location, internalOptions?.parentTerminal) : undefined }); } From 0e36ae1f7a1f180cff78a71e2f10db4a8af88a83 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 17 Aug 2021 18:28:43 -0400 Subject: [PATCH 12/24] Update src/vs/workbench/api/browser/mainThreadTerminalService.ts Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- src/vs/workbench/api/browser/mainThreadTerminalService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index db29002750639..703a0fdf0825b 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -152,7 +152,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape if (!terminal) { terminal = await this._terminalService.createTerminal({ config: shellLaunchConfig, - location: !launchConfig.location ? undefined : await this._getLocation(launchConfig.location) + location: launchConfig.location ? await this._getLocation(launchConfig.location) : undefined }); } r(terminal); From f46876b1142ecebddc539b737f335e343535126d Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 17 Aug 2021 15:59:51 -0700 Subject: [PATCH 13/24] get rid of isSplitTerminal and forceSplit --- .../api/browser/mainThreadTerminalService.ts | 6 ++-- .../api/common/extHostTerminalService.ts | 4 +-- .../tasks/browser/terminalTaskSystem.ts | 2 +- .../contrib/terminal/browser/terminal.ts | 13 ++------ .../terminal/browser/terminalActions.ts | 14 ++++---- .../terminal/browser/terminalEditorService.ts | 2 +- .../contrib/terminal/browser/terminalMenus.ts | 6 ++-- .../terminal/browser/terminalService.ts | 32 +++++++++++++------ .../terminal/browser/terminalTabsList.ts | 4 +-- .../contrib/terminal/browser/terminalView.ts | 2 +- 10 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 703a0fdf0825b..ffe8c105727ec 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -146,20 +146,20 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape if (launchConfig.isSplitTerminal) { const activeInstance = this._terminalService.getInstanceHost(launchConfig.target).activeInstance; if (activeInstance) { - terminal = withNullAsUndefined(await this._terminalService.createTerminal({ instanceToSplit: activeInstance, config: shellLaunchConfig })); + terminal = withNullAsUndefined(await this._terminalService.createTerminal({ location: { parentTerminal: activeInstance }, config: shellLaunchConfig })); } } if (!terminal) { terminal = await this._terminalService.createTerminal({ config: shellLaunchConfig, - location: launchConfig.location ? await this._getLocation(launchConfig.location) : undefined + location: launchConfig.location ? await this._resolveMainThreadLocation(launchConfig.location) : undefined }); } r(terminal); })); } - private async _getLocation(location: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }): Promise { + private async _resolveMainThreadLocation(location: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }): Promise { if (typeof location === 'object' && 'parentTerminal' in location) { const parentTerminal = await this._extHostTerminals.get(location.parentTerminal._id.toString()); return parentTerminal ? { parentTerminal } : undefined; diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index b9c3b98eaaf74..6b3c57704e672 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -148,11 +148,11 @@ export class ExtHostTerminal { isExtensionOwnedTerminal: true, useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), isSplitTerminal: internalOptions?.isSplitTerminal, - location: options.location ? this._getLocation(options.location, internalOptions?.parentTerminal) : undefined + location: options.location ? this._resolveExtHostLocation(options.location, internalOptions?.parentTerminal) : undefined }); } - private _getLocation(location: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminal): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal } | undefined { + private _resolveExtHostLocation(location: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminal): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal } | undefined { if (typeof location === 'object' && 'parentTerminal' in location) { // use the ExtHostTerminal with value = to the parentTerminal return parentTerminal ? { parentTerminal } : undefined; diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index af66f24f1deb3..85a3a4d0452a8 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -1302,7 +1302,7 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem { if (terminal.group === group) { const originalInstance = terminal.terminal; await originalInstance.waitForTitle(); - result = await this.terminalService.createTerminal({ instanceToSplit: originalInstance, config: launchConfigs }); + result = await this.terminalService.createTerminal({ location: { parentTerminal: originalInstance }, config: launchConfigs }); if (result) { break; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index d1655f50c21b6..aca48a3c7114f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -209,6 +209,8 @@ export interface ITerminalEditorService extends ITerminalInstanceHost, ITerminal getInputFromResource(resource: URI): TerminalEditorInput; } +export type ITerminalLocationOptions = TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }; + export interface ICreateTerminalOptions { /** * The shell launch config or profile to launch with, when not specified the default terminal @@ -220,24 +222,15 @@ export interface ICreateTerminalOptions { * specified. */ cwd?: string | URI; - /** - * Creates a split terminal without requiring a terminal instance to split, for example when splitting - * a terminal editor - */ - forceSplit?: boolean; /** * The terminal's resource, passed when the terminal has moved windows. */ resource?: URI; - /** - * The terminal instance to split - */ - instanceToSplit?: ITerminalInstance; /** * The location at which to create the terminal */ - location?: TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }; + location?: ITerminalLocationOptions; } export interface TerminalEditorLocation { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 083afbd697335..fee25f333e3ac 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -44,6 +44,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; export const switchTerminalActionViewItemSeparator = '─────────'; export const switchTerminalShowTabsTitle = localize('showTerminalTabs', "Show Tabs"); @@ -167,8 +168,7 @@ export function registerTerminalActions() { async run(accessor: ServicesAccessor) { const terminalService = accessor.get(ITerminalService); const instance = await terminalService.createTerminal({ - location: TerminalLocation.Editor, - forceSplit: true + location: { viewColumn: SIDE_GROUP } }); instance.focusWhenReady(); } @@ -1433,7 +1433,7 @@ export function registerTerminalActions() { if (cwd === undefined) { return undefined; } - const instance = await terminalService.createTerminal({ instanceToSplit: activeInstance, config: options?.config, cwd, location: activeInstance.target }); + const instance = await terminalService.createTerminal({ location: { parentTerminal: activeInstance }, config: options?.config, cwd }); if (instance) { if (instance.target === TerminalLocation.Editor) { instance.focusWhenReady(); @@ -1471,7 +1471,7 @@ export function registerTerminalActions() { terminalService.setActiveInstance(t); terminalService.doWithActiveInstance(async instance => { const cwd = await getCwdForSplit(terminalService.configHelper, instance); - await terminalService.createTerminal({ instanceToSplit: instance, cwd }); + await terminalService.createTerminal({ location: { parentTerminal: instance }, cwd }); await terminalGroupService.showPanel(true); }); } @@ -1546,7 +1546,7 @@ export function registerTerminalActions() { const terminalGroupService = accessor.get(ITerminalGroupService); await terminalService.doWithActiveInstance(async t => { const cwd = await getCwdForSplit(terminalService.configHelper, t); - const instance = await terminalService.createTerminal({ instanceToSplit: t, cwd }); + const instance = await terminalService.createTerminal({ location: { parentTerminal: t }, cwd }); if (instance?.target !== TerminalLocation.Editor) { await terminalGroupService.showPanel(true); } @@ -1613,7 +1613,7 @@ export function registerTerminalActions() { const activeInstance = terminalService.activeInstance; if (activeInstance) { const cwd = await getCwdForSplit(terminalService.configHelper, activeInstance); - await terminalService.createTerminal({ instanceToSplit: activeInstance, cwd }); + await terminalService.createTerminal({ location: { parentTerminal: activeInstance }, cwd }); return; } } @@ -2029,7 +2029,7 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { const activeInstance = terminalService.activeInstance; if (activeInstance) { const cwd = await getCwdForSplit(terminalService.configHelper, activeInstance); - await terminalService.createTerminal({ instanceToSplit: activeInstance, config: options?.config, cwd }); + await terminalService.createTerminal({ location: { parentTerminal: activeInstance }, config: options?.config, cwd }); return; } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts index 4ab405625f619..6625663165537 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts @@ -170,7 +170,7 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor preserveFocus: editorOptions?.preserveFocus } }, - editorOptions?.viewColumn || sideGroup ? SIDE_GROUP : undefined); + editorOptions?.viewColumn || (sideGroup ? SIDE_GROUP : undefined)); } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts index 3db9fb8312177..a8acb0b541573 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts @@ -17,6 +17,7 @@ import { ICreateTerminalOptions, ITerminalService } from 'vs/workbench/contrib/t import { TerminalCommandId, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalContextKeys, TerminalContextKeyStrings } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; +import { SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; const enum ContextMenuGroup { Create = '1_create', @@ -608,17 +609,16 @@ export function getTerminalActionBarArgs(location: TerminalLocation, profiles: I id: contributed.id, title }, - forceSplit: false, location }))); + const splitLocation = location === TerminalLocation.Editor ? { viewColumn: SIDE_GROUP } : location; submenuActions.push(new Action(TerminalCommandId.NewWithProfile, title, undefined, true, () => terminalService.createTerminal({ config: { extensionIdentifier: contributed.extensionIdentifier, id: contributed.id, title }, - forceSplit: true, - location + location: splitLocation }))); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 325e26379b23a..56d2f4f215dbb 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -31,7 +31,7 @@ import { ColorScheme } from 'vs/platform/theme/common/theme'; import { IThemeService, Themable, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { VirtualWorkspaceContext } from 'vs/workbench/browser/contextkeys'; import { IEditableData, IViewsService } from 'vs/workbench/common/views'; -import { ICreateTerminalOptions, IRemoteTerminalService, IRequestAddInstanceToGroupEvent, ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalFindHost, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceHost, ITerminalInstanceService, ITerminalProfileProvider, ITerminalService, TerminalConnectionState, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ICreateTerminalOptions, IRemoteTerminalService, IRequestAddInstanceToGroupEvent, ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalFindHost, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceHost, ITerminalInstanceService, ITerminalLocationOptions, ITerminalProfileProvider, ITerminalService, TerminalConnectionState, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal'; import { refreshTerminalActions } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalEditor } from 'vs/workbench/contrib/terminal/browser/terminalEditor'; @@ -44,6 +44,7 @@ import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/termin import { ITerminalContributionService } from 'vs/workbench/contrib/terminal/common/terminalExtensionPoints'; import { formatMessageForTerminal, terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; +import { SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ILifecycleService, ShutdownReason, WillShutdownEvent } from 'vs/workbench/services/lifecycle/common/lifecycle'; @@ -420,7 +421,7 @@ export class TerminalService implements ITerminalService { } } else { // add split terminals to this group - await this.createTerminal({ config: { attachPersistentProcess: terminalLayout.terminal! }, instanceToSplit: terminalInstance },); + await this.createTerminal({ config: { attachPersistentProcess: terminalLayout.terminal! }, location: { parentTerminal: terminalInstance } }); } } const activeInstance = this.instances.find(t => { @@ -944,7 +945,7 @@ export class TerminalService implements ITerminalService { } else { if (keyMods?.alt && activeInstance) { // create split, only valid if there's an active instance - instance = await this.createTerminal({ instanceToSplit: activeInstance, config: value.profile }); + instance = await this.createTerminal({ location: { parentTerminal: activeInstance }, config: value.profile }); } else { instance = await this.createTerminal({ location: this.configHelper.config.defaultLocation, config: value.profile, cwd }); } @@ -1125,7 +1126,7 @@ export class TerminalService implements ITerminalService { // Launch the contributed profile if (contributedProfile) { await this._createContributedTerminalProfile(contributedProfile.extensionIdentifier, contributedProfile.id, { - isSplitTerminal: options?.forceSplit || !!options?.instanceToSplit, + isSplitTerminal: this._isSplitTerminal(options), icon: contributedProfile.icon, target: options?.location === TerminalLocation.Editor ? TerminalLocation.Editor : TerminalLocation.Panel, color: contributedProfile.color @@ -1153,11 +1154,22 @@ export class TerminalService implements ITerminalService { } this._evaluateLocalCwd(shellLaunchConfig); - const location = this._getLocation(options?.location) || this.configHelper.config.defaultLocation; - const parent = options?.instanceToSplit || this._getSplitParent(options?.location); + const location = this._resolveLocation(options?.location) || this.configHelper.config.defaultLocation; + const parent = this._getSplitParent(options?.location); return parent ? this._splitTerminal(shellLaunchConfig, location, parent) : this._createTerminal(shellLaunchConfig, location, options); } + private _isSplitTerminal(options?: ICreateTerminalOptions): boolean { + if (options?.location && typeof options.location === 'object') { + if ('viewColumn' in options.location) { + return options.location.viewColumn === SIDE_GROUP; + } else if ('parentTerminal' in options.location) { + return true; + } + } + return false; + } + private _splitTerminal(shellLaunchConfig: IShellLaunchConfig, location: TerminalLocation, parent: ITerminalInstance): ITerminalInstance { let instance; // Use the URI from the base instance if it exists, this will correctly split local terminals @@ -1187,7 +1199,7 @@ export class TerminalService implements ITerminalService { if (location === TerminalLocation.Editor) { instance = this._terminalInstanceService.createInstance(shellLaunchConfig, undefined, options?.resource); instance.target = TerminalLocation.Editor; - this._terminalEditorService.openEditor(instance, options?.forceSplit || !!options?.instanceToSplit, editorOptions); + this._terminalEditorService.openEditor(instance, this._isSplitTerminal(options), editorOptions); } else { // TODO: pass resource? const group = this._terminalGroupService.createGroup(shellLaunchConfig); @@ -1196,7 +1208,7 @@ export class TerminalService implements ITerminalService { return instance; } - private _getLocation(location?: TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }): TerminalLocation | undefined { + private _resolveLocation(location?: ITerminalLocationOptions): TerminalLocation | undefined { if (!location) { return location; } else if (typeof location === 'object' && 'parentTerminal' in location) { @@ -1207,14 +1219,14 @@ export class TerminalService implements ITerminalService { return location; } - private _getSplitParent(location?: TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }): ITerminalInstance | undefined { + private _getSplitParent(location?: ITerminalLocationOptions): ITerminalInstance | undefined { if (location && typeof location === 'object' && 'parentTerminal' in location) { return location.parentTerminal; } return undefined; } - private _getEditorOptions(location?: TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }): TerminalEditorLocation | undefined { + private _getEditorOptions(location?: ITerminalLocationOptions): TerminalEditorLocation | undefined { if (location && typeof location === 'object' && 'viewColumn' in location) { return location; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts b/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts index 903d6492599d7..7547311d2ee10 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalTabsList.ts @@ -144,7 +144,7 @@ export class TerminalTabList extends WorkbenchList { // unless multi-selection is in progress this.onMouseClick(async e => { if (e.browserEvent.altKey && e.element) { - await this._terminalService.createTerminal({ instanceToSplit: e.element }); + await this._terminalService.createTerminal({ location: { parentTerminal: e.element } }); } else if (this._getFocusMode() === 'singleClick') { if (this.getSelection().length <= 1) { e.element?.focus(true); @@ -459,7 +459,7 @@ class TerminalTabsRenderer implements IListRenderer { - this._runForSelectionOrInstance(instance, e => this._terminalService.createTerminal({ instanceToSplit: e })); + this._runForSelectionOrInstance(instance, e => this._terminalService.createTerminal({ location: { parentTerminal: e } })); }), new Action(TerminalCommandId.KillInstance, terminalStrings.kill.short, ThemeIcon.asClassName(Codicon.trashcan), true, async () => { this._runForSelectionOrInstance(instance, e => e.dispose()); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalView.ts b/src/vs/workbench/contrib/terminal/browser/terminalView.ts index 6780b5763c860..6d3d14d466ba0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalView.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalView.ts @@ -183,7 +183,7 @@ export class TerminalViewPane extends ViewPane { run: async () => { const instance = this._terminalGroupService.activeInstance; if (instance) { - const newInstance = await this._terminalService.createTerminal({ instanceToSplit: instance, forceSplit: true }); + const newInstance = await this._terminalService.createTerminal({ location: { parentTerminal: instance } }); return newInstance?.focusWhenReady(); } return; From 6593e3af9d2615df98421d843fba14d1ea8c75e1 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 18 Aug 2021 10:29:41 -0700 Subject: [PATCH 14/24] remove isSplitTerminal and target from profile ocreation options --- src/vs/platform/terminal/common/terminal.ts | 3 +- .../api/browser/mainThreadTerminalService.ts | 12 ++++++-- .../api/common/extHostTerminalService.ts | 27 +++++++++++------- .../api/node/extHostTerminalService.ts | 4 ++- .../contrib/terminal/browser/terminal.ts | 10 +++++-- .../terminal/browser/terminalService.ts | 28 +++++++++++++++---- 6 files changed, 61 insertions(+), 23 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index c5ff37003cb06..4911f7d4b413d 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -391,10 +391,9 @@ export interface IShellLaunchConfig { } export interface ICreateContributedTerminalProfileOptions { - target?: TerminalLocation; icon?: URI | string | { light: URI, dark: URI }; color?: string; - isSplitTerminal?: boolean; + location?: TerminalLocation | { viewColumn: number, preserveState?: boolean } | { splitActive: boolean }; } export enum TerminalLocation { diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index ffe8c105727ec..b847212ece0d0 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; -import { IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensions, TerminalLocation, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { ICreateContributedTerminalProfileOptions, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensions, TerminalLocation, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; import { ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, ITerminalLink, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy'; @@ -231,11 +231,19 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape // Proxy profile provider requests through the extension host this._profileProviders.set(id, this._terminalService.registerTerminalProfileProvider(extensionIdentifier, id, { createContributedTerminalProfile: async (options) => { - return this._proxy.$createContributedProfileTerminal(id, options); + const resolvedOptions = this._resolveOptions(options); + return this._proxy.$createContributedProfileTerminal(id, resolvedOptions); } })); } + private _resolveOptions(options: any): ICreateContributedTerminalProfileOptions { + if (options.location && typeof options.location === 'object' && 'parentTerminal' in options.location) { + options.location = { splitActive: true }; + } + return options; + } + public $unregisterProfileProvider(id: string): void { this._profileProviders.get(id)?.dispose(); this._profileProviders.delete(id); diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 6b3c57704e672..2b5a2b6c4a9dd 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -51,8 +51,7 @@ export interface IExtHostTerminalService extends ExtHostTerminalServiceShape, ID export interface ITerminalInternalOptions { isFeatureTerminal?: boolean; useShellEnvironment?: boolean; - isSplitTerminal?: boolean; - parentTerminal?: ExtHostTerminal; + location?: TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }; } export const IExtHostTerminalService = createDecorator('IExtHostTerminalService'); @@ -147,8 +146,7 @@ export class ExtHostTerminal { isFeatureTerminal: withNullAsUndefined(internalOptions?.isFeatureTerminal), isExtensionOwnedTerminal: true, useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), - isSplitTerminal: internalOptions?.isSplitTerminal, - location: options.location ? this._resolveExtHostLocation(options.location, internalOptions?.parentTerminal) : undefined + location: options.location ? this._resolveExtHostLocation(options.location) : undefined }); } @@ -160,7 +158,7 @@ export class ExtHostTerminal { return location; } - public async createExtensionTerminal(isSplitTerminal?: boolean, iconPath?: TerminalIcon, color?: ThemeColor): Promise { + public async createExtensionTerminal(iconPath?: TerminalIcon, color?: ThemeColor): Promise { if (typeof this._id !== 'string') { throw new Error('Terminal has already been created'); } @@ -168,8 +166,7 @@ export class ExtHostTerminal { name: this._name, isExtensionCustomPtyTerminal: true, icon: iconPath, - color: ThemeColor.isThemeColor(color) ? color.id : undefined, - isSplitTerminal + color: ThemeColor.isThemeColor(color) ? color.id : undefined }); // At this point, the id has been set via `$acceptTerminalOpened` if (typeof this._id === 'string') { @@ -400,7 +397,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I public createExtensionTerminal(options: vscode.ExtensionTerminalOptions, internalOptions?: ITerminalInternalOptions): vscode.Terminal { const terminal = new ExtHostTerminal(this._proxy, generateUuid(), options, options.name); const p = new ExtHostPseudoterminal(options.pty); - terminal.createExtensionTerminal(internalOptions?.isSplitTerminal, asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { + terminal.createExtensionTerminal(asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { const disposable = this._setupExtHostProcessListeners(id, p); this._terminalProcessDisposables[id] = disposable; }); @@ -646,11 +643,21 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I if (!profile || !('options' in profile)) { throw new Error(`No terminal profile options provided for id "${id}"`); } + const opts: ITerminalInternalOptions = {}; + if (options.location && typeof options.location === 'object' && 'splitActive' in options.location) { + const id = this._terminals.find(t => t.value === this.activeTerminal)?._id; + if (id) { + const index = this._getTerminalObjectIndexById(this._terminals, id); + if (index) { + opts.location = { parentTerminal: this._terminals[index] }; + } + } + } if ('pty' in profile.options) { - this.createExtensionTerminal(profile.options, options); + this.createExtensionTerminal(profile.options, opts); return; } - this.createTerminalFromOptions(profile.options, options); + this.createTerminalFromOptions(profile.options, opts); } public async $provideLinks(terminalId: number, line: string): Promise { diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index a4de15922fee9..35fb8991d4fa6 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -28,7 +28,9 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { if (parentTerminal) { const parentExtHostTerminal = this._terminals.find(t => t.value === parentTerminal); internalOptions = internalOptions ? internalOptions : {}; - internalOptions.parentTerminal = parentExtHostTerminal; + if (parentExtHostTerminal) { + internalOptions.location = { parentTerminal: parentExtHostTerminal }; + } } } terminal.create(options, internalOptions); diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index aca48a3c7114f..d54cae0be040a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -8,7 +8,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { FindReplaceState } from 'vs/editor/contrib/find/findState'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource, TerminalShellType, ICreateContributedTerminalProfileOptions, TerminalLocation, IExtensionTerminalProfile, ITerminalProfileType } from 'vs/platform/terminal/common/terminal'; +import { IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource, TerminalShellType, IExtensionTerminalProfile, ITerminalProfileType, TerminalLocation } from 'vs/platform/terminal/common/terminal'; import { ICommandTracker, INavigationMode, IOffProcessTerminalService, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal'; import type { Terminal as XTermTerminal } from 'xterm'; import type { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; @@ -209,7 +209,13 @@ export interface ITerminalEditorService extends ITerminalInstanceHost, ITerminal getInputFromResource(resource: URI): TerminalEditorInput; } -export type ITerminalLocationOptions = TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }; +export type ITerminalLocationOptions = TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance } | { splitActive: boolean }; + +export interface ICreateContributedTerminalProfileOptions { + icon?: URI | string | { light: URI, dark: URI }; + color?: string; + location?: ITerminalLocationOptions; +} export interface ICreateTerminalOptions { /** diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 56d2f4f215dbb..364e027b0f04e 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -23,7 +23,7 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IKeyMods, IPickOptions, IQuickInputButton, IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { ICreateContributedTerminalProfileOptions, IExtensionTerminalProfile, IShellLaunchConfig, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalProfileType, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalSettingId, TerminalSettingPrefix } from 'vs/platform/terminal/common/terminal'; +import { IExtensionTerminalProfile, IShellLaunchConfig, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalProfileType, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalSettingId, TerminalSettingPrefix } from 'vs/platform/terminal/common/terminal'; import { registerTerminalDefaultProfileConfiguration } from 'vs/platform/terminal/common/terminalPlatformConfiguration'; import { iconForeground } from 'vs/platform/theme/common/colorRegistry'; import { IconDefinition } from 'vs/platform/theme/common/iconRegistry'; @@ -31,7 +31,7 @@ import { ColorScheme } from 'vs/platform/theme/common/theme'; import { IThemeService, Themable, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { VirtualWorkspaceContext } from 'vs/workbench/browser/contextkeys'; import { IEditableData, IViewsService } from 'vs/workbench/common/views'; -import { ICreateTerminalOptions, IRemoteTerminalService, IRequestAddInstanceToGroupEvent, ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalFindHost, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceHost, ITerminalInstanceService, ITerminalLocationOptions, ITerminalProfileProvider, ITerminalService, TerminalConnectionState, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ICreateContributedTerminalProfileOptions, ICreateTerminalOptions, IRemoteTerminalService, IRequestAddInstanceToGroupEvent, ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalFindHost, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceHost, ITerminalInstanceService, ITerminalLocationOptions, ITerminalProfileProvider, ITerminalService, TerminalConnectionState, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal'; import { refreshTerminalActions } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalEditor } from 'vs/workbench/contrib/terminal/browser/terminalEditor'; @@ -937,7 +937,7 @@ export class TerminalService implements ITerminalService { if ('id' in value.profile) { await this._createContributedTerminalProfile(value.profile.extensionIdentifier, value.profile.id, { - isSplitTerminal: !!(keyMods?.alt && activeInstance), + location: !!(keyMods?.alt && activeInstance) ? { splitActive: true } : undefined, icon: value.profile.icon, color: value.profile.color }); @@ -1021,7 +1021,8 @@ export class TerminalService implements ITerminalService { return; } try { - await profileProvider.createContributedTerminalProfile(options); + const resolvedOptions = this._resolveOptions(options); + await profileProvider.createContributedTerminalProfile(resolvedOptions); this._terminalGroupService.setActiveInstanceByIndex(this.instances.length - 1); await this.activeInstance?.focusWhenReady(); } catch (e) { @@ -1029,6 +1030,18 @@ export class TerminalService implements ITerminalService { } } + private _resolveOptions(options: any): ICreateContributedTerminalProfileOptions { + const opts: ICreateContributedTerminalProfileOptions = {}; + opts.icon = options.icon; + opts.color = options.color; + if (options.location && typeof options.location === 'object' && 'splitActive' in options.location) { + if (this.activeInstance) { + opts.location = { parentTerminal: this.activeInstance }; + } + } + return opts; + } + private async _registerContributedProfile(extensionIdentifier: string, id: string, title: string, options: ICreateContributedTerminalProfileOptions): Promise { const platformKey = await this._getPlatformKey(); const profilesConfig = await this._configurationService.getValue(`${TerminalSettingPrefix.Profiles}${platformKey}`); @@ -1126,9 +1139,8 @@ export class TerminalService implements ITerminalService { // Launch the contributed profile if (contributedProfile) { await this._createContributedTerminalProfile(contributedProfile.extensionIdentifier, contributedProfile.id, { - isSplitTerminal: this._isSplitTerminal(options), icon: contributedProfile.icon, - target: options?.location === TerminalLocation.Editor ? TerminalLocation.Editor : TerminalLocation.Panel, + location: options?.location, color: contributedProfile.color }); const instanceHost = options?.location === TerminalLocation.Editor ? this._terminalEditorService : this._terminalGroupService; @@ -1215,6 +1227,8 @@ export class TerminalService implements ITerminalService { return location.parentTerminal.target; } else if (typeof location === 'object' && 'viewColumn' in location) { return TerminalLocation.Editor; + } else if (typeof location === 'object' && 'splitActive' in location) { + return this._activeInstance?.target; } return location; } @@ -1222,6 +1236,8 @@ export class TerminalService implements ITerminalService { private _getSplitParent(location?: ITerminalLocationOptions): ITerminalInstance | undefined { if (location && typeof location === 'object' && 'parentTerminal' in location) { return location.parentTerminal; + } else if (location && typeof location === 'object' && 'splitActive' in location) { + return this._activeInstance; } return undefined; } From e4f9a073cbd51a2696dd078bd9d7c25e35396e60 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 18 Aug 2021 11:37:25 -0700 Subject: [PATCH 15/24] bring back defaultLocation setting strings --- src/vs/platform/terminal/common/terminal.ts | 5 +++++ .../workbench/contrib/terminal/browser/terminal.ts | 1 + .../contrib/terminal/browser/terminalActions.ts | 4 ++-- .../contrib/terminal/browser/terminalService.ts | 12 +++++++----- src/vs/workbench/contrib/terminal/common/terminal.ts | 4 ++-- .../contrib/terminal/common/terminalConfiguration.ts | 4 ++-- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 4911f7d4b413d..e10a1555994fd 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -401,6 +401,11 @@ export enum TerminalLocation { Editor = 1 } +export enum TerminalLocationString { + TerminalView = 'view', + Editor = 'editor' +} + export type TerminalIcon = ThemeIcon | URI | { light: URI; dark: URI }; export interface IShellLaunchConfigDto { diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index d54cae0be040a..52ba990ffbb41 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -111,6 +111,7 @@ export interface ITerminalService extends ITerminalInstanceHost { readonly availableProfiles: ITerminalProfile[]; readonly allProfiles: ITerminalProfileType[] | undefined; readonly profilesReady: Promise; + readonly defaultLocation: TerminalLocation; initializeTerminals(): Promise; onDidChangeActiveGroup: Event; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index fee25f333e3ac..0951fc4cb0468 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -123,7 +123,7 @@ export function registerTerminalActions() { const terminalService = accessor.get(ITerminalService); const terminalGroupService = accessor.get(ITerminalGroupService); if (terminalService.isProcessSupportRegistered) { - const instance = await terminalService.createTerminal({ location: terminalService.configHelper.config.defaultLocation }); + const instance = await terminalService.createTerminal({ location: terminalService.defaultLocation }); if (!instance) { return; } @@ -1620,7 +1620,7 @@ export function registerTerminalActions() { if (terminalService.isProcessSupportRegistered) { eventOrOptions = !eventOrOptions || eventOrOptions instanceof MouseEvent ? {} : eventOrOptions; - eventOrOptions.location = eventOrOptions.location || terminalService.configHelper.config.defaultLocation; + eventOrOptions.location = eventOrOptions.location || terminalService.defaultLocation; let instance: ITerminalInstance | undefined; if (folders.length <= 1) { // Allow terminal service to handle the path when there is only a diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 364e027b0f04e..1704cf89a1c95 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -23,7 +23,7 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IKeyMods, IPickOptions, IQuickInputButton, IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IExtensionTerminalProfile, IShellLaunchConfig, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalProfileType, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalSettingId, TerminalSettingPrefix } from 'vs/platform/terminal/common/terminal'; +import { IExtensionTerminalProfile, IShellLaunchConfig, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalProfileType, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalLocationString, TerminalSettingId, TerminalSettingPrefix } from 'vs/platform/terminal/common/terminal'; import { registerTerminalDefaultProfileConfiguration } from 'vs/platform/terminal/common/terminalPlatformConfiguration'; import { iconForeground } from 'vs/platform/theme/common/colorRegistry'; import { IconDefinition } from 'vs/platform/theme/common/iconRegistry'; @@ -97,6 +97,8 @@ export class TerminalService implements ITerminalService { return this._terminalGroupService.instances.concat(this._terminalEditorService.instances); } + get defaultLocation(): TerminalLocation { return this.configHelper.config.defaultLocation === TerminalLocationString.Editor ? TerminalLocation.Editor : TerminalLocation.Panel; } + private _activeInstance: ITerminalInstance | undefined; get activeInstance(): ITerminalInstance | undefined { // Check if either an editor or panel terminal has focus and return that, regardless of the @@ -947,11 +949,11 @@ export class TerminalService implements ITerminalService { // create split, only valid if there's an active instance instance = await this.createTerminal({ location: { parentTerminal: activeInstance }, config: value.profile }); } else { - instance = await this.createTerminal({ location: this.configHelper.config.defaultLocation, config: value.profile, cwd }); + instance = await this.createTerminal({ location: this.defaultLocation, config: value.profile, cwd }); } } - if (instance && this.configHelper.config.defaultLocation !== TerminalLocation.Editor) { + if (instance && this.defaultLocation !== TerminalLocation.Editor) { this._terminalGroupService.showPanel(true); this.setActiveInstance(instance); return instance; @@ -992,7 +994,7 @@ export class TerminalService implements ITerminalService { getDefaultInstanceHost(): ITerminalInstanceHost { - if (this.configHelper.config.defaultLocation === TerminalLocation.Editor) { + if (this.defaultLocation === TerminalLocation.Editor) { return this._terminalEditorService; } return this._terminalGroupService; @@ -1166,7 +1168,7 @@ export class TerminalService implements ITerminalService { } this._evaluateLocalCwd(shellLaunchConfig); - const location = this._resolveLocation(options?.location) || this.configHelper.config.defaultLocation; + const location = this._resolveLocation(options?.location) || this.defaultLocation; const parent = this._getSplitParent(options?.location); return parent ? this._splitTerminal(shellLaunchConfig, location, parent) : this._createTerminal(shellLaunchConfig, location, options); } diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 0cb577cf6ef10..7ca6a41a03134 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -8,7 +8,7 @@ import { Event } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform'; import { IExtensionPointDescriptor } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, TerminalLocation, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, TerminalLocationString, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { URI } from 'vs/base/common/uri'; @@ -203,7 +203,7 @@ export interface ITerminalConfiguration { focusMode: 'singleClick' | 'doubleClick'; }, bellDuration: number; - defaultLocation: TerminalLocation; + defaultLocation: TerminalLocationString; } export const DEFAULT_LOCAL_ECHO_EXCLUDE: ReadonlyArray = ['vim', 'vi', 'nano', 'tmux']; diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index b601aeb16f252..4ce8967c10029 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -6,7 +6,7 @@ import { Extensions, IConfigurationNode, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { localize } from 'vs/nls'; import { DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, TerminalCursorStyle, DEFAULT_COMMANDS_TO_SKIP_SHELL, SUGGESTIONS_FONT_WEIGHT, MINIMUM_FONT_WEIGHT, MAXIMUM_FONT_WEIGHT, DEFAULT_LOCAL_ECHO_EXCLUDE } from 'vs/workbench/contrib/terminal/common/terminal'; -import { TerminalLocation, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; +import { TerminalLocationString, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { isMacintosh, isWindows } from 'vs/base/common/platform'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -78,7 +78,7 @@ const terminalConfiguration: IConfigurationNode = { }, [TerminalSettingId.DefaultLocation]: { type: 'string', - enum: [TerminalLocation.Editor, TerminalLocation.Panel], + enum: [TerminalLocationString.Editor, TerminalLocationString.TerminalView], enumDescriptions: [ localize('terminal.integrated.defaultLocation.editor', "Create terminals in the editor"), localize('terminal.integrated.defaultLocation.view', "Create terminals in the terminal view") From b6046df5d2f3badc23e6d324581b8e1e42fc9da6 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 18 Aug 2021 12:47:28 -0700 Subject: [PATCH 16/24] splitting is broken with parentTerminal unable to be resolved in mainthread --- .../api/browser/mainThreadTerminalService.ts | 13 ++++------- .../workbench/api/common/extHost.protocol.ts | 2 -- .../api/common/extHostTerminalService.ts | 22 +++++++++++++------ .../api/node/extHostTerminalService.ts | 3 ++- .../terminal/browser/terminalService.ts | 2 ++ 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index b847212ece0d0..11ec10aa5ea5d 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -139,27 +139,22 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape extHostTerminalId, isFeatureTerminal: launchConfig.isFeatureTerminal, isExtensionOwnedTerminal: launchConfig.isExtensionOwnedTerminal, - useShellEnvironment: launchConfig.useShellEnvironment + useShellEnvironment: launchConfig.useShellEnvironment, }; + const location = await this._resolveMainThreadLocation(launchConfig.location); this._extHostTerminals.set(extHostTerminalId, new Promise(async r => { let terminal: ITerminalInstance | undefined; - if (launchConfig.isSplitTerminal) { - const activeInstance = this._terminalService.getInstanceHost(launchConfig.target).activeInstance; - if (activeInstance) { - terminal = withNullAsUndefined(await this._terminalService.createTerminal({ location: { parentTerminal: activeInstance }, config: shellLaunchConfig })); - } - } if (!terminal) { terminal = await this._terminalService.createTerminal({ config: shellLaunchConfig, - location: launchConfig.location ? await this._resolveMainThreadLocation(launchConfig.location) : undefined + location }); } r(terminal); })); } - private async _resolveMainThreadLocation(location: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }): Promise { + private async _resolveMainThreadLocation(location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }): Promise { if (typeof location === 'object' && 'parentTerminal' in location) { const parentTerminal = await this._extHostTerminals.get(location.parentTerminal._id.toString()); return parentTerminal ? { parentTerminal } : undefined; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 3c0079904dad7..b2339815405d8 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -486,8 +486,6 @@ export interface TerminalLaunchConfig { isFeatureTerminal?: boolean; isExtensionOwnedTerminal?: boolean; useShellEnvironment?: boolean; - isSplitTerminal?: boolean; - target?: TerminalLocation; location?: TerminalLocation | { viewColumn: number, preserveFocus?: boolean } | { parentTerminal: ExtHostTerminal }; } diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 2b5a2b6c4a9dd..098f85fcfae06 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -51,7 +51,7 @@ export interface IExtHostTerminalService extends ExtHostTerminalServiceShape, ID export interface ITerminalInternalOptions { isFeatureTerminal?: boolean; useShellEnvironment?: boolean; - location?: TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }; + parentTerminal?: ExtHostTerminal; } export const IExtHostTerminalService = createDecorator('IExtHostTerminalService'); @@ -146,11 +146,11 @@ export class ExtHostTerminal { isFeatureTerminal: withNullAsUndefined(internalOptions?.isFeatureTerminal), isExtensionOwnedTerminal: true, useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), - location: options.location ? this._resolveExtHostLocation(options.location) : undefined + location: this._resolveExtHostLocation(options.location, internalOptions?.parentTerminal) }); } - private _resolveExtHostLocation(location: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminal): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal } | undefined { + private _resolveExtHostLocation(location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminal): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal } | undefined { if (typeof location === 'object' && 'parentTerminal' in location) { // use the ExtHostTerminal with value = to the parentTerminal return parentTerminal ? { parentTerminal } : undefined; @@ -158,7 +158,7 @@ export class ExtHostTerminal { return location; } - public async createExtensionTerminal(iconPath?: TerminalIcon, color?: ThemeColor): Promise { + public async createExtensionTerminal(location?: TerminalLocation | vscode.TerminalEditorLocationOptions, parentTerminal?: ExtHostTerminal, iconPath?: TerminalIcon, color?: ThemeColor): Promise { if (typeof this._id !== 'string') { throw new Error('Terminal has already been created'); } @@ -166,7 +166,8 @@ export class ExtHostTerminal { name: this._name, isExtensionCustomPtyTerminal: true, icon: iconPath, - color: ThemeColor.isThemeColor(color) ? color.id : undefined + color: ThemeColor.isThemeColor(color) ? color.id : undefined, + location: this._resolveExtHostLocation(location, parentTerminal) }); // At this point, the id has been set via `$acceptTerminalOpened` if (typeof this._id === 'string') { @@ -397,7 +398,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I public createExtensionTerminal(options: vscode.ExtensionTerminalOptions, internalOptions?: ITerminalInternalOptions): vscode.Terminal { const terminal = new ExtHostTerminal(this._proxy, generateUuid(), options, options.name); const p = new ExtHostPseudoterminal(options.pty); - terminal.createExtensionTerminal(asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { + terminal.createExtensionTerminal(this._resolveLocation(options.location), internalOptions?.parentTerminal, asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { const disposable = this._setupExtHostProcessListeners(id, p); this._terminalProcessDisposables[id] = disposable; }); @@ -405,6 +406,13 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I return terminal.value; } + private _resolveLocation(location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions): undefined | TerminalLocation | vscode.TerminalEditorLocationOptions { + if (typeof location === 'object' && 'parentTerminal' in location) { + return undefined; + } + return location; + } + public attachPtyToTerminal(id: number, pty: vscode.Pseudoterminal): void { const terminal = this._getTerminalById(id); if (!terminal) { @@ -649,7 +657,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I if (id) { const index = this._getTerminalObjectIndexById(this._terminals, id); if (index) { - opts.location = { parentTerminal: this._terminals[index] }; + opts.parentTerminal = this._terminals[index]; } } } diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 35fb8991d4fa6..9405854c4e64f 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -29,10 +29,11 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { const parentExtHostTerminal = this._terminals.find(t => t.value === parentTerminal); internalOptions = internalOptions ? internalOptions : {}; if (parentExtHostTerminal) { - internalOptions.location = { parentTerminal: parentExtHostTerminal }; + internalOptions.parentTerminal = parentExtHostTerminal; } } } + console.log(internalOptions?.parentTerminal); terminal.create(options, internalOptions); return terminal.value; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 1704cf89a1c95..28b39814a232b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -1179,6 +1179,8 @@ export class TerminalService implements ITerminalService { return options.location.viewColumn === SIDE_GROUP; } else if ('parentTerminal' in options.location) { return true; + } else if ('splitActive' in options.location) { + return true; } } return false; From 8dce8c2ce4077a502984ae6f31e2eb700f97e5f3 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 18 Aug 2021 13:19:57 -0700 Subject: [PATCH 17/24] delete console.logs --- src/vs/workbench/api/browser/mainThreadTerminalService.ts | 3 +-- src/vs/workbench/api/node/extHostTerminalService.ts | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 11ec10aa5ea5d..d4960d57975a3 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -141,13 +141,12 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape isExtensionOwnedTerminal: launchConfig.isExtensionOwnedTerminal, useShellEnvironment: launchConfig.useShellEnvironment, }; - const location = await this._resolveMainThreadLocation(launchConfig.location); this._extHostTerminals.set(extHostTerminalId, new Promise(async r => { let terminal: ITerminalInstance | undefined; if (!terminal) { terminal = await this._terminalService.createTerminal({ config: shellLaunchConfig, - location + location: await this._resolveMainThreadLocation(launchConfig.location) }); } r(terminal); diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 9405854c4e64f..ed3f11b766da0 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -33,7 +33,6 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { } } } - console.log(internalOptions?.parentTerminal); terminal.create(options, internalOptions); return terminal.value; } From d28dffd9075a558e26db58f6b835215dee80d1f6 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 18 Aug 2021 13:57:14 -0700 Subject: [PATCH 18/24] clean up --- src/vs/platform/terminal/common/terminal.ts | 2 +- .../api/browser/mainThreadTerminalService.ts | 14 ++++------ .../api/common/extHostTerminalService.ts | 26 ++++++++++++------- .../api/node/extHostTerminalService.ts | 2 +- .../contrib/terminal/browser/terminal.ts | 2 +- .../contrib/terminal/browser/terminalMenus.ts | 2 +- .../terminal/browser/terminalService.ts | 18 +++++-------- 7 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index e10a1555994fd..bcf3ebc75e4f8 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -401,7 +401,7 @@ export enum TerminalLocation { Editor = 1 } -export enum TerminalLocationString { +export const enum TerminalLocationString { TerminalView = 'view', Editor = 'editor' } diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index d4960d57975a3..f461556b8466e 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -142,13 +142,10 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape useShellEnvironment: launchConfig.useShellEnvironment, }; this._extHostTerminals.set(extHostTerminalId, new Promise(async r => { - let terminal: ITerminalInstance | undefined; - if (!terminal) { - terminal = await this._terminalService.createTerminal({ - config: shellLaunchConfig, - location: await this._resolveMainThreadLocation(launchConfig.location) - }); - } + const terminal = await this._terminalService.createTerminal({ + config: shellLaunchConfig, + location: await this._resolveMainThreadLocation(launchConfig.location) + }); r(terminal); })); } @@ -225,8 +222,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape // Proxy profile provider requests through the extension host this._profileProviders.set(id, this._terminalService.registerTerminalProfileProvider(extensionIdentifier, id, { createContributedTerminalProfile: async (options) => { - const resolvedOptions = this._resolveOptions(options); - return this._proxy.$createContributedProfileTerminal(id, resolvedOptions); + return this._proxy.$createContributedProfileTerminal(id, this._resolveOptions(options)); } })); } diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 098f85fcfae06..6ec22df858122 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -51,7 +51,7 @@ export interface IExtHostTerminalService extends ExtHostTerminalServiceShape, ID export interface ITerminalInternalOptions { isFeatureTerminal?: boolean; useShellEnvironment?: boolean; - parentTerminal?: ExtHostTerminal; + resolvedExtHostTerminal?: ExtHostTerminal; } export const IExtHostTerminalService = createDecorator('IExtHostTerminalService'); @@ -146,7 +146,7 @@ export class ExtHostTerminal { isFeatureTerminal: withNullAsUndefined(internalOptions?.isFeatureTerminal), isExtensionOwnedTerminal: true, useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), - location: this._resolveExtHostLocation(options.location, internalOptions?.parentTerminal) + location: this._resolveExtHostLocation(options.location, internalOptions?.resolvedExtHostTerminal) }); } @@ -398,7 +398,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I public createExtensionTerminal(options: vscode.ExtensionTerminalOptions, internalOptions?: ITerminalInternalOptions): vscode.Terminal { const terminal = new ExtHostTerminal(this._proxy, generateUuid(), options, options.name); const p = new ExtHostPseudoterminal(options.pty); - terminal.createExtensionTerminal(this._resolveLocation(options.location), internalOptions?.parentTerminal, asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { + terminal.createExtensionTerminal(this._resolveLocation(options.location), internalOptions?.resolvedExtHostTerminal, asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { const disposable = this._setupExtHostProcessListeners(id, p); this._terminalProcessDisposables[id] = disposable; }); @@ -651,21 +651,27 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I if (!profile || !('options' in profile)) { throw new Error(`No terminal profile options provided for id "${id}"`); } - const opts: ITerminalInternalOptions = {}; + + const internalOptions: ITerminalInternalOptions = this._resolveParentTerminal(options); + if ('pty' in profile.options) { + this.createExtensionTerminal(profile.options, internalOptions); + return; + } + this.createTerminalFromOptions(profile.options, internalOptions); + } + + private _resolveParentTerminal(options: ICreateContributedTerminalProfileOptions): ITerminalInternalOptions { + let internalOptions: ITerminalInternalOptions = {}; if (options.location && typeof options.location === 'object' && 'splitActive' in options.location) { const id = this._terminals.find(t => t.value === this.activeTerminal)?._id; if (id) { const index = this._getTerminalObjectIndexById(this._terminals, id); if (index) { - opts.parentTerminal = this._terminals[index]; + internalOptions.resolvedExtHostTerminal = this._terminals[index]; } } } - if ('pty' in profile.options) { - this.createExtensionTerminal(profile.options, opts); - return; - } - this.createTerminalFromOptions(profile.options, opts); + return internalOptions; } public async $provideLinks(terminalId: number, line: string): Promise { diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index ed3f11b766da0..3c47f9816501b 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -29,7 +29,7 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { const parentExtHostTerminal = this._terminals.find(t => t.value === parentTerminal); internalOptions = internalOptions ? internalOptions : {}; if (parentExtHostTerminal) { - internalOptions.parentTerminal = parentExtHostTerminal; + internalOptions.resolvedExtHostTerminal = parentExtHostTerminal; } } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 52ba990ffbb41..2747a7c55d11f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -235,7 +235,7 @@ export interface ICreateTerminalOptions { resource?: URI; /** - * The location at which to create the terminal + * The terminal's location (editor or panel), it's terminal parent (split to the right), or editor group */ location?: ITerminalLocationOptions; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts index a8acb0b541573..d80f3b6e1a891 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts @@ -662,7 +662,7 @@ export function getTerminalActionBarArgs(location: TerminalLocation, profiles: I }, { shouldForwardArgs: true, - arg: { target: location } as ICreateTerminalOptions, + arg: { location } as ICreateTerminalOptions, }); const dropdownAction = new Action('refresh profiles', 'Launch Profile...', 'codicon-chevron-down', true); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 28b39814a232b..c601f1a4dcd61 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -1032,16 +1032,12 @@ export class TerminalService implements ITerminalService { } } - private _resolveOptions(options: any): ICreateContributedTerminalProfileOptions { - const opts: ICreateContributedTerminalProfileOptions = {}; - opts.icon = options.icon; - opts.color = options.color; - if (options.location && typeof options.location === 'object' && 'splitActive' in options.location) { - if (this.activeInstance) { - opts.location = { parentTerminal: this.activeInstance }; - } + private _resolveOptions(options: ICreateContributedTerminalProfileOptions): ICreateContributedTerminalProfileOptions { + const profileOptions: ICreateContributedTerminalProfileOptions = { icon: options?.icon, color: options?.color }; + if (options.location && typeof options.location === 'object' && 'splitActive' in options.location && this.activeInstance) { + profileOptions.location = { parentTerminal: this.activeInstance }; } - return opts; + return profileOptions; } private async _registerContributedProfile(extensionIdentifier: string, id: string, title: string, options: ICreateContributedTerminalProfileOptions): Promise { @@ -1177,9 +1173,7 @@ export class TerminalService implements ITerminalService { if (options?.location && typeof options.location === 'object') { if ('viewColumn' in options.location) { return options.location.viewColumn === SIDE_GROUP; - } else if ('parentTerminal' in options.location) { - return true; - } else if ('splitActive' in options.location) { + } else if ('parentTerminal' in options.location || 'splitActive' in options.location) { return true; } } From 163bfe6263cb2ad6294b8d2821ed4bb498b5b426 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 18 Aug 2021 13:59:09 -0700 Subject: [PATCH 19/24] add todo --- src/vs/workbench/contrib/terminal/browser/terminalService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index c601f1a4dcd61..b42a98cc2c720 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -1169,6 +1169,7 @@ export class TerminalService implements ITerminalService { return parent ? this._splitTerminal(shellLaunchConfig, location, parent) : this._createTerminal(shellLaunchConfig, location, options); } + //TODO - is this needed? private _isSplitTerminal(options?: ICreateTerminalOptions): boolean { if (options?.location && typeof options.location === 'object') { if ('viewColumn' in options.location) { From b62b4de70728d89c4f327758cd2b0570a4c0e282 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 19 Aug 2021 12:26:55 -0700 Subject: [PATCH 20/24] use ExtHostTerminalIdentifier instead of ExtHostTerminal --- src/vs/platform/terminal/common/terminal.ts | 2 +- .../api/browser/mainThreadTerminalService.ts | 19 +++++----- .../workbench/api/common/extHost.protocol.ts | 13 +++---- .../api/common/extHostTerminalService.ts | 37 ++++++++----------- .../api/node/extHostTerminalService.ts | 12 ++++-- 5 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index fde60ecfcc24a..30d8f491f6ec1 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -394,7 +394,7 @@ export interface IShellLaunchConfig { export interface ICreateContributedTerminalProfileOptions { icon?: URI | string | { light: URI, dark: URI }; color?: string; - location?: TerminalLocation | { viewColumn: number, preserveState?: boolean } | { splitActive: boolean }; + location?: TerminalLocation | { viewColumn: number, preserveState?: boolean } | { parentTerminal: number }; } export enum TerminalLocation { diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index f461556b8466e..cda8e4b26350c 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { DisposableStore, Disposable, IDisposable } from 'vs/base/common/lifecycle'; -import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, TerminalLaunchConfig, ITerminalDimensionsDto, TerminalIdentifier } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, TerminalLaunchConfig, ITerminalDimensionsDto, ExtHostTerminalIdentifier } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; @@ -21,7 +21,6 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA import { withNullAsUndefined } from 'vs/base/common/types'; import { OperatingSystem, OS } from 'vs/base/common/platform'; import { TerminalEditorLocationOptions } from 'vscode'; -import { ExtHostTerminal } from 'vs/workbench/api/common/extHostTerminalService'; @extHostNamedCustomer(MainContext.MainThreadTerminalService) export class MainThreadTerminalService implements MainThreadTerminalServiceShape { @@ -112,7 +111,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._proxy.$acceptDefaultProfile(...await Promise.all([defaultProfile, defaultAutomationProfile])); } - private async _getTerminalInstance(id: TerminalIdentifier): Promise { + private async _getTerminalInstance(id: ExtHostTerminalIdentifier): Promise { if (typeof id === 'string') { return this._extHostTerminals.get(id); } @@ -144,21 +143,21 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._extHostTerminals.set(extHostTerminalId, new Promise(async r => { const terminal = await this._terminalService.createTerminal({ config: shellLaunchConfig, - location: await this._resolveMainThreadLocation(launchConfig.location) + location: await this._deserializeParentTerminal(launchConfig.location) }); r(terminal); })); } - private async _resolveMainThreadLocation(location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal }): Promise { + private async _deserializeParentTerminal(location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminalIdentifier }): Promise { if (typeof location === 'object' && 'parentTerminal' in location) { - const parentTerminal = await this._extHostTerminals.get(location.parentTerminal._id.toString()); + const parentTerminal = await this._extHostTerminals.get(location.parentTerminal.toString()); return parentTerminal ? { parentTerminal } : undefined; } return location; } - public async $show(id: TerminalIdentifier, preserveFocus: boolean): Promise { + public async $show(id: ExtHostTerminalIdentifier, preserveFocus: boolean): Promise { const terminalInstance = await this._getTerminalInstance(id); if (terminalInstance) { this._terminalService.setActiveInstance(terminalInstance); @@ -170,7 +169,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } } - public async $hide(id: TerminalIdentifier): Promise { + public async $hide(id: ExtHostTerminalIdentifier): Promise { const instanceToHide = await this._getTerminalInstance(id); const activeInstance = this._terminalService.activeInstance; if (activeInstance && activeInstance.instanceId === instanceToHide?.instanceId && activeInstance.target !== TerminalLocation.Editor) { @@ -178,11 +177,11 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } } - public async $dispose(id: TerminalIdentifier): Promise { + public async $dispose(id: ExtHostTerminalIdentifier): Promise { (await this._getTerminalInstance(id))?.dispose(); } - public async $sendText(id: TerminalIdentifier, text: string, addNewLine: boolean): Promise { + public async $sendText(id: ExtHostTerminalIdentifier, text: string, addNewLine: boolean): Promise { const instance = await this._getTerminalInstance(id); await instance?.sendText(text, addNewLine); } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 5af5064beee94..42cc7127ca2af 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -46,7 +46,6 @@ import { IExtensionIdWithVersion } from 'vs/platform/userDataSync/common/extensi import { WorkspaceTrustRequestOptions } from 'vs/platform/workspace/common/workspaceTrust'; import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtHostInteractive } from 'vs/workbench/api/common/extHostInteractive'; -import { ExtHostTerminal } from 'vs/workbench/api/common/extHostTerminalService'; import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService'; import { DebugConfigurationProviderTriggerKind } from 'vs/workbench/api/common/extHostTypes'; import * as tasks from 'vs/workbench/api/common/shared/tasks'; @@ -468,7 +467,7 @@ export interface MainThreadProgressShape extends IDisposable { * All other terminals (that are not created on the extension host side) always * use the numeric id. */ -export type TerminalIdentifier = number | string; +export type ExtHostTerminalIdentifier = number | string; export interface TerminalLaunchConfig { name?: string; @@ -486,15 +485,15 @@ export interface TerminalLaunchConfig { isFeatureTerminal?: boolean; isExtensionOwnedTerminal?: boolean; useShellEnvironment?: boolean; - location?: TerminalLocation | { viewColumn: number, preserveFocus?: boolean } | { parentTerminal: ExtHostTerminal }; + location?: TerminalLocation | { viewColumn: number, preserveFocus?: boolean } | { parentTerminal: ExtHostTerminalIdentifier }; } export interface MainThreadTerminalServiceShape extends IDisposable { $createTerminal(extHostTerminalId: string, config: TerminalLaunchConfig): Promise; - $dispose(id: TerminalIdentifier): void; - $hide(id: TerminalIdentifier): void; - $sendText(id: TerminalIdentifier, text: string, addNewLine: boolean): void; - $show(id: TerminalIdentifier, preserveFocus: boolean): void; + $dispose(id: ExtHostTerminalIdentifier): void; + $hide(id: ExtHostTerminalIdentifier): void; + $sendText(id: ExtHostTerminalIdentifier, text: string, addNewLine: boolean): void; + $show(id: ExtHostTerminalIdentifier, preserveFocus: boolean): void; $startSendingDataEvents(): void; $stopSendingDataEvents(): void; $startLinkProvider(): void; diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 6ec22df858122..d46d9275b119a 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -5,7 +5,7 @@ import type * as vscode from 'vscode'; import { Event, Emitter } from 'vs/base/common/event'; -import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, ITerminalDimensionsDto, ITerminalLinkDto, TerminalIdentifier } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, ITerminalDimensionsDto, ITerminalLinkDto, ExtHostTerminalIdentifier } from 'vs/workbench/api/common/extHost.protocol'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { URI } from 'vs/base/common/uri'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; @@ -51,7 +51,7 @@ export interface IExtHostTerminalService extends ExtHostTerminalServiceShape, ID export interface ITerminalInternalOptions { isFeatureTerminal?: boolean; useShellEnvironment?: boolean; - resolvedExtHostTerminal?: ExtHostTerminal; + resolvedExtHostIdentifier?: ExtHostTerminalIdentifier; } export const IExtHostTerminalService = createDecorator('IExtHostTerminalService'); @@ -71,7 +71,7 @@ export class ExtHostTerminal { constructor( private _proxy: MainThreadTerminalServiceShape, - public _id: TerminalIdentifier, + public _id: ExtHostTerminalIdentifier, private readonly _creationOptions: vscode.TerminalOptions | vscode.ExtensionTerminalOptions, private _name?: string, ) { @@ -146,19 +146,12 @@ export class ExtHostTerminal { isFeatureTerminal: withNullAsUndefined(internalOptions?.isFeatureTerminal), isExtensionOwnedTerminal: true, useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), - location: this._resolveExtHostLocation(options.location, internalOptions?.resolvedExtHostTerminal) + location: this._serializeParentTerminal(options.location, internalOptions?.resolvedExtHostIdentifier) }); } - private _resolveExtHostLocation(location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminal): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminal } | undefined { - if (typeof location === 'object' && 'parentTerminal' in location) { - // use the ExtHostTerminal with value = to the parentTerminal - return parentTerminal ? { parentTerminal } : undefined; - } - return location; - } - public async createExtensionTerminal(location?: TerminalLocation | vscode.TerminalEditorLocationOptions, parentTerminal?: ExtHostTerminal, iconPath?: TerminalIcon, color?: ThemeColor): Promise { + public async createExtensionTerminal(location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminalIdentifier, iconPath?: TerminalIcon, color?: ThemeColor): Promise { if (typeof this._id !== 'string') { throw new Error('Terminal has already been created'); } @@ -167,7 +160,7 @@ export class ExtHostTerminal { isExtensionCustomPtyTerminal: true, icon: iconPath, color: ThemeColor.isThemeColor(color) ? color.id : undefined, - location: this._resolveExtHostLocation(location, parentTerminal) + location: this._serializeParentTerminal(location, parentTerminal) }); // At this point, the id has been set via `$acceptTerminalOpened` if (typeof this._id === 'string') { @@ -176,6 +169,13 @@ export class ExtHostTerminal { return this._id; } + private _serializeParentTerminal(location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminalIdentifier): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminalIdentifier } | undefined { + if (typeof location === 'object' && 'parentTerminal' in location) { + return parentTerminal ? { parentTerminal } : undefined; + } + return location; + } + private _checkDisposed() { if (this._disposed) { throw new Error('Terminal has already been disposed'); @@ -398,7 +398,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I public createExtensionTerminal(options: vscode.ExtensionTerminalOptions, internalOptions?: ITerminalInternalOptions): vscode.Terminal { const terminal = new ExtHostTerminal(this._proxy, generateUuid(), options, options.name); const p = new ExtHostPseudoterminal(options.pty); - terminal.createExtensionTerminal(this._resolveLocation(options.location), internalOptions?.resolvedExtHostTerminal, asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { + terminal.createExtensionTerminal(this._resolveLocation(options.location), internalOptions?.resolvedExtHostIdentifier, asTerminalIcon(options.iconPath), asTerminalColor(options.color)).then(id => { const disposable = this._setupExtHostProcessListeners(id, p); this._terminalProcessDisposables[id] = disposable; }); @@ -664,12 +664,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I let internalOptions: ITerminalInternalOptions = {}; if (options.location && typeof options.location === 'object' && 'splitActive' in options.location) { const id = this._terminals.find(t => t.value === this.activeTerminal)?._id; - if (id) { - const index = this._getTerminalObjectIndexById(this._terminals, id); - if (index) { - internalOptions.resolvedExtHostTerminal = this._terminals[index]; - } - } + internalOptions.resolvedExtHostIdentifier = id; } return internalOptions; } @@ -770,7 +765,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I return index !== null ? array[index] : null; } - private _getTerminalObjectIndexById(array: T[], id: TerminalIdentifier): number | null { + private _getTerminalObjectIndexById(array: T[], id: ExtHostTerminalIdentifier): number | null { let index: number | null = null; array.some((item, i) => { const thisId = item._id; diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 3c47f9816501b..dadc49d7e4535 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -23,17 +23,21 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { public createTerminalFromOptions(options: vscode.TerminalOptions, internalOptions?: ITerminalInternalOptions): vscode.Terminal { const terminal = new ExtHostTerminal(this._proxy, generateUuid(), options, options.name); this._terminals.push(terminal); + terminal.create(options, this._serializeParentTerminal(options, internalOptions)); + return terminal.value; + } + + private _serializeParentTerminal(options: vscode.TerminalOptions, internalOptions?: ITerminalInternalOptions): ITerminalInternalOptions { + internalOptions = internalOptions ? internalOptions : {}; if (options.location && typeof options.location === 'object' && 'parentTerminal' in options.location) { const parentTerminal = options.location.parentTerminal; if (parentTerminal) { const parentExtHostTerminal = this._terminals.find(t => t.value === parentTerminal); - internalOptions = internalOptions ? internalOptions : {}; if (parentExtHostTerminal) { - internalOptions.resolvedExtHostTerminal = parentExtHostTerminal; + internalOptions.resolvedExtHostIdentifier = parentExtHostTerminal._id; } } } - terminal.create(options, internalOptions); - return terminal.value; + return internalOptions; } } From 1e2febc25025c84d6b07a8e2b5bd9199e817c055 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 19 Aug 2021 12:57:43 -0700 Subject: [PATCH 21/24] Update src/vs/workbench/contrib/terminal/browser/terminalService.ts Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- .../terminal/browser/terminalService.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 7a46a1383aa13..435335316caa6 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -1223,12 +1223,18 @@ export class TerminalService implements ITerminalService { private _resolveLocation(location?: ITerminalLocationOptions): TerminalLocation | undefined { if (!location) { return location; - } else if (typeof location === 'object' && 'parentTerminal' in location) { - return location.parentTerminal.target; - } else if (typeof location === 'object' && 'viewColumn' in location) { - return TerminalLocation.Editor; - } else if (typeof location === 'object' && 'splitActive' in location) { - return this._activeInstance?.target; + } + if (typeof location !== 'object') { + if ('parentTerminal' in location) { + return location.parentTerminal.target; + } + if ('viewColumn' in location) { + return TerminalLocation.Editor; + } + // TODO: Remove splitActive? + if ('splitActive' in location) { + return this._activeInstance?.target; + } } return location; } From 00f62752e258dba90bebc5a0ccb7909a40735f93 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 19 Aug 2021 13:00:44 -0700 Subject: [PATCH 22/24] clean up --- src/vs/platform/terminal/common/terminal.ts | 2 +- .../api/browser/mainThreadTerminalService.ts | 11 +--- .../api/common/extHostTerminalService.ts | 11 +++- .../contrib/terminal/browser/terminal.ts | 14 ++--- .../terminal/browser/terminalActions.ts | 10 ++-- .../terminal/browser/terminalEditorService.ts | 5 +- .../terminal/browser/terminalService.ts | 55 ++++++++----------- 7 files changed, 45 insertions(+), 63 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 30d8f491f6ec1..c6bbf7b8d9495 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -394,7 +394,7 @@ export interface IShellLaunchConfig { export interface ICreateContributedTerminalProfileOptions { icon?: URI | string | { light: URI, dark: URI }; color?: string; - location?: TerminalLocation | { viewColumn: number, preserveState?: boolean } | { parentTerminal: number }; + location?: TerminalLocation | { viewColumn: number, preserveState?: boolean } | { parentTerminal: any }; } export enum TerminalLocation { diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index cda8e4b26350c..e771502f66ca5 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; -import { ICreateContributedTerminalProfileOptions, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensions, TerminalLocation, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensions, TerminalLocation, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; import { ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, ITerminalLink, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy'; @@ -221,18 +221,11 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape // Proxy profile provider requests through the extension host this._profileProviders.set(id, this._terminalService.registerTerminalProfileProvider(extensionIdentifier, id, { createContributedTerminalProfile: async (options) => { - return this._proxy.$createContributedProfileTerminal(id, this._resolveOptions(options)); + return this._proxy.$createContributedProfileTerminal(id, options); } })); } - private _resolveOptions(options: any): ICreateContributedTerminalProfileOptions { - if (options.location && typeof options.location === 'object' && 'parentTerminal' in options.location) { - options.location = { splitActive: true }; - } - return options; - } - public $unregisterProfileProvider(id: string): void { this._profileProviders.get(id)?.dispose(); this._profileProviders.delete(id); diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index d46d9275b119a..c1c920aa236b2 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -662,9 +662,14 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I private _resolveParentTerminal(options: ICreateContributedTerminalProfileOptions): ITerminalInternalOptions { let internalOptions: ITerminalInternalOptions = {}; - if (options.location && typeof options.location === 'object' && 'splitActive' in options.location) { - const id = this._terminals.find(t => t.value === this.activeTerminal)?._id; - internalOptions.resolvedExtHostIdentifier = id; + if (options.location && typeof options.location === 'object' && 'parentTerminal' in options.location) { + const location = options.location; + if ('parentTerminal' in location) { + const extHostTerminal = this._terminals.find(t => t._id === location.parentTerminal.toString()); + if (extHostTerminal) { + internalOptions.resolvedExtHostIdentifier = extHostTerminal._id; + } + } } return internalOptions; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 2747a7c55d11f..5e782e28e3585 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -8,7 +8,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { FindReplaceState } from 'vs/editor/contrib/find/findState'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource, TerminalShellType, IExtensionTerminalProfile, ITerminalProfileType, TerminalLocation } from 'vs/platform/terminal/common/terminal'; +import { IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource, TerminalShellType, IExtensionTerminalProfile, ITerminalProfileType, TerminalLocation, ICreateContributedTerminalProfileOptions } from 'vs/platform/terminal/common/terminal'; import { ICommandTracker, INavigationMode, IOffProcessTerminalService, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal'; import type { Terminal as XTermTerminal } from 'xterm'; import type { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; @@ -184,7 +184,7 @@ export interface ITerminalService extends ITerminalInstanceHost { safeDisposeTerminal(instance: ITerminalInstance): Promise; getDefaultInstanceHost(): ITerminalInstanceHost; - getInstanceHost(target: TerminalLocation | undefined): ITerminalInstanceHost; + getInstanceHost(target: ITerminalLocationOptions | undefined): ITerminalInstanceHost; getFindHost(instance?: ITerminalInstance): ITerminalFindHost; getDefaultProfileName(): string; @@ -200,7 +200,7 @@ export interface ITerminalEditorService extends ITerminalInstanceHost, ITerminal /** Gets all _terminal editor_ instances. */ readonly instances: readonly ITerminalInstance[]; - openEditor(instance: ITerminalInstance, sideGroup?: boolean, editorOptions?: TerminalEditorLocation): Promise; + openEditor(instance: ITerminalInstance, editorOptions?: TerminalEditorLocation): Promise; detachActiveEditorInstance(): ITerminalInstance; detachInstance(instance: ITerminalInstance): void; splitInstance(instanceToSplit: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig): ITerminalInstance; @@ -210,13 +210,7 @@ export interface ITerminalEditorService extends ITerminalInstanceHost, ITerminal getInputFromResource(resource: URI): TerminalEditorInput; } -export type ITerminalLocationOptions = TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance } | { splitActive: boolean }; - -export interface ICreateContributedTerminalProfileOptions { - icon?: URI | string | { light: URI, dark: URI }; - color?: string; - location?: ITerminalLocationOptions; -} +export type ITerminalLocationOptions = TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }; export interface ICreateTerminalOptions { /** diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 03f25862a85bc..0b4372a87650f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -1425,7 +1425,7 @@ export function registerTerminalActions() { const terminalService = accessor.get(ITerminalService); const workspaceContextService = accessor.get(IWorkspaceContextService); const options = convertOptionsOrProfileToOptions(optionsOrProfile); - const activeInstance = terminalService.getInstanceHost(options?.location === TerminalLocation.Editor ? TerminalLocation.Editor : TerminalLocation.Panel).activeInstance; + const activeInstance = terminalService.getInstanceHost(options?.location).activeInstance; if (!activeInstance) { return; } @@ -2026,10 +2026,10 @@ export function refreshTerminalActions(detectedProfiles: ITerminalProfile[]) { const folders = workspaceContextService.getWorkspace().folders; if (event && (event.altKey || event.ctrlKey)) { - const activeInstance = terminalService.activeInstance; - if (activeInstance) { - const cwd = await getCwdForSplit(terminalService.configHelper, activeInstance); - await terminalService.createTerminal({ location: { parentTerminal: activeInstance }, config: options?.config, cwd }); + const parentTerminal = terminalService.activeInstance; + if (parentTerminal) { + const cwd = await getCwdForSplit(terminalService.configHelper, parentTerminal); + await terminalService.createTerminal({ location: { parentTerminal }, config: options?.config, cwd }); return; } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts index 6625663165537..a13d8ffcb90fa 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts @@ -158,7 +158,7 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor this._onDidChangeActiveInstance.fire(this.activeInstance); } - async openEditor(instance: ITerminalInstance, sideGroup: boolean = false, editorOptions?: TerminalEditorLocation): Promise { + async openEditor(instance: ITerminalInstance, editorOptions?: TerminalEditorLocation): Promise { const resource = this.resolveResource(instance); if (resource) { await this._editorService.openEditor({ @@ -169,8 +169,7 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor forceReload: true, preserveFocus: editorOptions?.preserveFocus } - }, - editorOptions?.viewColumn || (sideGroup ? SIDE_GROUP : undefined)); + }, editorOptions?.viewColumn); } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 435335316caa6..ca82653787e55 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -23,7 +23,7 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IKeyMods, IPickOptions, IQuickInputButton, IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IExtensionTerminalProfile, IShellLaunchConfig, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalProfileType, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalLocationString, TerminalSettingId, TerminalSettingPrefix } from 'vs/platform/terminal/common/terminal'; +import { ICreateContributedTerminalProfileOptions, IExtensionTerminalProfile, IShellLaunchConfig, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalProfileType, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalLocation, TerminalLocationString, TerminalSettingId, TerminalSettingPrefix } from 'vs/platform/terminal/common/terminal'; import { registerTerminalDefaultProfileConfiguration } from 'vs/platform/terminal/common/terminalPlatformConfiguration'; import { iconForeground } from 'vs/platform/theme/common/colorRegistry'; import { IconDefinition } from 'vs/platform/theme/common/iconRegistry'; @@ -31,7 +31,7 @@ import { ColorScheme } from 'vs/platform/theme/common/theme'; import { IThemeService, Themable, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { VirtualWorkspaceContext } from 'vs/workbench/browser/contextkeys'; import { IEditableData, IViewsService } from 'vs/workbench/common/views'; -import { ICreateContributedTerminalProfileOptions, ICreateTerminalOptions, IRemoteTerminalService, IRequestAddInstanceToGroupEvent, ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalFindHost, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceHost, ITerminalInstanceService, ITerminalLocationOptions, ITerminalProfileProvider, ITerminalService, TerminalConnectionState, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ICreateTerminalOptions, IRemoteTerminalService, IRequestAddInstanceToGroupEvent, ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalFindHost, ITerminalGroup, ITerminalGroupService, ITerminalInstance, ITerminalInstanceHost, ITerminalInstanceService, ITerminalLocationOptions, ITerminalProfileProvider, ITerminalService, TerminalConnectionState, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal'; import { refreshTerminalActions } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalEditor } from 'vs/workbench/contrib/terminal/browser/terminalEditor'; @@ -44,7 +44,6 @@ import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/termin import { ITerminalContributionService } from 'vs/workbench/contrib/terminal/common/terminalExtensionPoints'; import { formatMessageForTerminal, terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings'; import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; -import { SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ILifecycleService, ShutdownReason, WillShutdownEvent } from 'vs/workbench/services/lifecycle/common/lifecycle'; @@ -940,7 +939,7 @@ export class TerminalService implements ITerminalService { if ('id' in value.profile) { await this._createContributedTerminalProfile(value.profile.extensionIdentifier, value.profile.id, { - location: !!(keyMods?.alt && activeInstance) ? { splitActive: true } : undefined, + location: !!(keyMods?.alt && activeInstance) ? { parentTerminal: this.activeInstance } : undefined, icon: value.profile.icon, color: value.profile.color }); @@ -1001,12 +1000,19 @@ export class TerminalService implements ITerminalService { return this._terminalGroupService; } - getInstanceHost(target: TerminalLocation | undefined): ITerminalInstanceHost { - if (target) { - if (target === TerminalLocation.Editor) { + getInstanceHost(location: ITerminalLocationOptions | undefined): ITerminalInstanceHost { + if (location) { + if (location === TerminalLocation.Editor) { return this._terminalEditorService; + } else if (typeof location === 'object') { + if ('viewColumn' in location) { + return this._terminalEditorService; + } else if ('parentTerminal' in location) { + return location.parentTerminal.target === TerminalLocation.Editor ? this._terminalEditorService : this._terminalGroupService; + } + } else { + return this._terminalGroupService; } - return this._terminalGroupService; } return this; } @@ -1035,8 +1041,8 @@ export class TerminalService implements ITerminalService { private _resolveOptions(options: ICreateContributedTerminalProfileOptions): ICreateContributedTerminalProfileOptions { const profileOptions: ICreateContributedTerminalProfileOptions = { icon: options?.icon, color: options?.color }; - if (options.location && typeof options.location === 'object' && 'splitActive' in options.location && this.activeInstance) { - profileOptions.location = { parentTerminal: this.activeInstance }; + if (options.location && typeof options.location === 'object' && 'parentTerminal' in options.location) { + profileOptions.location = { parentTerminal: options.location.parentTerminal }; } return profileOptions; } @@ -1167,19 +1173,12 @@ export class TerminalService implements ITerminalService { this._evaluateLocalCwd(shellLaunchConfig); const location = this._resolveLocation(options?.location) || this.defaultLocation; const parent = this._getSplitParent(options?.location); - return parent ? this._splitTerminal(shellLaunchConfig, location, parent) : this._createTerminal(shellLaunchConfig, location, options); - } - //TODO - is this needed? - private _isSplitTerminal(options?: ICreateTerminalOptions): boolean { - if (options?.location && typeof options.location === 'object') { - if ('viewColumn' in options.location) { - return options.location.viewColumn === SIDE_GROUP; - } else if ('parentTerminal' in options.location || 'splitActive' in options.location) { - return true; - } + if (parent) { + return this._splitTerminal(shellLaunchConfig, location, parent); + } else { + return this._createTerminal(shellLaunchConfig, location, options); } - return false; } private _splitTerminal(shellLaunchConfig: IShellLaunchConfig, location: TerminalLocation, parent: ITerminalInstance): ITerminalInstance { @@ -1211,7 +1210,7 @@ export class TerminalService implements ITerminalService { if (location === TerminalLocation.Editor) { instance = this._terminalInstanceService.createInstance(shellLaunchConfig, undefined, options?.resource); instance.target = TerminalLocation.Editor; - this._terminalEditorService.openEditor(instance, this._isSplitTerminal(options), editorOptions); + this._terminalEditorService.openEditor(instance, editorOptions); } else { // TODO: pass resource? const group = this._terminalGroupService.createGroup(shellLaunchConfig); @@ -1223,17 +1222,11 @@ export class TerminalService implements ITerminalService { private _resolveLocation(location?: ITerminalLocationOptions): TerminalLocation | undefined { if (!location) { return location; - } - if (typeof location !== 'object') { + } else if (typeof location === 'object') { if ('parentTerminal' in location) { return location.parentTerminal.target; - } - if ('viewColumn' in location) { + } else if ('viewColumn' in location) { return TerminalLocation.Editor; - } - // TODO: Remove splitActive? - if ('splitActive' in location) { - return this._activeInstance?.target; } } return location; @@ -1242,8 +1235,6 @@ export class TerminalService implements ITerminalService { private _getSplitParent(location?: ITerminalLocationOptions): ITerminalInstance | undefined { if (location && typeof location === 'object' && 'parentTerminal' in location) { return location.parentTerminal; - } else if (location && typeof location === 'object' && 'splitActive' in location) { - return this._activeInstance; } return undefined; } From d55713eb3456049d1b4b2e600cb5d51c838afbdb Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 19 Aug 2021 13:16:37 -0700 Subject: [PATCH 23/24] use instance id for terminal profiles --- src/vs/platform/terminal/common/terminal.ts | 2 +- .../terminal/browser/terminalService.ts | 21 ++++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index c6bbf7b8d9495..30d8f491f6ec1 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -394,7 +394,7 @@ export interface IShellLaunchConfig { export interface ICreateContributedTerminalProfileOptions { icon?: URI | string | { light: URI, dark: URI }; color?: string; - location?: TerminalLocation | { viewColumn: number, preserveState?: boolean } | { parentTerminal: any }; + location?: TerminalLocation | { viewColumn: number, preserveState?: boolean } | { parentTerminal: number }; } export enum TerminalLocation { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index ca82653787e55..66a7161dfae21 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -938,8 +938,12 @@ export class TerminalService implements ITerminalService { let instance; if ('id' in value.profile) { + let parentTerminal = undefined; + if (!!(keyMods?.alt && activeInstance?.instanceId)) { + parentTerminal = { parentTerminal: activeInstance.instanceId }; + } await this._createContributedTerminalProfile(value.profile.extensionIdentifier, value.profile.id, { - location: !!(keyMods?.alt && activeInstance) ? { parentTerminal: this.activeInstance } : undefined, + location: parentTerminal, icon: value.profile.icon, color: value.profile.color }); @@ -1030,8 +1034,7 @@ export class TerminalService implements ITerminalService { return; } try { - const resolvedOptions = this._resolveOptions(options); - await profileProvider.createContributedTerminalProfile(resolvedOptions); + await profileProvider.createContributedTerminalProfile(options); this._terminalGroupService.setActiveInstanceByIndex(this.instances.length - 1); await this.activeInstance?.focusWhenReady(); } catch (e) { @@ -1039,14 +1042,6 @@ export class TerminalService implements ITerminalService { } } - private _resolveOptions(options: ICreateContributedTerminalProfileOptions): ICreateContributedTerminalProfileOptions { - const profileOptions: ICreateContributedTerminalProfileOptions = { icon: options?.icon, color: options?.color }; - if (options.location && typeof options.location === 'object' && 'parentTerminal' in options.location) { - profileOptions.location = { parentTerminal: options.location.parentTerminal }; - } - return profileOptions; - } - private async _registerContributedProfile(extensionIdentifier: string, id: string, title: string, options: ICreateContributedTerminalProfileOptions): Promise { const platformKey = await this._getPlatformKey(); const profilesConfig = await this._configurationService.getValue(`${TerminalSettingPrefix.Profiles}${platformKey}`); @@ -1143,9 +1138,11 @@ export class TerminalService implements ITerminalService { // Launch the contributed profile if (contributedProfile) { + const parent = this._getSplitParent(options?.location); + const location = this._resolveLocation(options?.location) || this.defaultLocation; await this._createContributedTerminalProfile(contributedProfile.extensionIdentifier, contributedProfile.id, { icon: contributedProfile.icon, - location: options?.location, + location: parent ? { parentTerminal: parent.instanceId } : location, color: contributedProfile.color }); const instanceHost = options?.location === TerminalLocation.Editor ? this._terminalEditorService : this._terminalGroupService; From 25692e44bc3afcc851f1dd7dc5bbbeb31474ab92 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 19 Aug 2021 18:59:31 -0700 Subject: [PATCH 24/24] get profiles to work with splits --- src/vs/platform/terminal/common/terminal.ts | 2 +- .../api/browser/mainThreadTerminalService.ts | 2 +- .../workbench/api/common/extHost.protocol.ts | 2 +- .../api/common/extHostTerminalService.ts | 26 +++++-------------- .../contrib/terminal/browser/terminal.ts | 2 +- .../terminal/browser/terminalService.ts | 17 ++++++------ 6 files changed, 19 insertions(+), 32 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 30d8f491f6ec1..3ae78ec6ef729 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -394,7 +394,7 @@ export interface IShellLaunchConfig { export interface ICreateContributedTerminalProfileOptions { icon?: URI | string | { light: URI, dark: URI }; color?: string; - location?: TerminalLocation | { viewColumn: number, preserveState?: boolean } | { parentTerminal: number }; + splitActiveTerminal?: boolean; } export enum TerminalLocation { diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index e771502f66ca5..7029bcd385506 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -149,7 +149,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape })); } - private async _deserializeParentTerminal(location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminalIdentifier }): Promise { + private async _deserializeParentTerminal(location?: TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminalIdentifier } | { splitActiveTerminal: boolean }): Promise { if (typeof location === 'object' && 'parentTerminal' in location) { const parentTerminal = await this._extHostTerminals.get(location.parentTerminal.toString()); return parentTerminal ? { parentTerminal } : undefined; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index d7e2f9e2bb27c..e523906939081 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -485,7 +485,7 @@ export interface TerminalLaunchConfig { isFeatureTerminal?: boolean; isExtensionOwnedTerminal?: boolean; useShellEnvironment?: boolean; - location?: TerminalLocation | { viewColumn: number, preserveFocus?: boolean } | { parentTerminal: ExtHostTerminalIdentifier }; + location?: TerminalLocation | { viewColumn: number, preserveFocus?: boolean } | { parentTerminal: ExtHostTerminalIdentifier } | { splitActiveTerminal: boolean }; } export interface MainThreadTerminalServiceShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 282c82c676100..f78b6ec3ac38d 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -52,6 +52,7 @@ export interface ITerminalInternalOptions { isFeatureTerminal?: boolean; useShellEnvironment?: boolean; resolvedExtHostIdentifier?: ExtHostTerminalIdentifier; + splitActiveTerminal?: boolean; } export const IExtHostTerminalService = createDecorator('IExtHostTerminalService'); @@ -146,7 +147,7 @@ export class ExtHostTerminal { isFeatureTerminal: withNullAsUndefined(internalOptions?.isFeatureTerminal), isExtensionOwnedTerminal: true, useShellEnvironment: withNullAsUndefined(internalOptions?.useShellEnvironment), - location: this._serializeParentTerminal(options.location, internalOptions?.resolvedExtHostIdentifier) + location: this._serializeParentTerminal(options.location, internalOptions?.resolvedExtHostIdentifier, internalOptions?.splitActiveTerminal) }); } @@ -169,9 +170,11 @@ export class ExtHostTerminal { return this._id; } - private _serializeParentTerminal(location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminalIdentifier): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminalIdentifier } | undefined { + private _serializeParentTerminal(location?: TerminalLocation | vscode.TerminalEditorLocationOptions | vscode.TerminalSplitLocationOptions, parentTerminal?: ExtHostTerminalIdentifier, splitActiveTerminal?: boolean): TerminalLocation | vscode.TerminalEditorLocationOptions | { parentTerminal: ExtHostTerminalIdentifier } | { splitActiveTerminal: boolean } | undefined { if (typeof location === 'object' && 'parentTerminal' in location) { return parentTerminal ? { parentTerminal } : undefined; + } else if (splitActiveTerminal) { + return { splitActiveTerminal: true }; } return location; } @@ -649,26 +652,11 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I throw new Error(`No terminal profile options provided for id "${id}"`); } - const internalOptions: ITerminalInternalOptions = this._resolveParentTerminal(options); if ('pty' in profile.options) { - this.createExtensionTerminal(profile.options, internalOptions); + this.createExtensionTerminal(profile.options, options); return; } - this.createTerminalFromOptions(profile.options, internalOptions); - } - - private _resolveParentTerminal(options: ICreateContributedTerminalProfileOptions): ITerminalInternalOptions { - let internalOptions: ITerminalInternalOptions = {}; - if (options.location && typeof options.location === 'object' && 'parentTerminal' in options.location) { - const location = options.location; - if ('parentTerminal' in location) { - const extHostTerminal = this._terminals.find(t => t._id === location.parentTerminal.toString()); - if (extHostTerminal) { - internalOptions.resolvedExtHostIdentifier = extHostTerminal._id; - } - } - } - return internalOptions; + this.createTerminalFromOptions(profile.options, options); } public async $provideLinks(terminalId: number, line: string): Promise { diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 5e782e28e3585..07436d4c0e829 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -210,7 +210,7 @@ export interface ITerminalEditorService extends ITerminalInstanceHost, ITerminal getInputFromResource(resource: URI): TerminalEditorInput; } -export type ITerminalLocationOptions = TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance }; +export type ITerminalLocationOptions = TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance } | { splitActiveTerminal: boolean }; export interface ICreateTerminalOptions { /** diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 66a7161dfae21..a3937089afda1 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -938,12 +938,8 @@ export class TerminalService implements ITerminalService { let instance; if ('id' in value.profile) { - let parentTerminal = undefined; - if (!!(keyMods?.alt && activeInstance?.instanceId)) { - parentTerminal = { parentTerminal: activeInstance.instanceId }; - } await this._createContributedTerminalProfile(value.profile.extensionIdentifier, value.profile.id, { - location: parentTerminal, + splitActiveTerminal: !!(keyMods?.alt && activeInstance), icon: value.profile.icon, color: value.profile.color }); @@ -1138,13 +1134,12 @@ export class TerminalService implements ITerminalService { // Launch the contributed profile if (contributedProfile) { - const parent = this._getSplitParent(options?.location); - const location = this._resolveLocation(options?.location) || this.defaultLocation; await this._createContributedTerminalProfile(contributedProfile.extensionIdentifier, contributedProfile.id, { icon: contributedProfile.icon, - location: parent ? { parentTerminal: parent.instanceId } : location, - color: contributedProfile.color + color: contributedProfile.color, + splitActiveTerminal: typeof options?.location === 'object' && 'splitActiveTerminal' in options.location ? true : false }); + // TODO shouldn't the below use defaultLocation? const instanceHost = options?.location === TerminalLocation.Editor ? this._terminalEditorService : this._terminalGroupService; const instance = instanceHost.instances[instanceHost.instances.length - 1]; await instance.focusWhenReady(); @@ -1224,6 +1219,8 @@ export class TerminalService implements ITerminalService { return location.parentTerminal.target; } else if ('viewColumn' in location) { return TerminalLocation.Editor; + } else if ('splitActiveTerminal' in location) { + return this._activeInstance?.target || this.defaultLocation; } } return location; @@ -1232,6 +1229,8 @@ export class TerminalService implements ITerminalService { private _getSplitParent(location?: ITerminalLocationOptions): ITerminalInstance | undefined { if (location && typeof location === 'object' && 'parentTerminal' in location) { return location.parentTerminal; + } else if (location && typeof location === 'object' && 'splitActiveTerminal' in location) { + return this.activeInstance; } return undefined; }