diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 43c390066a3..e9a4480b6ef 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -409,6 +409,11 @@ export interface ICreateTerminalOptions { * The terminal's resource, passed when the terminal has moved windows. */ resource?: URI; + + /** + * Whether or not this terminal should be a split + */ + isSplitTerminal?: boolean; } export interface ICreateContributedTerminalProfileOptions { diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 28228575f0d..8529093be58 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -133,8 +133,6 @@ export interface ITerminalService extends ITerminalInstanceHost { */ createTerminal(options?: ICreateTerminalOptions): Promise; - createContributedTerminalProfile(extensionIdentifier: string, id: string, options: ICreateContributedTerminalProfileOptions): Promise; - /** * Creates a raw terminal instance, this should not be used outside of the terminal part. */ diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts index 6362b3a0561..f00354b3e89 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditor.ts @@ -238,13 +238,21 @@ export class TerminalEditor extends EditorPane { } } - // TODO: Support contributed profiles with editor target for (const contributed of this._terminalContributionService.terminalProfiles) { - dropdownActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title.replace(/[\n\r\t]/g, ''), undefined, true, () => this._terminalService.createContributedTerminalProfile(contributed.extensionIdentifier, contributed.id, { - isSplitTerminal: false, + dropdownActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title.replace(/[\n\r\t]/g, ''), undefined, true, () => this._terminalService.createTerminal({ + config: { + extensionIdentifier: contributed.extensionIdentifier, + id: contributed.id, + title: contributed.title.replace(/[\n\r\t]/g, '') + }, target: TerminalLocation.Editor }))); - submenuActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title.replace(/[\n\r\t]/g, ''), undefined, true, () => this._terminalService.createContributedTerminalProfile(contributed.extensionIdentifier, contributed.id, { + submenuActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title.replace(/[\n\r\t]/g, ''), undefined, true, () => this._terminalService.createTerminal({ + config: { + extensionIdentifier: contributed.extensionIdentifier, + id: contributed.id, + title: contributed.title.replace(/[\n\r\t]/g, '') + }, isSplitTerminal: true, target: TerminalLocation.Editor }))); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 05de1788a42..3ada4e0f851 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -629,7 +629,7 @@ export class TerminalService implements ITerminalService { const contributedDefaultProfile = await this._getContributedDefaultProfile(shellLaunchConfig); if (contributedDefaultProfile) { - await this.createContributedTerminalProfile(contributedDefaultProfile.extensionIdentifier, contributedDefaultProfile.id, { isSplitTerminal: true, icon: contributedDefaultProfile.icon, color: contributedDefaultProfile.color }); + await this._createContributedTerminalProfile(contributedDefaultProfile.extensionIdentifier, contributedDefaultProfile.id, { isSplitTerminal: true, icon: contributedDefaultProfile.icon, color: contributedDefaultProfile.color }); return this._terminalGroupService.instances[this._terminalGroupService.instances.length - 1]; } @@ -934,7 +934,7 @@ export class TerminalService implements ITerminalService { let instance; if ('id' in value.profile) { - await this.createContributedTerminalProfile(value.profile.extensionIdentifier, value.profile.id, { + await this._createContributedTerminalProfile(value.profile.extensionIdentifier, value.profile.id, { isSplitTerminal: !!(keyMods?.alt && activeInstance), icon: value.profile.icon }); @@ -948,7 +948,7 @@ export class TerminalService implements ITerminalService { } } - if (instance && this.configHelper.config.defaultLocation === TerminalLocation.TerminalView) { + if (instance && this.configHelper.config.defaultLocation !== TerminalLocation.Editor) { this._terminalGroupService.showPanel(true); this.setActiveInstance(instance); return instance; @@ -1009,9 +1009,9 @@ export class TerminalService implements ITerminalService { return instance?.target === TerminalLocation.Editor ? this._terminalEditorService : this._terminalGroupService; } - async createContributedTerminalProfile(extensionIdentifierentifier: string, id: string, options: ICreateContributedTerminalProfileOptions): Promise { + private async _createContributedTerminalProfile(extensionIdentifier: string, id: string, options: ICreateContributedTerminalProfileOptions): Promise { await this._extensionService.activateByEvent(`onTerminalProfile:${id}`); - const extMap = this._profileProviders.get(extensionIdentifierentifier); + const extMap = this._profileProviders.get(extensionIdentifier); const profileProvider = extMap?.get(id); if (!profileProvider) { this._notificationService.error(`No terminal profile provider registered for id "${id}"`); @@ -1023,16 +1023,15 @@ export class TerminalService implements ITerminalService { await this.activeInstance?.focusWhenReady(); } catch (e) { this._notificationService.error(e.message); - throw new Error('nope'); } } - private async _registerContributedProfile(extensionIdentifierentifier: string, id: string, title: string, options: ICreateContributedTerminalProfileOptions): Promise { + private async _registerContributedProfile(extensionIdentifier: string, id: string, title: string, options: ICreateContributedTerminalProfileOptions): Promise { const platformKey = await this._getPlatformKey(); const profilesConfig = await this._configurationService.getValue(`terminal.integrated.profiles.${platformKey}`); if (typeof profilesConfig === 'object') { const newProfile: IExtensionTerminalProfile = { - extensionIdentifier: extensionIdentifierentifier, + extensionIdentifier: extensionIdentifier, icon: options.icon, id, title: title, @@ -1108,6 +1107,15 @@ export class TerminalService implements ITerminalService { return undefined; } + private _optionsAreBasic(options?: ICreateTerminalOptions): boolean { + if (!options) { + return true; + } else if (Object.entries(options).length > 2) { + return false; + } + return Array.from(Object.keys(options)).filter(k => k !== 'target' && k !== 'isSplitTerminal').length === 0; + } + async createTerminal(options?: ICreateTerminalOptions): Promise { const config = options?.config; const shellLaunchConfig = config && 'extensionIdentifier' in config @@ -1118,19 +1126,21 @@ export class TerminalService implements ITerminalService { let contributedProfile = config && 'extensionIdentifier' in config ? config : undefined; // Get the default profile as a contributed profile if it exists - if (!contributedProfile && !options) { + if (!contributedProfile && this._optionsAreBasic(options)) { contributedProfile = await this._getContributedDefaultProfile(shellLaunchConfig); } // Launch the contributed profile if (contributedProfile) { - // TODO: createContributedTerminalProfile should be private if we want all terminal creation to go through createTerminal - await this.createContributedTerminalProfile(contributedProfile.extensionIdentifier, contributedProfile.id, { - isSplitTerminal: false, - icon: contributedProfile.icon + await this._createContributedTerminalProfile(contributedProfile.extensionIdentifier, contributedProfile.id, { + isSplitTerminal: options?.isSplitTerminal || false, + icon: contributedProfile.icon, + target: options?.target }); - // TODO: The extension terminal may be created in the editor area - return this._terminalGroupService.instances[this._terminalGroupService.instances.length - 1]; + const instanceHost = options?.target === TerminalLocation.Editor ? this._terminalEditorService : this._terminalGroupService; + const instance = instanceHost.instances[instanceHost.instances.length - 1]; + await instance.focusWhenReady(); + return instance; } if (options?.cwd) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalView.ts b/src/vs/workbench/contrib/terminal/browser/terminalView.ts index 787b65a7856..51ebfac7048 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalView.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalView.ts @@ -252,8 +252,22 @@ export class TerminalViewPane extends ViewPane { } for (const contributed of this._terminalContributionService.terminalProfiles) { - dropdownActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title.replace(/[\n\r\t]/g, ''), undefined, true, () => this._terminalService.createContributedTerminalProfile(contributed.extensionIdentifier, contributed.id, { isSplitTerminal: false }))); - submenuActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title.replace(/[\n\r\t]/g, ''), undefined, true, () => this._terminalService.createContributedTerminalProfile(contributed.extensionIdentifier, contributed.id, { isSplitTerminal: true }))); + dropdownActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title.replace(/[\n\r\t]/g, ''), undefined, true, () => this._terminalService.createTerminal({ + config: { + extensionIdentifier: contributed.extensionIdentifier, + id: contributed.id, + title: contributed.title.replace(/[\n\r\t]/g, '') + }, + isSplitTerminal: false + }))); + submenuActions.push(new Action(TerminalCommandId.NewWithProfile, contributed.title.replace(/[\n\r\t]/g, ''), undefined, true, () => this._terminalService.createTerminal({ + config: { + extensionIdentifier: contributed.extensionIdentifier, + id: contributed.id, + title: contributed.title.replace(/[\n\r\t]/g, '') + }, + isSplitTerminal: true + }))); } if (dropdownActions.length > 0) {