From 5c9fb46c7a19ab0eefc92f4f10eb943c5e3e598b Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Mon, 28 Oct 2024 12:56:50 -0700 Subject: [PATCH] recover notebook backed Interactive windows (#16166) * recover notebook backed IWs to be re-used * create correct type on recovery * lint --- src/interactive-window/helpers.ts | 12 ----- src/interactive-window/interactiveWindow.ts | 19 ++++---- .../interactiveWindowProvider.ts | 46 +++++++++++-------- src/interactive-window/types.ts | 20 +------- 4 files changed, 37 insertions(+), 60 deletions(-) diff --git a/src/interactive-window/helpers.ts b/src/interactive-window/helpers.ts index 82e2f06ded2..b75d82de99b 100644 --- a/src/interactive-window/helpers.ts +++ b/src/interactive-window/helpers.ts @@ -5,11 +5,9 @@ import { NotebookCell } from 'vscode'; import { dedentCode, splitLines } from '../platform/common/helpers'; import { IJupyterSettings } from '../platform/common/types'; import { appendLineFeed, removeLinesFromFrontAndBackNoConcat } from '../platform/common/utils'; -import { isUri } from '../platform/common/utils/misc'; import { uncommentMagicCommands } from './editor-integration/cellFactory'; import { CellMatcher } from './editor-integration/cellMatcher'; import { InteractiveCellMetadata } from './editor-integration/types'; -import { InteractiveTab } from './types'; export function getInteractiveCellMetadata(cell: NotebookCell): InteractiveCellMetadata | undefined { if (cell.metadata.interactive !== undefined) { @@ -38,13 +36,3 @@ export function generateInteractiveCode(code: string, settings: IJupyterSettings return dedentCode(withMagicsAndLinefeeds.join('')); } - -export function isInteractiveInputTab(tab: unknown): tab is InteractiveTab { - let interactiveTab = tab as InteractiveTab; - return ( - interactiveTab && - interactiveTab.input && - isUri(interactiveTab.input.uri) && - isUri(interactiveTab.input.inputBoxUri) - ); -} diff --git a/src/interactive-window/interactiveWindow.ts b/src/interactive-window/interactiveWindow.ts index e201db71ca8..0a16901bfef 100644 --- a/src/interactive-window/interactiveWindow.ts +++ b/src/interactive-window/interactiveWindow.ts @@ -39,13 +39,8 @@ import { INotebookExporter } from '../kernels/jupyter/types'; import { ExportFormat } from '../notebooks/export/types'; import { generateCellsFromNotebookDocument } from './editor-integration/cellFactory'; import { CellMatcher } from './editor-integration/cellMatcher'; -import { - IInteractiveWindow, - IInteractiveWindowDebugger, - IInteractiveWindowDebuggingManager, - InteractiveTab -} from './types'; -import { generateInteractiveCode, isInteractiveInputTab } from './helpers'; +import { IInteractiveWindow, IInteractiveWindowDebugger, IInteractiveWindowDebuggingManager } from './types'; +import { generateInteractiveCode } from './helpers'; import { getInteractiveCellMetadata } from './helpers'; import { getFilePath } from '../platform/common/platform/fs-paths'; import { @@ -120,7 +115,7 @@ export class InteractiveWindow implements IInteractiveWindow { private readonly serviceContainer: IServiceContainer, private _owner: Resource, private readonly controllerFactory: InteractiveControllerFactory, - notebookEditorOrTab: NotebookEditor | InteractiveTab, + notebookEditorOrTabInput: NotebookEditor | TabInputNotebook | TabInputInteractiveWindow, public readonly inputUri: Uri ) { this.fs = this.serviceContainer.get(IFileSystem); @@ -135,9 +130,11 @@ export class InteractiveWindow implements IInteractiveWindow { this.debuggingManager = this.serviceContainer.get( IInteractiveWindowDebuggingManager ); - this.notebookUri = isInteractiveInputTab(notebookEditorOrTab) - ? notebookEditorOrTab.input.uri - : notebookEditorOrTab.notebook.uri; + this.notebookUri = + notebookEditorOrTabInput instanceof TabInputInteractiveWindow || + notebookEditorOrTabInput instanceof TabInputNotebook + ? notebookEditorOrTabInput.uri + : notebookEditorOrTabInput.notebook.uri; // Set our owner and first submitter if (this._owner) { diff --git a/src/interactive-window/interactiveWindowProvider.ts b/src/interactive-window/interactiveWindowProvider.ts index 63bace765e8..b4ef8e1479c 100644 --- a/src/interactive-window/interactiveWindowProvider.ts +++ b/src/interactive-window/interactiveWindowProvider.ts @@ -11,6 +11,8 @@ import { NotebookControllerAffinity, NotebookDocument, NotebookEditor, + TabInputInteractiveWindow, + TabInputNotebook, Uri, ViewColumn, commands, @@ -48,14 +50,12 @@ import { IInteractiveWindow, IInteractiveWindowCache, IInteractiveWindowProvider, - INativeInteractiveWindow, - InteractiveTab + INativeInteractiveWindow } from './types'; import { getInteractiveWindowTitle } from './identity'; import { createDeferred } from '../platform/common/utils/async'; import { getDisplayPath } from '../platform/common/platform/fs-paths'; import { IVSCodeNotebookController } from '../notebooks/controllers/types'; -import { isInteractiveInputTab } from './helpers'; import { sendTelemetryEvent } from '../telemetry'; import { InteractiveControllerFactory } from './InteractiveWindowController'; import { NotebookInteractiveWindow } from './notebookInteractiveWindow'; @@ -116,11 +116,12 @@ export class InteractiveWindowProvider implements IInteractiveWindowProvider, IE private restoreWindows() { // VS Code controls if interactive windows are restored. - const interactiveWindowMapping = new Map(); + const interactiveWindowMapping = new Map(); window.tabGroups.all.forEach((group) => { group.tabs.forEach((tab) => { - if (isInteractiveInputTab(tab) && tab.input.uri) { - interactiveWindowMapping.set(tab.input.uri.toString(), tab); + const input = tab.input; + if (input instanceof TabInputInteractiveWindow || input instanceof TabInputNotebook) { + interactiveWindowMapping.set(input.uri.toString(), input); } }); }); @@ -130,21 +131,30 @@ export class InteractiveWindowProvider implements IInteractiveWindowProvider, IE return; } - const tab = interactiveWindowMapping.get(iw.uriString); + const tabInput = interactiveWindowMapping.get(iw.uriString); - if (!tab) { + if (!tabInput) { return; } - const mode = this.configService.getSettings(tab.input.uri).interactiveWindowMode; - - const result = new InteractiveWindow( - this.serviceContainer, - Uri.parse(iw.owner), - new InteractiveControllerFactory(this.controllerHelper, mode), - tab, - Uri.parse(iw.inputBoxUriString) - ); + const mode = this.configService.getSettings(tabInput.uri).interactiveWindowMode; + + const result = + tabInput instanceof TabInputInteractiveWindow + ? new InteractiveWindow( + this.serviceContainer, + Uri.parse(iw.owner), + new InteractiveControllerFactory(this.controllerHelper, mode), + tabInput, + Uri.parse(iw.inputBoxUriString) + ) + : new NotebookInteractiveWindow( + this.serviceContainer, + Uri.parse(iw.owner), + new InteractiveControllerFactory(this.controllerHelper, mode), + tabInput, + Uri.parse(iw.inputBoxUriString) + ); result.notifyConnectionReset().catch(noop); @@ -315,7 +325,7 @@ export class InteractiveWindowProvider implements IInteractiveWindowProvider, IE const editor = await window.showNotebookDocument(notebookDocument, { // currently, to set the controller, we need to focus the editor - preserveFocus: !!controller ? true : preserveFocus, + preserveFocus: !!controller ? false : preserveFocus, viewColumn, asRepl: title }); diff --git a/src/interactive-window/types.ts b/src/interactive-window/types.ts index ba647ed52f3..437310d13d6 100644 --- a/src/interactive-window/types.ts +++ b/src/interactive-window/types.ts @@ -1,16 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { - Disposable, - Event, - NotebookCell, - NotebookController, - NotebookDocument, - NotebookEditor, - Tab, - Uri -} from 'vscode'; +import { Disposable, Event, NotebookCell, NotebookController, NotebookDocument, NotebookEditor, Uri } from 'vscode'; import { IDebuggingManager } from '../notebooks/debugger/debuggingTypes'; import { IKernel, KernelConnectionMetadata } from '../kernels/types'; import { Resource, InteractiveWindowMode } from '../platform/common/types'; @@ -117,15 +108,6 @@ export interface IInteractiveWindowCache { inputBoxUriString: string; } -export interface TabInputInteractiveWindow { - readonly uri: Uri; - readonly inputBoxUri: Uri; -} - -export interface InteractiveTab extends Tab { - readonly input: TabInputInteractiveWindow; -} - export const IInteractiveWindowDebuggingManager = Symbol('IInteractiveWindowDebuggingManager'); export interface IInteractiveWindowDebuggingManager extends IDebuggingManager { start(notebook: NotebookDocument, cell: NotebookCell): Promise;