@@ -18,6 +18,7 @@ import {
1818 EnvManagerTreeItem ,
1919 EnvTreeItem ,
2020 EnvTreeItemKind ,
21+ getEnvironmentParentDirName ,
2122 NoPythonEnvTreeItem ,
2223 PackageTreeItem ,
2324 PythonEnvTreeItem ,
@@ -28,6 +29,53 @@ const COPIED_STATE = 'copied';
2829const SELECTED_STATE = 'selected' ;
2930const ENV_STATE_KEYS = [ COPIED_STATE , SELECTED_STATE ] ;
3031
32+ /**
33+ * Extracts the base name from a display name by removing version info.
34+ * @example getBaseName('.venv (3.12)') returns '.venv'
35+ * @example getBaseName('myenv (3.14.1)') returns 'myenv'
36+ */
37+ function getBaseName ( displayName : string ) : string {
38+ return displayName . replace ( / \s * \( [ 0 - 9 . ] + \) \s * $ / , '' ) . trim ( ) ;
39+ }
40+
41+ /**
42+ * Computes disambiguation suffixes for environments with similar base names.
43+ *
44+ * When multiple environments share the same base name (ignoring version numbers),
45+ * this function returns a map from environment ID to the parent folder name,
46+ * which can be displayed to help users distinguish between them.
47+ *
48+ * @example Two environments '.venv (3.12)' in folders 'alice' and 'bob' would
49+ * return suffixes 'alice' and 'bob' respectively.
50+ *
51+ * @param envs List of environments to analyze
52+ * @returns Map from environment ID to disambiguation suffix (parent folder name)
53+ */
54+ function computeDisambiguationSuffixes ( envs : PythonEnvironment [ ] ) : Map < string , string > {
55+ const suffixes = new Map < string , string > ( ) ;
56+
57+ // Group environments by their base name (ignoring version)
58+ const baseNameToEnvs = new Map < string , PythonEnvironment [ ] > ( ) ;
59+ for ( const env of envs ) {
60+ const displayName = env . displayName ?? env . name ;
61+ const baseName = getBaseName ( displayName ) ;
62+ const existing = baseNameToEnvs . get ( baseName ) ?? [ ] ;
63+ existing . push ( env ) ;
64+ baseNameToEnvs . set ( baseName , existing ) ;
65+ }
66+
67+ // For base names with multiple environments, compute suffixes
68+ for ( const [ , similarEnvs ] of baseNameToEnvs ) {
69+ if ( similarEnvs . length > 1 ) {
70+ for ( const env of similarEnvs ) {
71+ suffixes . set ( env . envId . id , getEnvironmentParentDirName ( env ) ) ;
72+ }
73+ }
74+ }
75+
76+ return suffixes ;
77+ }
78+
3179export class EnvManagerView implements TreeDataProvider < EnvTreeItem > , Disposable {
3280 private treeView : TreeView < EnvTreeItem > ;
3381 private treeDataChanged : EventEmitter < EnvTreeItem | EnvTreeItem [ ] | null | undefined > = new EventEmitter <
@@ -126,8 +174,16 @@ export class EnvManagerView implements TreeDataProvider<EnvTreeItem>, Disposable
126174 const manager = ( element as EnvManagerTreeItem ) . manager ;
127175 const views : EnvTreeItem [ ] = [ ] ;
128176 const envs = await manager . getEnvironments ( 'all' ) ;
129- envs . filter ( ( e ) => ! e . group ) . forEach ( ( env ) => {
130- const view = new PythonEnvTreeItem ( env , element as EnvManagerTreeItem , this . selected . get ( env . envId . id ) ) ;
177+ const nonGroupedEnvs = envs . filter ( ( e ) => ! e . group ) ;
178+ const disambiguationSuffixes = computeDisambiguationSuffixes ( nonGroupedEnvs ) ;
179+ nonGroupedEnvs . forEach ( ( env ) => {
180+ const suffix = disambiguationSuffixes . get ( env . envId . id ) ;
181+ const view = new PythonEnvTreeItem (
182+ env ,
183+ element as EnvManagerTreeItem ,
184+ this . selected . get ( env . envId . id ) ,
185+ suffix ,
186+ ) ;
131187 views . push ( view ) ;
132188 this . revealMap . set ( env . envId . id , view ) ;
133189 } ) ;
@@ -172,8 +228,10 @@ export class EnvManagerView implements TreeDataProvider<EnvTreeItem>, Disposable
172228 return false ;
173229 } ) ;
174230
231+ const groupDisambiguationSuffixes = computeDisambiguationSuffixes ( grouped ) ;
175232 grouped . forEach ( ( env ) => {
176- const view = new PythonEnvTreeItem ( env , groupItem , this . selected . get ( env . envId . id ) ) ;
233+ const suffix = groupDisambiguationSuffixes . get ( env . envId . id ) ;
234+ const view = new PythonEnvTreeItem ( env , groupItem , this . selected . get ( env . envId . id ) , suffix ) ;
177235 views . push ( view ) ;
178236 this . revealMap . set ( env . envId . id , view ) ;
179237 } ) ;
0 commit comments