From 44d973419b971586c628fe7885609c9064fd1cd0 Mon Sep 17 00:00:00 2001 From: anthonykim1 Date: Sun, 5 Oct 2025 23:17:27 -0700 Subject: [PATCH 1/2] Just use profile for wsl --- .../terminal/shells/bash/bashStartup.ts | 4 +-- .../terminal/shells/common/shellUtils.ts | 11 +++++-- .../terminal/shells/fish/fishStartup.ts | 4 +-- .../terminal/shells/pwsh/pwshStartup.ts | 3 +- src/features/terminal/terminalManager.ts | 29 ++++++++++--------- 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/features/terminal/shells/bash/bashStartup.ts b/src/features/terminal/shells/bash/bashStartup.ts index e62ad1af..bbe98c85 100644 --- a/src/features/terminal/shells/bash/bashStartup.ts +++ b/src/features/terminal/shells/bash/bashStartup.ts @@ -5,7 +5,7 @@ import which from 'which'; import { traceError, traceInfo, traceVerbose } from '../../../../common/logging'; import { ShellConstants } from '../../../common/shellConstants'; import { hasStartupCode, insertStartupCode, removeStartupCode } from '../common/editUtils'; -import { shellIntegrationForActiveTerminal } from '../common/shellUtils'; +import { isWsl, shellIntegrationForActiveTerminal } from '../common/shellUtils'; import { ShellScriptEditState, ShellSetupState, ShellStartupScriptProvider } from '../startupProvider'; import { BASH_ENV_KEY, BASH_OLD_ENV_KEY, BASH_SCRIPT_VERSION, ZSH_ENV_KEY, ZSH_OLD_ENV_KEY } from './bashConstants'; @@ -68,7 +68,7 @@ async function isStartupSetup(profile: string, key: string): Promise { - if (shellIntegrationForActiveTerminal(name, profile)) { + if (shellIntegrationForActiveTerminal(name, profile) && !isWsl()) { removeStartup(profile, key); return true; } diff --git a/src/features/terminal/shells/common/shellUtils.ts b/src/features/terminal/shells/common/shellUtils.ts index 95e6f71a..20d310b5 100644 --- a/src/features/terminal/shells/common/shellUtils.ts +++ b/src/features/terminal/shells/common/shellUtils.ts @@ -103,10 +103,17 @@ export function shellIntegrationForActiveTerminal(name: string, profile?: string if (hasShellIntegration) { traceInfo( - `SHELL: Shell integration is available on your active terminal. Python activate scripts will be evaluated at shell integration level. - Skipping modification of ${name} profile at: ${profile}`, + `SHELL: Shell integration is available on your active terminal, with name ${name} and profile ${profile}. Python activate scripts will be evaluated at shell integration level, except in WSL.` ); return true; } return false; } + +export function isWsl(): boolean { + // WSL sets these environment variables + return !!(process.env.WSL_DISTRO_NAME || + process.env.WSL_INTEROP || + process.env.WSLENV); +} + diff --git a/src/features/terminal/shells/fish/fishStartup.ts b/src/features/terminal/shells/fish/fishStartup.ts index 37ac130b..395829e9 100644 --- a/src/features/terminal/shells/fish/fishStartup.ts +++ b/src/features/terminal/shells/fish/fishStartup.ts @@ -6,7 +6,7 @@ import which from 'which'; import { traceError, traceInfo, traceVerbose } from '../../../../common/logging'; import { ShellConstants } from '../../../common/shellConstants'; import { hasStartupCode, insertStartupCode, removeStartupCode } from '../common/editUtils'; -import { shellIntegrationForActiveTerminal } from '../common/shellUtils'; +import { isWsl, shellIntegrationForActiveTerminal } from '../common/shellUtils'; import { ShellScriptEditState, ShellSetupState, ShellStartupScriptProvider } from '../startupProvider'; import { FISH_ENV_KEY, FISH_OLD_ENV_KEY, FISH_SCRIPT_VERSION } from './fishConstants'; @@ -58,7 +58,7 @@ async function isStartupSetup(profilePath: string, key: string): Promise { try { - if (shellIntegrationForActiveTerminal('fish', profilePath)) { + if (shellIntegrationForActiveTerminal('fish', profilePath) && !isWsl()) { removeFishStartup(profilePath, key); return true; } diff --git a/src/features/terminal/shells/pwsh/pwshStartup.ts b/src/features/terminal/shells/pwsh/pwshStartup.ts index 6e0cf31e..3758dbb7 100644 --- a/src/features/terminal/shells/pwsh/pwshStartup.ts +++ b/src/features/terminal/shells/pwsh/pwshStartup.ts @@ -13,6 +13,7 @@ import { ShellConstants } from '../../../common/shellConstants'; import { hasStartupCode, insertStartupCode, removeStartupCode } from '../common/editUtils'; import { extractProfilePath, + isWsl, PROFILE_TAG_END, PROFILE_TAG_START, shellIntegrationForActiveTerminal, @@ -145,7 +146,7 @@ async function isPowerShellStartupSetup(shell: string, profile: string): Promise } async function setupPowerShellStartup(shell: string, profile: string): Promise { - if (shellIntegrationForActiveTerminal(shell, profile)) { + if (shellIntegrationForActiveTerminal(shell, profile) && !isWsl()) { removePowerShellStartup(shell, profile, POWERSHELL_OLD_ENV_KEY); removePowerShellStartup(shell, profile, POWERSHELL_ENV_KEY); return true; diff --git a/src/features/terminal/terminalManager.ts b/src/features/terminal/terminalManager.ts index dcba585c..9dcf0a8e 100644 --- a/src/features/terminal/terminalManager.ts +++ b/src/features/terminal/terminalManager.ts @@ -16,7 +16,7 @@ import { getConfiguration, onDidChangeConfiguration } from '../../common/workspa import { isActivatableEnvironment } from '../common/activation'; import { identifyTerminalShell } from '../common/shellDetector'; import { getPythonApi } from '../pythonApi'; -import { shellIntegrationForActiveTerminal } from './shells/common/shellUtils'; +import { isWsl, shellIntegrationForActiveTerminal } from './shells/common/shellUtils'; import { ShellEnvsProvider, ShellSetupState, ShellStartupScriptProvider } from './shells/startupProvider'; import { handleSettingUpShellProfile } from './shellStartupSetupHandlers'; import { @@ -143,41 +143,42 @@ export class TerminalManagerImpl implements TerminalManager { private async handleSetupCheck(shellType: string | Set): Promise { const shellTypes = typeof shellType === 'string' ? new Set([shellType]) : shellType; const providers = this.startupScriptProviders.filter((p) => shellTypes.has(p.shellType)); - if (providers.length > 0) { + if (providers.length > 0) { const shellsToSetup: ShellStartupScriptProvider[] = []; await Promise.all( providers.map(async (p) => { const state = await p.isSetup(); + const currentSetup = (state === ShellSetupState.Setup); + // Check if we already processed this shell and the state hasn't changed if (this.shellSetup.has(p.shellType)) { - // This ensures modified scripts are detected even after initial setup const cachedSetup = this.shellSetup.get(p.shellType); - if ((state === ShellSetupState.Setup) !== cachedSetup) { - traceVerbose(`Shell profile for ${p.shellType} state changed, updating cache.`); - // State changed - clear cache and re-evaluate - this.shellSetup.delete(p.shellType); - } else { - traceVerbose(`Shell profile for ${p.shellType} already checked.`); + if (currentSetup === cachedSetup) { + traceVerbose(`Shell profile for ${p.shellType} already checked, state unchanged.`); return; } + traceVerbose(`Shell profile for ${p.shellType} state changed from ${cachedSetup} to ${currentSetup}, re-evaluating.`); } traceVerbose(`Checking shell profile for ${p.shellType}.`); if (state === ShellSetupState.NotSetup) { - if (shellIntegrationForActiveTerminal(p.name)) { + traceVerbose(`WSL detected: ${isWsl()}, Shell integration available: ${shellIntegrationForActiveTerminal(p.name)}`); + + if (shellIntegrationForActiveTerminal(p.name) && !isWsl()) { + // Shell integration available and NOT in WSL - skip setup await p.teardownScripts(); this.shellSetup.set(p.shellType, true); traceVerbose( - `Shell integration available for ${p.shellType}, skipping prompt, and profile modification.`, + `Shell integration available for ${p.shellType} (not WSL), skipping prompt, and profile modification.`, ); } else { - // No shell integration, mark for setup + // WSL (regardless of integration) OR no shell integration - needs setup this.shellSetup.set(p.shellType, false); shellsToSetup.push(p); traceVerbose( - `Shell integration is NOT avaoiable. Shell profile for ${p.shellType} is not setup.`, + `Shell integration is NOT available. Shell profile for ${p.shellType} is not setup.`, ); } } else if (state === ShellSetupState.Setup) { - if (shellIntegrationForActiveTerminal(p.name)) { + if (shellIntegrationForActiveTerminal(p.name) && !isWsl()) { await p.teardownScripts(); traceVerbose( `Shell integration available for ${p.shellType}, removed profile script in favor of shell integration.`, From c9023accff7eb563b5d1f5e12a3a78ea8f3cfcd7 Mon Sep 17 00:00:00 2001 From: anthonykim1 Date: Sun, 5 Oct 2025 23:54:48 -0700 Subject: [PATCH 2/2] Make sure to clean after shell startup changes when `off` --- src/features/terminal/terminalManager.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/features/terminal/terminalManager.ts b/src/features/terminal/terminalManager.ts index 9dcf0a8e..81768dbd 100644 --- a/src/features/terminal/terminalManager.ts +++ b/src/features/terminal/terminalManager.ts @@ -129,7 +129,9 @@ export class TerminalManagerImpl implements TerminalManager { await this.handleSetupCheck(shells); } } else { - traceVerbose(`Auto activation type changed to ${actType}`); + traceVerbose(`Auto activation type changed to ${actType}, we are cleaning up shell startup setup`); + // Teardown scripts when switching away from shell startup activation + await Promise.all(this.startupScriptProviders.map((p) => p.teardownScripts())); this.shellSetup.clear(); } }