Skip to content

Commit 1c28421

Browse files
committed
fix: ensure interpreter change event is raised when using environments extension
1 parent b84fce2 commit 1c28421

File tree

3 files changed

+65
-7
lines changed

3 files changed

+65
-7
lines changed

src/client/envExt/api.internal.ts

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
import { Terminal, Uri } from 'vscode';
4+
import { EventEmitter, Terminal, Uri, Disposable, ConfigurationTarget } from 'vscode';
55
import { getExtension } from '../common/vscodeApis/extensionsApi';
66
import {
77
GetEnvironmentScope,
@@ -10,8 +10,10 @@ import {
1010
PythonEnvironmentApi,
1111
PythonProcess,
1212
RefreshEnvironmentsScope,
13+
DidChangeEnvironmentEventArgs,
1314
} from './types';
1415
import { executeCommand } from '../common/vscodeApis/commandApis';
16+
import { IInterpreterPathService } from '../common/types';
1517

1618
export const ENVS_EXTENSION_ID = 'ms-python.vscode-python-envs';
1719

@@ -24,6 +26,17 @@ export function useEnvExtension(): boolean {
2426
return _useExt;
2527
}
2628

29+
const onDidChangeEnvironmentEnvExtEmitter: EventEmitter<DidChangeEnvironmentEventArgs> = new EventEmitter<
30+
DidChangeEnvironmentEventArgs
31+
>();
32+
export function onDidChangeEnvironmentEnvExt(
33+
listener: (e: DidChangeEnvironmentEventArgs) => unknown,
34+
thisArgs?: unknown,
35+
disposables?: Disposable[],
36+
): Disposable {
37+
return onDidChangeEnvironmentEnvExtEmitter.event(listener, thisArgs, disposables);
38+
}
39+
2740
let _extApi: PythonEnvironmentApi | undefined;
2841
export async function getEnvExtApi(): Promise<PythonEnvironmentApi> {
2942
if (_extApi) {
@@ -33,14 +46,15 @@ export async function getEnvExtApi(): Promise<PythonEnvironmentApi> {
3346
if (!extension) {
3447
throw new Error('Python Environments extension not found.');
3548
}
36-
if (extension?.isActive) {
37-
_extApi = extension.exports as PythonEnvironmentApi;
38-
return _extApi;
49+
if (!extension?.isActive) {
50+
await extension.activate();
3951
}
4052

41-
await extension.activate();
42-
4353
_extApi = extension.exports as PythonEnvironmentApi;
54+
_extApi.onDidChangeEnvironment((e) => {
55+
onDidChangeEnvironmentEnvExtEmitter.fire(e);
56+
});
57+
4458
return _extApi;
4559
}
4660

@@ -106,3 +120,32 @@ export async function clearCache(): Promise<void> {
106120
await executeCommand('python-envs.clearCache');
107121
}
108122
}
123+
124+
export function registerEnvExtFeatures(
125+
disposables: Disposable[],
126+
interpreterPathService: IInterpreterPathService,
127+
): void {
128+
if (useEnvExtension()) {
129+
disposables.push(
130+
onDidChangeEnvironmentEnvExt(async (e: DidChangeEnvironmentEventArgs) => {
131+
const previousPath = interpreterPathService.get(e.uri);
132+
133+
if (previousPath !== e.new?.environmentPath.fsPath) {
134+
if (e.uri) {
135+
await interpreterPathService.update(
136+
e.uri,
137+
ConfigurationTarget.WorkspaceFolder,
138+
e.new?.environmentPath.fsPath,
139+
);
140+
} else {
141+
await interpreterPathService.update(
142+
undefined,
143+
ConfigurationTarget.Global,
144+
e.new?.environmentPath.fsPath,
145+
);
146+
}
147+
}
148+
}),
149+
);
150+
}
151+
}

src/client/environmentApi.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { PythonEnvInfo, PythonEnvKind, PythonEnvType } from './pythonEnvironment
1111
import { getEnvPath } from './pythonEnvironments/base/info/env';
1212
import { IDiscoveryAPI, ProgressReportStage } from './pythonEnvironments/base/locator';
1313
import { IPythonExecutionFactory } from './common/process/types';
14-
import { traceError, traceVerbose } from './logging';
14+
import { traceError, traceInfo, traceVerbose } from './logging';
1515
import { isParentPath, normCasePath } from './common/platform/fs-paths';
1616
import { sendTelemetryEvent } from './telemetry';
1717
import { EventName } from './telemetry/constants';
@@ -42,7 +42,13 @@ type ActiveEnvironmentChangeEvent = {
4242
};
4343

4444
const onDidActiveInterpreterChangedEvent = new EventEmitter<ActiveEnvironmentPathChangeEvent>();
45+
const previousEnvMap = new Map<string, string>();
4546
export function reportActiveInterpreterChanged(e: ActiveEnvironmentChangeEvent): void {
47+
const oldPath = previousEnvMap.get(e.resource?.uri.fsPath ?? '');
48+
if (oldPath === e.path) {
49+
return;
50+
}
51+
previousEnvMap.set(e.resource?.uri.fsPath ?? '', e.path);
4652
onDidActiveInterpreterChangedEvent.fire({ id: getEnvID(e.path), path: e.path, resource: e.resource });
4753
reportActiveInterpreterChangedDeprecated({ path: e.path, resource: e.resource?.uri });
4854
}
@@ -172,6 +178,13 @@ export function buildEnvironmentApi(
172178
}
173179

174180
disposables.push(
181+
onDidActiveInterpreterChangedEvent.event((e) => {
182+
let scope = 'global';
183+
if (e.resource) {
184+
scope = e.resource instanceof Uri ? e.resource.fsPath : e.resource.uri.fsPath;
185+
}
186+
traceInfo(`Active interpreter [${scope}]: `, e.path);
187+
}),
175188
discoveryApi.onProgress((e) => {
176189
if (e.stage === ProgressReportStage.discoveryFinished) {
177190
knownCache = initKnownCache();

src/client/extensionActivation.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import { registerTriggerForTerminalREPL } from './terminals/codeExecution/termin
5656
import { registerPythonStartup } from './terminals/pythonStartup';
5757
import { registerPixiFeatures } from './pythonEnvironments/common/environmentManagers/pixi';
5858
import { registerCustomTerminalLinkProvider } from './terminals/pythonStartupLinkProvider';
59+
import { registerEnvExtFeatures } from './envExt/api.internal';
5960

6061
export async function activateComponents(
6162
// `ext` is passed to any extra activation funcs.
@@ -101,6 +102,7 @@ export function activateFeatures(ext: ExtensionState, _components: Components):
101102
const interpreterService: IInterpreterService = ext.legacyIOC.serviceContainer.get<IInterpreterService>(
102103
IInterpreterService,
103104
);
105+
registerEnvExtFeatures(ext.disposables, interpreterPathService);
104106
const pathUtils = ext.legacyIOC.serviceContainer.get<IPathUtils>(IPathUtils);
105107
registerPixiFeatures(ext.disposables);
106108
registerAllCreateEnvironmentFeatures(

0 commit comments

Comments
 (0)