@@ -14,8 +14,8 @@ import { getConfiguration, onDidChangeConfiguration } from '../../common/workspa
1414import { isActivatableEnvironment } from '../common/activation' ;
1515import { identifyTerminalShell } from '../common/shellDetector' ;
1616import { getPythonApi } from '../pythonApi' ;
17- import { ShellEnvsProvider , ShellStartupScriptProvider } from './shells/startupProvider' ;
18- import { handleSettingUpShellProfile } from './shellStartupSetupHandlers' ;
17+ import { ShellEnvsProvider , ShellSetupState , ShellStartupScriptProvider } from './shells/startupProvider' ;
18+ import { filterProviders , handleSettingUpShellProfile } from './shellStartupSetupHandlers' ;
1919import {
2020 DidChangeTerminalActivationStateEvent ,
2121 TerminalActivation ,
@@ -113,45 +113,77 @@ export class TerminalManagerImpl implements TerminalManager {
113113 . filter ( ( t ) => t !== 'unknown' ) ,
114114 ) ;
115115 if ( shells . size > 0 ) {
116- await handleSettingUpShellProfile ( shells , this . startupScriptProviders , ( p , v ) =>
117- this . shellSetup . set ( p . shellType , v ) ,
118- ) ;
116+ await this . handleSetupCheck ( shells ) ;
119117 }
120118 }
121119 }
122120 } ) ,
123121 ) ;
124122 }
125123
126- private async getEffectiveActivationType ( shellType : string ) : Promise < AutoActivationType > {
127- const provider = this . startupScriptProviders . find ( ( p ) => p . shellType === shellType ) ;
128- if ( provider ) {
129- traceVerbose ( `Shell startup is supported for ${ shellType } , using shell startup activation` ) ;
130- const isSetup = this . shellSetup . get ( shellType ) ;
131- if ( isSetup === true ) {
132- traceVerbose ( `Shell profile for ${ shellType } is already setup.` ) ;
133- return 'shellStartup' ;
134- } else if ( isSetup === false ) {
135- traceVerbose ( `Shell profile for ${ shellType } is not set up, using command fallback.` ) ;
136- return 'command' ;
137- }
124+ private async handleSetupCheck ( shellType : string | Set < string > ) : Promise < void > {
125+ const shellTypes = typeof shellType === 'string' ? new Set ( [ shellType ] ) : shellType ;
126+ const providers = filterProviders ( shellTypes , this . startupScriptProviders ) ;
127+ if ( providers . length > 0 ) {
128+ const shellsToSetup : ShellStartupScriptProvider [ ] = [ ] ;
129+ await Promise . all (
130+ providers . map ( async ( p ) => {
131+ if ( this . shellSetup . has ( p . shellType ) ) {
132+ traceVerbose ( `Shell profile for ${ p . shellType } already checked.` ) ;
133+ return ;
134+ }
135+ traceVerbose ( `Checking shell profile for ${ p . shellType } .` ) ;
136+ const state = await p . isSetup ( ) ;
137+ if ( state === ShellSetupState . NotSetup ) {
138+ this . shellSetup . set ( p . shellType , false ) ;
139+ shellsToSetup . push ( p ) ;
140+ traceVerbose ( `Shell profile for ${ p . shellType } is not setup.` ) ;
141+ } else if ( state === ShellSetupState . Setup ) {
142+ this . shellSetup . set ( p . shellType , true ) ;
143+ traceVerbose ( `Shell profile for ${ p . shellType } is setup.` ) ;
144+ } else if ( state === ShellSetupState . NotInstalled ) {
145+ this . shellSetup . set ( p . shellType , false ) ;
146+ traceVerbose ( `Shell profile for ${ p . shellType } is not installed.` ) ;
147+ }
148+ } ) ,
149+ ) ;
138150
139- if ( await provider . isSetup ( ) ) {
140- this . shellSetup . set ( shellType , true ) ;
141- traceVerbose ( `Shell profile for ${ shellType } is setup successfully.` ) ;
142- return 'shellStartup' ;
151+ if ( shellsToSetup . length === 0 ) {
152+ traceVerbose ( `No shell profiles to setup for ${ Array . from ( shellTypes ) . join ( ', ' ) } ` ) ;
153+ return ;
143154 }
144155
145- this . shellSetup . set ( shellType , false ) ;
146- traceVerbose ( `Shell profile for ${ shellType } is not setup, falling back to command activation` ) ;
147-
148156 setImmediate ( async ( ) => {
149- await handleSettingUpShellProfile ( new Set ( [ shellType ] ) , this . startupScriptProviders , ( p , v ) =>
150- this . shellSetup . set ( p . shellType , v ) ,
151- ) ;
157+ await handleSettingUpShellProfile ( shellsToSetup , ( p , v ) => this . shellSetup . set ( p . shellType , v ) ) ;
152158 } ) ;
159+ }
160+ }
161+
162+ private getShellActivationType ( shellType : string ) : AutoActivationType | undefined {
163+ let isSetup = this . shellSetup . get ( shellType ) ;
164+ if ( isSetup === true ) {
165+ traceVerbose ( `Shell profile for ${ shellType } is already setup.` ) ;
166+ return 'shellStartup' ;
167+ } else if ( isSetup === false ) {
168+ traceVerbose ( `Shell profile for ${ shellType } is not set up, using command fallback.` ) ;
153169 return 'command' ;
154170 }
171+ }
172+
173+ private async getEffectiveActivationType ( shellType : string ) : Promise < AutoActivationType > {
174+ const providers = filterProviders ( new Set ( [ shellType ] ) , this . startupScriptProviders ) ;
175+ if ( providers . length > 0 ) {
176+ traceVerbose ( `Shell startup is supported for ${ shellType } , using shell startup activation` ) ;
177+ let isSetup = this . getShellActivationType ( shellType ) ;
178+ if ( isSetup !== undefined ) {
179+ return isSetup ;
180+ }
181+
182+ await this . handleSetupCheck ( shellType ) ;
183+
184+ // Check again after the setup check.
185+ return this . getShellActivationType ( shellType ) ?? 'command' ;
186+ }
155187 traceInfo ( `Shell startup not supported for ${ shellType } , using command activation as fallback` ) ;
156188 return 'command' ;
157189 }
@@ -322,9 +354,7 @@ export class TerminalManagerImpl implements TerminalManager {
322354 . filter ( ( t ) => t !== 'unknown' ) ,
323355 ) ;
324356 if ( shells . size > 0 ) {
325- await handleSettingUpShellProfile ( shells , this . startupScriptProviders , ( p , v ) =>
326- this . shellSetup . set ( p . shellType , v ) ,
327- ) ;
357+ await this . handleSetupCheck ( shells ) ;
328358 }
329359 }
330360 }
0 commit comments