diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 858a6486cdc..2377fc9bbd0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -46,7 +46,7 @@ import { TypeAheadAddon } from 'vs/workbench/contrib/terminal/browser/terminalTy import { BrowserFeatures } from 'vs/base/browser/canIUse'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable'; -import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType, TerminalSettingId, TitleEventSource, TerminalIcon, TerminalSettingPrefix } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType, TerminalSettingId, TitleEventSource, TerminalIcon, TerminalSettingPrefix, ITerminalProfileObject } from 'vs/platform/terminal/common/terminal'; import { IProductService } from 'vs/platform/product/common/productService'; import { formatMessageForTerminal } from 'vs/workbench/contrib/terminal/common/terminalStrings'; import { AutoOpenBarrier } from 'vs/base/common/async'; @@ -373,14 +373,22 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { const shell = this._configurationService.getValue(TerminalSettingPrefix.Shell + platform); const shellArgs = this._configurationService.getValue(TerminalSettingPrefix.ShellArgs + platform); const profile = await this._terminalProfileResolverService.createProfileFromShellAndShellArgs(shell, shellArgs); - if (profile) { - this._configurationService.updateValue(TerminalSettingPrefix.DefaultProfile + platform, profile.profileName); - this._configurationService.updateValue(TerminalSettingPrefix.Shell + platform, undefined); - this._configurationService.updateValue(TerminalSettingPrefix.ShellArgs + platform, undefined); - this._logService.trace(`migrated from shell/shellArgs, ${shell} ${shellArgs} to profile ${JSON.stringify(profile)}`); + if (typeof profile === 'string') { + await this._configurationService.updateValue(TerminalSettingPrefix.DefaultProfile + platform, profile); + this._logService.trace(`migrated from shell/shellArgs, using existing profile ${profile}`); } else { - this._logService.trace('migration from shell/shellArgs to profile did not occur bc created profile was an exact match for existing one', shell, shellArgs); + const profiles = this._configurationService.inspect<{ [key: string]: ITerminalProfileObject }>(TerminalSettingPrefix.Profiles + platform).userValue || {}; + const profileConfig: ITerminalProfileObject = { path: profile.path }; + if (profile.args) { + profileConfig.args = profile.args; + } + profiles[profile.profileName] = profileConfig; + await this._configurationService.updateValue(TerminalSettingPrefix.Profiles + platform, profiles); + await this._configurationService.updateValue(TerminalSettingPrefix.DefaultProfile + platform, profile.profileName); + this._logService.trace(`migrated from shell/shellArgs, ${shell} ${shellArgs} to profile ${JSON.stringify(profile)}`); } + await this._configurationService.updateValue(TerminalSettingPrefix.Shell + platform, undefined); + await this._configurationService.updateValue(TerminalSettingPrefix.ShellArgs + platform, undefined); } } as IPromptChoice, ], diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts index d569aabfae4..d139954dc87 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProfileResolverService.ts @@ -21,6 +21,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA import { debounce } from 'vs/base/common/decorators'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { URI, UriComponents } from 'vs/base/common/uri'; +import { equals } from 'vs/base/common/arrays'; export interface IProfileContextProvider { getDefaultSystemShell: (remoteAuthority: string | undefined, os: OperatingSystem) => Promise; @@ -392,12 +393,21 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro return false; } - async createProfileFromShellAndShellArgs(shell?: unknown, shellArgs?: unknown): Promise { - const detectedProfile = this._terminalService.availableProfiles?.find(p => p.path === shell); + async createProfileFromShellAndShellArgs(shell?: unknown, shellArgs?: unknown): Promise { + const detectedProfile = this._terminalService.availableProfiles?.find(p => { + if (p.path !== shell) { + return false; + } + if (p.args === undefined || typeof p.args === 'string') { + return p.args === shellArgs; + } + return p.path === shell && equals(p.args, (shellArgs || []) as string[]); + }); const fallbackProfile = (await this.getDefaultProfile({ remoteAuthority: this._remoteAgentService.getConnection()?.remoteAuthority, os: this._primaryBackendOs! })); + fallbackProfile.profileName = `${fallbackProfile.path} (migrated)`; const profile = detectedProfile || fallbackProfile; const args = this._isValidShellArgs(shellArgs, this._primaryBackendOs!) ? shellArgs : profile.args; const createdProfile = { @@ -407,7 +417,7 @@ export abstract class BaseTerminalProfileResolverService implements ITerminalPro isDefault: true }; if (detectedProfile && detectedProfile.profileName === createdProfile.profileName && detectedProfile.path === createdProfile.path && this._argsMatch(detectedProfile.args, createdProfile.args)) { - return undefined; + return detectedProfile.profileName; } return createdProfile; } diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 9c76b60ebf3..fb62f0be0a7 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -112,7 +112,7 @@ export interface ITerminalProfileResolverService { getDefaultShell(options: IShellLaunchConfigResolveOptions): Promise; getDefaultShellArgs(options: IShellLaunchConfigResolveOptions): Promise; getEnvironment(remoteAuthority: string | undefined): Promise; - createProfileFromShellAndShellArgs(shell?: unknown, shellArgs?: unknown): Promise; + createProfileFromShellAndShellArgs(shell?: unknown, shellArgs?: unknown): Promise; } export interface IShellLaunchConfigResolveOptions {