diff --git a/src/features/terminal/shellStartupSetupHandlers.ts b/src/features/terminal/shellStartupSetupHandlers.ts index b9da1e8d..0a818ee2 100644 --- a/src/features/terminal/shellStartupSetupHandlers.ts +++ b/src/features/terminal/shellStartupSetupHandlers.ts @@ -55,6 +55,10 @@ export async function handleSettingUpShellProfile( }); providers.forEach((provider) => callback(provider, false)); } + } else { + traceInfo(`User declined shell profile setup for ${shells}, switching to command activation`); + await Promise.all(providers.map((provider) => provider.teardownScripts())); + await setAutoActivationType(ACT_TYPE_COMMAND); } } diff --git a/src/features/terminal/shells/common/shellUtils.ts b/src/features/terminal/shells/common/shellUtils.ts index 0d74e31e..1264c188 100644 --- a/src/features/terminal/shells/common/shellUtils.ts +++ b/src/features/terminal/shells/common/shellUtils.ts @@ -161,3 +161,23 @@ export async function getShellIntegrationEnabledCache(): Promise { await persistentState.set(SHELL_INTEGRATION_STATE_KEY, shellIntegrationEnabled); return shellIntegrationEnabled; } + +// Shells that support shell integration way of environment activation. +// CMD is not listed here, but we still want to support activation via profile modification. +export const shellIntegrationSupportedShells = [ + ShellConstants.PWSH, + ShellConstants.BASH, + ShellConstants.GITBASH, + ShellConstants.FISH, + ShellConstants.ZSH, +]; + +/** + * Determines whether profile-based activation should be used instead of shell integration. + * Profile activation is preferred when: + * - Running in WSL + * - The shell type doesn't support shell integration (e.g., cmd) + */ +export function shouldUseProfileActivation(shellType: string): boolean { + return isWsl() || !shellIntegrationSupportedShells.includes(shellType); +} diff --git a/src/features/terminal/terminalManager.ts b/src/features/terminal/terminalManager.ts index d73e498a..394cc8db 100644 --- a/src/features/terminal/terminalManager.ts +++ b/src/features/terminal/terminalManager.ts @@ -16,7 +16,12 @@ import { getConfiguration, onDidChangeConfiguration } from '../../common/workspa import { isActivatableEnvironment } from '../common/activation'; import { identifyTerminalShell } from '../common/shellDetector'; import { getPythonApi } from '../pythonApi'; -import { getShellIntegrationEnabledCache, isWsl, shellIntegrationForActiveTerminal } from './shells/common/shellUtils'; +import { + getShellIntegrationEnabledCache, + isWsl, + shellIntegrationForActiveTerminal, + shouldUseProfileActivation, +} from './shells/common/shellUtils'; import { ShellEnvsProvider, ShellSetupState, ShellStartupScriptProvider } from './shells/startupProvider'; import { handleSettingUpShellProfile } from './shellStartupSetupHandlers'; import { @@ -166,19 +171,20 @@ export class TerminalManagerImpl implements TerminalManager { await Promise.all( providers.map(async (p) => { const state = await p.isSetup(); - const shellIntegrationEnabled = await getShellIntegrationEnabledCache(); + const shellIntegrationEnabledSetting = await getShellIntegrationEnabledCache(); + const shellIntegrationActiveTerminal = await shellIntegrationForActiveTerminal(p.name); + const shellIntegrationLikelyAvailable = + shellIntegrationEnabledSetting || shellIntegrationActiveTerminal; traceVerbose(`Checking shell profile for ${p.shellType}, with state: ${state}`); + if (state === ShellSetupState.NotSetup) { traceVerbose( - `WSL detected: ${isWsl()}, Shell integration available from setting, or active terminal: ${shellIntegrationEnabled}, or ${await shellIntegrationForActiveTerminal( + `WSL detected: ${isWsl()}, Shell integration available from setting, or active terminal: ${shellIntegrationEnabledSetting}, or ${await shellIntegrationForActiveTerminal( p.name, )}`, ); - if ( - (shellIntegrationEnabled || (await shellIntegrationForActiveTerminal(p.name))) && - !isWsl() - ) { + if (shellIntegrationLikelyAvailable && !shouldUseProfileActivation(p.shellType)) { // Shell integration available and NOT in WSL - skip setup await p.teardownScripts(); this.shellSetup.set(p.shellType, true); @@ -194,10 +200,7 @@ export class TerminalManagerImpl implements TerminalManager { ); } } else if (state === ShellSetupState.Setup) { - if ( - (shellIntegrationEnabled || (await shellIntegrationForActiveTerminal(p.name))) && - !isWsl() - ) { + if (shellIntegrationLikelyAvailable && !shouldUseProfileActivation(p.shellType)) { await p.teardownScripts(); traceVerbose( `Shell integration available for ${p.shellType}, removed profile script in favor of shell integration.`,