1- import { Disposable , EventEmitter , Uri , workspace , ConfigurationTarget , Event } from 'vscode' ;
1+ import { ConfigurationTarget , Disposable , Event , EventEmitter , Uri , workspace } from 'vscode' ;
22import {
33 DidChangeEnvironmentEventArgs ,
44 DidChangeEnvironmentsEventArgs ,
@@ -10,13 +10,14 @@ import {
1010 PythonProject ,
1111 SetEnvironmentScope ,
1212} from '../api' ;
13- import { traceError , traceVerbose } from '../common/logging' ;
1413import {
15- EditAllManagerSettings ,
16- getDefaultEnvManagerSetting ,
17- getDefaultPkgManagerSetting ,
18- setAllManagerSettings ,
19- } from './settings/settingHelpers' ;
14+ EnvironmentManagerAlreadyRegisteredError ,
15+ PackageManagerAlreadyRegisteredError ,
16+ } from '../common/errors/AlreadyRegisteredError' ;
17+ import { traceError , traceVerbose } from '../common/logging' ;
18+ import { EventNames } from '../common/telemetry/constants' ;
19+ import { sendTelemetryEvent } from '../common/telemetry/sender' ;
20+ import { getCallingExtension } from '../common/utils/frameUtils' ;
2021import {
2122 DidChangeEnvironmentManagerEventArgs ,
2223 DidChangePackageManagerEventArgs ,
@@ -30,13 +31,12 @@ import {
3031 PythonProjectManager ,
3132 PythonProjectSettings ,
3233} from '../internal.api' ;
33- import { getCallingExtension } from '../common/utils/frameUtils' ;
3434import {
35- EnvironmentManagerAlreadyRegisteredError ,
36- PackageManagerAlreadyRegisteredError ,
37- } from '../common/errors/AlreadyRegisteredError' ;
38- import { sendTelemetryEvent } from '../common/telemetry/sender' ;
39- import { EventNames } from '../common/telemetry/constants ' ;
35+ EditAllManagerSettings ,
36+ getDefaultEnvManagerSetting ,
37+ getDefaultPkgManagerSetting ,
38+ setAllManagerSettings ,
39+ } from './settings/settingHelpers ' ;
4040
4141function generateId ( name : string ) : string {
4242 const newName = name . toLowerCase ( ) . replace ( / [ ^ a - z A - Z 0 - 9 - _ ] / g, '_' ) ;
@@ -165,6 +165,10 @@ export class PythonEnvironmentManagers implements EnvironmentManagers {
165165 this . _onDidChangePackages . dispose ( ) ;
166166 }
167167
168+ /**
169+ * Returns the environment manager for the given context.
170+ * Uses the default from settings if context is undefined or a Uri; otherwise uses the id or environment's managerId passed in via context.
171+ */
168172 public getEnvironmentManager ( context : EnvironmentManagerScope ) : InternalEnvironmentManager | undefined {
169173 if ( this . _environmentManagers . size === 0 ) {
170174 traceError ( 'No environment managers registered' ) ;
@@ -256,6 +260,10 @@ export class PythonEnvironmentManagers implements EnvironmentManagers {
256260 }
257261 }
258262
263+ /**
264+ * Sets the environment for a single scope, scope of undefined checks 'global'.
265+ * If given an array of scopes, delegates to setEnvironments for batch setting.
266+ */
259267 public async setEnvironment ( scope : SetEnvironmentScope , environment ?: PythonEnvironment ) : Promise < void > {
260268 if ( Array . isArray ( scope ) ) {
261269 return this . setEnvironments ( scope , environment ) ;
@@ -299,6 +307,10 @@ export class PythonEnvironmentManagers implements EnvironmentManagers {
299307 }
300308 }
301309
310+ /**
311+ * Sets the given environment for the specified project URIs or globally.
312+ * If a list of URIs is provided, sets the environment for each project; if 'global', sets it as the global environment.
313+ */
302314 public async setEnvironments ( scope : Uri [ ] | string , environment ?: PythonEnvironment ) : Promise < void > {
303315 if ( environment ) {
304316 const manager = this . managers . find ( ( m ) => m . id === environment . envId . managerId ) ;
@@ -403,6 +415,44 @@ export class PythonEnvironmentManagers implements EnvironmentManagers {
403415 }
404416 }
405417
418+ /**
419+ * Sets the environment for the given scopes, but only if the scope is not already set (i.e., is global or undefined).
420+ * Existing environments for a scope are not overwritten.
421+ *
422+ */
423+ public async setEnvironmentsIfUnset ( scope : Uri [ ] | string , environment ?: PythonEnvironment ) : Promise < void > {
424+ if ( ! environment ) {
425+ return ;
426+ }
427+ if ( typeof scope === 'string' && scope === 'global' ) {
428+ const current = await this . getEnvironment ( undefined ) ;
429+ if ( ! current ) {
430+ await this . setEnvironments ( 'global' , environment ) ;
431+ }
432+ } else if ( Array . isArray ( scope ) ) {
433+ const urisToSet : Uri [ ] = [ ] ;
434+ for ( const uri of scope ) {
435+ const current = await this . getEnvironment ( uri ) ;
436+ if ( ! current || current . envId . managerId === 'ms-python.python:system' ) {
437+ // If the current environment is not set or is the system environment, set the new environment.
438+ urisToSet . push ( uri ) ;
439+ }
440+ }
441+ if ( urisToSet . length > 0 ) {
442+ await this . setEnvironments ( urisToSet , environment ) ;
443+ }
444+ }
445+ }
446+
447+ /**
448+ * Gets the current Python environment for the given scope URI or undefined for 'global'.
449+ *
450+ * This method queries the appropriate environment manager for the latest environment for the scope.
451+ * It also updates the internal cache and fires an event if the environment has changed since last check.
452+ *
453+ * @param scope The scope to get the environment.
454+ * @returns The current PythonEnvironment for the scope, or undefined if none is set.
455+ */
406456 async getEnvironment ( scope : GetEnvironmentScope ) : Promise < PythonEnvironment | undefined > {
407457 const manager = this . getEnvironmentManager ( scope ) ;
408458 if ( ! manager ) {
0 commit comments