Skip to content

Commit f979910

Browse files
anthonykim1eleanorjboyd
authored andcommitted
Fix wsl not activating properly. (microsoft#896)
Resolves: microsoft#865
1 parent 4f4488e commit f979910

File tree

5 files changed

+33
-22
lines changed

5 files changed

+33
-22
lines changed

src/features/terminal/shells/bash/bashStartup.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import which from 'which';
55
import { traceError, traceInfo, traceVerbose } from '../../../../common/logging';
66
import { ShellConstants } from '../../../common/shellConstants';
77
import { hasStartupCode, insertStartupCode, removeStartupCode } from '../common/editUtils';
8-
import { shellIntegrationForActiveTerminal } from '../common/shellUtils';
8+
import { isWsl, shellIntegrationForActiveTerminal } from '../common/shellUtils';
99
import { ShellScriptEditState, ShellSetupState, ShellStartupScriptProvider } from '../startupProvider';
1010
import { BASH_ENV_KEY, BASH_OLD_ENV_KEY, BASH_SCRIPT_VERSION, ZSH_ENV_KEY, ZSH_OLD_ENV_KEY } from './bashConstants';
1111

@@ -68,7 +68,7 @@ async function isStartupSetup(profile: string, key: string): Promise<ShellSetupS
6868
return ShellSetupState.NotSetup;
6969
}
7070
async function setupStartup(profile: string, key: string, name: string): Promise<boolean> {
71-
if (shellIntegrationForActiveTerminal(name, profile)) {
71+
if (shellIntegrationForActiveTerminal(name, profile) && !isWsl()) {
7272
removeStartup(profile, key);
7373
return true;
7474
}

src/features/terminal/shells/common/shellUtils.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,17 @@ export function shellIntegrationForActiveTerminal(name: string, profile?: string
103103

104104
if (hasShellIntegration) {
105105
traceInfo(
106-
`SHELL: Shell integration is available on your active terminal. Python activate scripts will be evaluated at shell integration level.
107-
Skipping modification of ${name} profile at: ${profile}`,
106+
`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.`
108107
);
109108
return true;
110109
}
111110
return false;
112111
}
112+
113+
export function isWsl(): boolean {
114+
// WSL sets these environment variables
115+
return !!(process.env.WSL_DISTRO_NAME ||
116+
process.env.WSL_INTEROP ||
117+
process.env.WSLENV);
118+
}
119+

src/features/terminal/shells/fish/fishStartup.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import which from 'which';
66
import { traceError, traceInfo, traceVerbose } from '../../../../common/logging';
77
import { ShellConstants } from '../../../common/shellConstants';
88
import { hasStartupCode, insertStartupCode, removeStartupCode } from '../common/editUtils';
9-
import { shellIntegrationForActiveTerminal } from '../common/shellUtils';
9+
import { isWsl, shellIntegrationForActiveTerminal } from '../common/shellUtils';
1010
import { ShellScriptEditState, ShellSetupState, ShellStartupScriptProvider } from '../startupProvider';
1111
import { FISH_ENV_KEY, FISH_OLD_ENV_KEY, FISH_SCRIPT_VERSION } from './fishConstants';
1212

@@ -58,7 +58,7 @@ async function isStartupSetup(profilePath: string, key: string): Promise<boolean
5858

5959
async function setupStartup(profilePath: string, key: string): Promise<boolean> {
6060
try {
61-
if (shellIntegrationForActiveTerminal('fish', profilePath)) {
61+
if (shellIntegrationForActiveTerminal('fish', profilePath) && !isWsl()) {
6262
removeFishStartup(profilePath, key);
6363
return true;
6464
}

src/features/terminal/shells/pwsh/pwshStartup.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { ShellConstants } from '../../../common/shellConstants';
1313
import { hasStartupCode, insertStartupCode, removeStartupCode } from '../common/editUtils';
1414
import {
1515
extractProfilePath,
16+
isWsl,
1617
PROFILE_TAG_END,
1718
PROFILE_TAG_START,
1819
shellIntegrationForActiveTerminal,
@@ -145,7 +146,7 @@ async function isPowerShellStartupSetup(shell: string, profile: string): Promise
145146
}
146147

147148
async function setupPowerShellStartup(shell: string, profile: string): Promise<boolean> {
148-
if (shellIntegrationForActiveTerminal(shell, profile)) {
149+
if (shellIntegrationForActiveTerminal(shell, profile) && !isWsl()) {
149150
removePowerShellStartup(shell, profile, POWERSHELL_OLD_ENV_KEY);
150151
removePowerShellStartup(shell, profile, POWERSHELL_ENV_KEY);
151152
return true;

src/features/terminal/terminalManager.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { getConfiguration, onDidChangeConfiguration } from '../../common/workspa
1616
import { isActivatableEnvironment } from '../common/activation';
1717
import { identifyTerminalShell } from '../common/shellDetector';
1818
import { getPythonApi } from '../pythonApi';
19-
import { shellIntegrationForActiveTerminal } from './shells/common/shellUtils';
19+
import { isWsl, shellIntegrationForActiveTerminal } from './shells/common/shellUtils';
2020
import { ShellEnvsProvider, ShellSetupState, ShellStartupScriptProvider } from './shells/startupProvider';
2121
import { handleSettingUpShellProfile } from './shellStartupSetupHandlers';
2222
import {
@@ -129,7 +129,9 @@ export class TerminalManagerImpl implements TerminalManager {
129129
await this.handleSetupCheck(shells);
130130
}
131131
} else {
132-
traceVerbose(`Auto activation type changed to ${actType}`);
132+
traceVerbose(`Auto activation type changed to ${actType}, we are cleaning up shell startup setup`);
133+
// Teardown scripts when switching away from shell startup activation
134+
await Promise.all(this.startupScriptProviders.map((p) => p.teardownScripts()));
133135
this.shellSetup.clear();
134136
}
135137
}
@@ -143,41 +145,42 @@ export class TerminalManagerImpl implements TerminalManager {
143145
private async handleSetupCheck(shellType: string | Set<string>): Promise<void> {
144146
const shellTypes = typeof shellType === 'string' ? new Set([shellType]) : shellType;
145147
const providers = this.startupScriptProviders.filter((p) => shellTypes.has(p.shellType));
146-
if (providers.length > 0) {
148+
if (providers.length > 0) {
147149
const shellsToSetup: ShellStartupScriptProvider[] = [];
148150
await Promise.all(
149151
providers.map(async (p) => {
150152
const state = await p.isSetup();
153+
const currentSetup = (state === ShellSetupState.Setup);
154+
// Check if we already processed this shell and the state hasn't changed
151155
if (this.shellSetup.has(p.shellType)) {
152-
// This ensures modified scripts are detected even after initial setup
153156
const cachedSetup = this.shellSetup.get(p.shellType);
154-
if ((state === ShellSetupState.Setup) !== cachedSetup) {
155-
traceVerbose(`Shell profile for ${p.shellType} state changed, updating cache.`);
156-
// State changed - clear cache and re-evaluate
157-
this.shellSetup.delete(p.shellType);
158-
} else {
159-
traceVerbose(`Shell profile for ${p.shellType} already checked.`);
157+
if (currentSetup === cachedSetup) {
158+
traceVerbose(`Shell profile for ${p.shellType} already checked, state unchanged.`);
160159
return;
161160
}
161+
traceVerbose(`Shell profile for ${p.shellType} state changed from ${cachedSetup} to ${currentSetup}, re-evaluating.`);
162162
}
163163
traceVerbose(`Checking shell profile for ${p.shellType}.`);
164164
if (state === ShellSetupState.NotSetup) {
165-
if (shellIntegrationForActiveTerminal(p.name)) {
165+
traceVerbose(`WSL detected: ${isWsl()}, Shell integration available: ${shellIntegrationForActiveTerminal(p.name)}`);
166+
167+
if (shellIntegrationForActiveTerminal(p.name) && !isWsl()) {
168+
// Shell integration available and NOT in WSL - skip setup
166169
await p.teardownScripts();
167170
this.shellSetup.set(p.shellType, true);
168171
traceVerbose(
169-
`Shell integration available for ${p.shellType}, skipping prompt, and profile modification.`,
172+
`Shell integration available for ${p.shellType} (not WSL), skipping prompt, and profile modification.`,
170173
);
171174
} else {
172-
// No shell integration, mark for setup
175+
// WSL (regardless of integration) OR no shell integration - needs setup
173176
this.shellSetup.set(p.shellType, false);
174177
shellsToSetup.push(p);
175178
traceVerbose(
176-
`Shell integration is NOT avaoiable. Shell profile for ${p.shellType} is not setup.`,
179+
`Shell integration is NOT available. Shell profile for ${p.shellType} is not setup.`,
177180
);
178181
}
179182
} else if (state === ShellSetupState.Setup) {
180-
if (shellIntegrationForActiveTerminal(p.name)) {
183+
if (shellIntegrationForActiveTerminal(p.name) && !isWsl()) {
181184
await p.teardownScripts();
182185
traceVerbose(
183186
`Shell integration available for ${p.shellType}, removed profile script in favor of shell integration.`,

0 commit comments

Comments
 (0)