diff --git a/extensions/positron-python/src/client/positron/discoverer.ts b/extensions/positron-python/src/client/positron/discoverer.ts index 95c9c7d8b5a0..c21a3fad3f1c 100644 --- a/extensions/positron-python/src/client/positron/discoverer.ts +++ b/extensions/positron-python/src/client/positron/discoverer.ts @@ -48,6 +48,7 @@ export async function* pythonRuntimeDiscoverer( traceInfo(`pythonRuntimeDiscoverer: recommended interpreter: ${recommendedInterpreter?.path}`); // Discover Python interpreters + await interpreterService.triggerRefresh().ignoreErrors(); let interpreters = interpreterService.getInterpreters(); traceInfo(`pythonRuntimeDiscoverer: discovered ${interpreters.length} Python interpreters`); diff --git a/src/vs/workbench/contrib/languageRuntime/browser/languageRuntimeActions.ts b/src/vs/workbench/contrib/languageRuntime/browser/languageRuntimeActions.ts index fb83540dee63..9c1c6e8f3e15 100644 --- a/src/vs/workbench/contrib/languageRuntime/browser/languageRuntimeActions.ts +++ b/src/vs/workbench/contrib/languageRuntime/browser/languageRuntimeActions.ts @@ -44,8 +44,8 @@ export const LANGUAGE_RUNTIME_RESTART_ACTIVE_SESSION_ID = 'workbench.action.lang export const LANGUAGE_RUNTIME_RENAME_SESSION_ID = 'workbench.action.language.runtime.renameSession'; export const LANGUAGE_RUNTIME_RENAME_ACTIVE_SESSION_ID = 'workbench.action.language.runtime.renameActiveSession'; export const LANGUAGE_RUNTIME_DUPLICATE_ACTIVE_SESSION_ID = 'workbench.action.language.runtime.duplicateActiveSession'; - export const LANGUAGE_RUNTIME_SELECT_RUNTIME_ID = 'workbench.action.languageRuntime.selectRuntime'; +export const LANGUAGE_RUNTIME_DISCOVER_RUNTIMES_ID = 'workbench.action.language.runtime.discoverAllRuntimes'; /** * Helper function that askses the user to select a language from the list of registered language @@ -967,6 +967,29 @@ export function registerLanguageRuntimeActions() { } }); + registerAction2(class extends Action2 { + /** + * Constructor. + */ + constructor() { + super({ + id: LANGUAGE_RUNTIME_DISCOVER_RUNTIMES_ID, + title: nls.localize2('workbench.action.language.runtime.discoverAllRuntimes', "Discover All Interpreters"), + f1: true, + category + }); + } + + async run(accessor: ServicesAccessor) { + // Access service. + const runtimeStartupService = accessor.get(IRuntimeStartupService); + + // Kick off discovery. + runtimeStartupService.rediscoverAllRuntimes(); + } + }); + + /** * Arguments passed to the Execute Code actions. */ diff --git a/src/vs/workbench/services/positronHistory/test/common/executionHistoryService.test.ts b/src/vs/workbench/services/positronHistory/test/common/executionHistoryService.test.ts index bcc64a806d06..0e7bf5dfaf90 100644 --- a/src/vs/workbench/services/positronHistory/test/common/executionHistoryService.test.ts +++ b/src/vs/workbench/services/positronHistory/test/common/executionHistoryService.test.ts @@ -319,6 +319,10 @@ class TestRuntimeStartupService implements IRuntimeStartupService { // No-op in test implementation } + public async rediscoverAllRuntimes() { + // No-op in test implementation + } + registerRuntimeManager(_manager: IRuntimeManager): IDisposable { return Disposable.None; } diff --git a/src/vs/workbench/services/runtimeStartup/common/runtimeStartup.ts b/src/vs/workbench/services/runtimeStartup/common/runtimeStartup.ts index 7e9d995c58e3..57f5e56e25be 100644 --- a/src/vs/workbench/services/runtimeStartup/common/runtimeStartup.ts +++ b/src/vs/workbench/services/runtimeStartup/common/runtimeStartup.ts @@ -637,6 +637,52 @@ export class RuntimeStartupService extends Disposable implements IRuntimeStartup }; } + /** + * Kicks off a refresh of runtime discovery, after initial discovery. + */ + public async rediscoverAllRuntimes(): Promise { + + // If we haven't completed discovery once already, don't do anything. + if (this._startupPhase !== RuntimeStartupPhase.Complete) { + this._logService.warn('[Runtime startup] Runtime discovery refresh called before initial discovery is complete.'); + return; + } + + // Set up event to notify when runtimes are added. + const oldRuntimes = this._languageRuntimeService.registeredRuntimes; + this._register( + this._languageRuntimeService.onDidChangeRuntimeStartupPhase( + (phase) => { + if (phase === RuntimeStartupPhase.Complete) { + const newRuntimes = this._languageRuntimeService.registeredRuntimes; + const addedRuntimes = newRuntimes.filter(newRuntime => { + return !oldRuntimes.some(oldRuntime => { + return oldRuntime.runtimeId === newRuntime.runtimeId; + }); + }); + + // If any runtimes were added, show a notification. + if (addedRuntimes.length > 0) { + this._notificationService.info(nls.localize('positron.runtimeStartupService.runtimesAddedMessage', + "Found {0} new interpreter{1}: {2}.", + addedRuntimes.length, + addedRuntimes.length > 1 ? 's' : '', + addedRuntimes.map(runtime => { return runtime.runtimeName; }).join(', '))); + } + } + } + ) + ); + + this._logService.debug('[Runtime startup] Refreshing runtime discovery.'); + this._discoveryCompleteByExtHostId.forEach((_, extHostId, m) => { + m.set(extHostId, false); + }); + + this.discoverAllRuntimes(); + + } + /** * Runs as an event handler when the active runtime changes. * @@ -693,7 +739,7 @@ export class RuntimeStartupService extends Disposable implements IRuntimeStartup } /** - * Activates all of the extensions that provides language runtimes, then + * Activates all of the extensions that provide language runtimes, then * enters the discovery phase, in which each extension is asked to supply * its language runtime metadata. */ @@ -739,7 +785,7 @@ export class RuntimeStartupService extends Disposable implements IRuntimeStartup // language runtime providers. this.setStartupPhase(RuntimeStartupPhase.Discovering); - // Ask each extension to provide its language runtime metadata. + // Ask each extension host to provide its language runtime metadata. for (const manager of this._runtimeManagers) { manager.discoverAllRuntimes(disabledLanguages); } diff --git a/src/vs/workbench/services/runtimeStartup/common/runtimeStartupService.ts b/src/vs/workbench/services/runtimeStartup/common/runtimeStartupService.ts index f4421b0ed1d4..ef18383a565d 100644 --- a/src/vs/workbench/services/runtimeStartup/common/runtimeStartupService.ts +++ b/src/vs/workbench/services/runtimeStartup/common/runtimeStartupService.ts @@ -124,6 +124,11 @@ export interface IRuntimeStartupService { */ completeDiscovery(id: number): void; + /** + * Kick off a user-driven refresh of runtime discovery, after the initial discovery. + */ + rediscoverAllRuntimes(): Promise; + /** * Get the sessions that were (or will be) restored into this window. */ diff --git a/src/vs/workbench/services/runtimeStartup/test/common/testRuntimeStartupService.ts b/src/vs/workbench/services/runtimeStartup/test/common/testRuntimeStartupService.ts index 8184b536a829..ae2872e61f68 100644 --- a/src/vs/workbench/services/runtimeStartup/test/common/testRuntimeStartupService.ts +++ b/src/vs/workbench/services/runtimeStartup/test/common/testRuntimeStartupService.ts @@ -110,6 +110,13 @@ export class TestRuntimeStartupService implements IRuntimeStartupService { // No-op in test implementation } + /** + * {@inheritDoc} + */ + public async rediscoverAllRuntimes() { + // No-op in test implementation + } + /** * {@inheritDoc} */