diff --git a/src/interactive-window/InteractiveWindowController.ts b/src/interactive-window/InteractiveWindowController.ts index f1f0cf6a5c9..bf162da9459 100644 --- a/src/interactive-window/InteractiveWindowController.ts +++ b/src/interactive-window/InteractiveWindowController.ts @@ -8,13 +8,11 @@ import { noop } from '../platform/common/utils/misc'; import { InteractiveWindowMode, Resource } from '../platform/common/types'; import { IInteractiveControllerHelper } from './types'; import { IVSCodeNotebookController } from '../notebooks/controllers/types'; -import { SystemInfoCell, getSysInfoMessage } from './systemInfoCell'; +import { SystemInfoCell, getFinishConnectMessage, getStartConnectMessage } from './systemInfoCell'; import { traceError, traceInfoIfCI, traceVerbose, traceWarning } from '../platform/logging'; import { getFilePath } from '../platform/common/platform/fs-paths'; import { SysInfoReason } from '../messageTypes'; -import { DataScience } from '../platform/common/utils/localize'; import { IDataScienceErrorHandler } from '../kernels/errors/types'; -import { getDisplayNameOrNameOfKernelConnection } from '../kernels/helpers'; export class InteractiveWindowController { public kernel: Deferred | undefined; @@ -177,10 +175,13 @@ export class InteractiveWindowController { // Clear cached kernel when the selected controller for this document changes if (e.controller.id !== this.controller?.id) { + const previouslyConnected = !!this.kernel; this.disconnect(); this.controller = e.controller.controller; this.metadata = e.controller.connection; - this.startKernel().catch(noop); + if (previouslyConnected) { + this.startKernel().catch(noop); + } } }, this @@ -188,9 +189,6 @@ export class InteractiveWindowController { } public setInfoMessageCell(message: string) { - if (!this.notebook) { - return; - } if (!this.systemInfoCell) { this.systemInfoCell = new SystemInfoCell(this.notebook, message); } else { @@ -203,15 +201,12 @@ export class InteractiveWindowController { } private setInfoMessage(metadata: KernelConnectionMetadata, reason: SysInfoReason) { - const message = getSysInfoMessage(metadata, reason); + const message = getStartConnectMessage(metadata, reason); this.setInfoMessageCell(message); } private finishSysInfoMessage(kernel: IKernel, reason: SysInfoReason) { - const displayName = getDisplayNameOrNameOfKernelConnection(kernel.kernelConnectionMetadata); - const kernelInfo = 'info' in kernel && kernel.info?.status === 'ok' ? kernel.info : undefined; - const banner = kernelInfo ? kernelInfo.banner.split('\n').join(' \n') : kernel.toString(); - const message = reason == SysInfoReason.Restart ? DataScience.restartedKernelHeader(displayName || '') : banner; + const message = getFinishConnectMessage(kernel.kernelConnectionMetadata, reason); this.systemInfoCell ?.updateMessage(message) .catch((error) => diff --git a/src/interactive-window/interactiveWindow.ts b/src/interactive-window/interactiveWindow.ts index f2e28c4ea52..715081a938c 100644 --- a/src/interactive-window/interactiveWindow.ts +++ b/src/interactive-window/interactiveWindow.ts @@ -90,8 +90,14 @@ export class InteractiveWindow implements IInteractiveWindow { public get submitters(): Uri[] { return this._submitters; } + private _notebookDocument: NotebookDocument | undefined; public get notebookDocument(): NotebookDocument | undefined { - return workspace.notebookDocuments.find((nb) => nb.uri.toString() === this.notebookUri.toString())!; + if (!this._notebookDocument) { + this._notebookDocument = workspace.notebookDocuments.find( + (nb) => nb.uri.toString() === this.notebookUri.toString() + ); + } + return this._notebookDocument; } public get kernelConnectionMetadata(): KernelConnectionMetadata | undefined { return this.controller?.metadata; @@ -169,30 +175,53 @@ export class InteractiveWindow implements IInteractiveWindow { } this.cellMatcher = new CellMatcher(this.configuration.getSettings(this.owningResource)); + if (this.notebookDocument) { this.codeGeneratorFactory.getOrCreate(this.notebookDocument); } } + public notifyConnectionReset() { + if (!this.notebookDocument) { + const onNotebookOpen = workspace.onDidOpenNotebookDocument((notebook) => { + if (notebook.uri.toString() === this.notebookUri.toString()) { + this._notebookDocument = notebook; + this.controller = this.initController(notebook); + this.internalDisposables.push(this.controller.listenForControllerSelection()); + this.controller.setInfoMessageCell(DataScience.noKernelConnected); + onNotebookOpen.dispose(); + } + }); + } else { + if (!this.controller) { + this.controller = this.initController(this.notebookDocument); + } + this.controller.setInfoMessageCell(DataScience.noKernelConnected); + } + } + + private initController(notebook: NotebookDocument) { + const controller = this.controllerFactory.create(notebook, this.errorHandler, this.kernelProvider, this._owner); + this.internalDisposables.push(controller.listenForControllerSelection()); + return controller; + } + public async ensureInitialized() { - let notebook = this.notebookDocument; - if (!notebook) { + if (!this.notebookDocument) { traceVerbose(`Showing Interactive editor to initialize codeGenerator from notebook document`); - notebook = (await this.showInteractiveEditor()).notebook; + await this.showInteractiveEditor(); + + if (!this.notebookDocument) { + throw new Error('Could not open notebook document for Interactive Window'); + } } - if (!this.codeGeneratorFactory.get(notebook)) { - this.codeGeneratorFactory.getOrCreate(notebook); + if (!this.codeGeneratorFactory.get(this.notebookDocument)) { + this.codeGeneratorFactory.getOrCreate(this.notebookDocument); } if (!this.controller) { - this.controller = this.controllerFactory.create( - notebook, - this.errorHandler, - this.kernelProvider, - this._owner - ); - this.internalDisposables.push(this.controller.listenForControllerSelection()); + this.controller = this.initController(this.notebookDocument); } if (this.controller.controller) { diff --git a/src/interactive-window/interactiveWindowProvider.ts b/src/interactive-window/interactiveWindowProvider.ts index 438ddf6790e..adc50760707 100644 --- a/src/interactive-window/interactiveWindowProvider.ts +++ b/src/interactive-window/interactiveWindowProvider.ts @@ -122,6 +122,7 @@ export class InteractiveWindowProvider implements IInteractiveWindowProvider, IE tab, Uri.parse(iw.inputBoxUriString) ); + result.notifyConnectionReset(); this._windows.push(result); sendTelemetryEvent( diff --git a/src/interactive-window/systemInfoCell.ts b/src/interactive-window/systemInfoCell.ts index 6339c63550f..4fbd1bf723f 100644 --- a/src/interactive-window/systemInfoCell.ts +++ b/src/interactive-window/systemInfoCell.ts @@ -17,15 +17,24 @@ import { SysInfoReason } from '../messageTypes'; import { DataScience } from '../platform/common/utils/localize'; import { KernelConnectionMetadata } from '../kernels/types'; -export function getSysInfoMessage(kernelMetadata: KernelConnectionMetadata, reason: SysInfoReason) { +export function getStartConnectMessage(kernelMetadata: KernelConnectionMetadata, reason: SysInfoReason) { const displayName = getDisplayNameOrNameOfKernelConnection(kernelMetadata); - return reason === SysInfoReason.Restart - ? displayName + if (displayName) { + return reason == SysInfoReason.Restart ? DataScience.restartingKernelCustomHeader(displayName) - : DataScience.restartingKernelHeader - : displayName - ? DataScience.startingNewKernelCustomHeader(displayName) - : DataScience.startingNewKernelHeader; + : DataScience.startingNewKernelCustomHeader(displayName); + } else { + return reason == SysInfoReason.Restart + ? DataScience.restartingKernelHeader + : DataScience.startingNewKernelHeader; + } +} + +export function getFinishConnectMessage(kernelMetadata: KernelConnectionMetadata, reason: SysInfoReason) { + const displayName = getDisplayNameOrNameOfKernelConnection(kernelMetadata); + return reason == SysInfoReason.Restart + ? DataScience.restartedKernelHeader(displayName || '') + : DataScience.connectedKernelHeader(displayName || ''); } export class SystemInfoCell { diff --git a/src/platform/common/utils/localize.ts b/src/platform/common/utils/localize.ts index 0f9808a89d9..330a2d6721e 100644 --- a/src/platform/common/utils/localize.ts +++ b/src/platform/common/utils/localize.ts @@ -345,10 +345,12 @@ export namespace DataScience { export const restartKernel = l10n.t('Restart Kernel'); export const reloadRequired = l10n.t('Please reload the window for new settings to take effect.'); export const restartedKernelHeader = (kernelName: string) => l10n.t('Restarted {0}', kernelName); + export const connectedKernelHeader = (kernelName: string) => l10n.t('Connected to {0}', kernelName); export const restartingKernelCustomHeader = (kernelName: string) => l10n.t('_Restarting {0}..._', kernelName); export const restartingKernelHeader = l10n.t('_Restarting kernel..._'); export const startingNewKernelHeader = l10n.t('_Connecting to kernel..._'); export const startingNewKernelCustomHeader = (kernelName: string) => l10n.t('_Connecting to {0}..._', kernelName); + export const noKernelConnected = l10n.t('No kernel connected'); export const jupyterSelectURIPrompt = l10n.t('Enter the URL of the running Jupyter server'); export const jupyterSelectURIMRUDetail = (date: Date) => l10n.t('Last Connection: {0}', date.toLocaleString()); export const jupyterSelectURINewDetail = l10n.t('Specify the URL of an existing server');