diff --git a/src/vs/workbench/api/browser/mainThreadInteractive.ts b/src/vs/workbench/api/browser/mainThreadInteractive.ts index 51d2a90a410..33676ceed31 100644 --- a/src/vs/workbench/api/browser/mainThreadInteractive.ts +++ b/src/vs/workbench/api/browser/mainThreadInteractive.ts @@ -21,7 +21,11 @@ export class MainThreadInteractive implements MainThreadInteractiveShape { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostInteractive); this._disposables.add(interactiveDocumentService.onWillAddInteractiveDocument((e) => { - this._proxy.$acceptInputDocument(e.inputUri, '\n', 'plaintext', e.notebookUri); + this._proxy.$willAddInteractiveDocument(e.inputUri, '\n', 'plaintext', e.notebookUri); + })); + + this._disposables.add(interactiveDocumentService.onWillAddInteractiveDocument((e) => { + this._proxy.$willRemoveInteractiveDocument(e.inputUri, e.notebookUri); })); } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 7d6886457e1..96f10273325 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -2038,7 +2038,8 @@ export interface ExtHostNotebookKernelsShape { } export interface ExtHostInteractiveShape { - $acceptInputDocument(uri: UriComponents, eol: string, modeId: string, notebookUri: UriComponents): void; + $willAddInteractiveDocument(uri: UriComponents, eol: string, modeId: string, notebookUri: UriComponents): void; + $willRemoveInteractiveDocument(uri: UriComponents, notebookUri: UriComponents): void; } export interface ExtHostStorageShape { diff --git a/src/vs/workbench/api/common/extHostInteractive.ts b/src/vs/workbench/api/common/extHostInteractive.ts index 0cc338e927c..cba91a9fa9c 100644 --- a/src/vs/workbench/api/common/extHostInteractive.ts +++ b/src/vs/workbench/api/common/extHostInteractive.ts @@ -16,7 +16,7 @@ export class ExtHostInteractive implements ExtHostInteractiveShape { ) { } - $acceptInputDocument(uri: UriComponents, eol: string, modeId: string, notebookUri: UriComponents) { + $willAddInteractiveDocument(uri: UriComponents, eol: string, modeId: string, notebookUri: UriComponents) { this._textDocumentsAndEditors.acceptDocumentsAndEditorsDelta({ addedDocuments: [{ EOL: eol, @@ -29,4 +29,10 @@ export class ExtHostInteractive implements ExtHostInteractiveShape { }] }); } + + $willRemoveInteractiveDocument(uri: UriComponents, notebookUri: UriComponents) { + this._textDocumentsAndEditors.acceptDocumentsAndEditorsDelta({ + removedDocuments: [uri] + }); + } } diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveDocumentService.ts b/src/vs/workbench/contrib/interactive/browser/interactiveDocumentService.ts index e96c8734bba..25fe881455b 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveDocumentService.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveDocumentService.ts @@ -13,13 +13,17 @@ export const IInteractiveDocumentService = createDecorator; + onWillRemoveInteractiveDocument: Event<{ notebookUri: URI; inputUri: URI; }>; willCreateInteractiveDocument(notebookUri: URI, inputUri: URI, languageId: string): void; + willRemoveInteractiveDocument(notebookUri: URI, inputUri: URI): void; } export class InteractiveDocumentService extends Disposable { declare readonly _serviceBrand: undefined; private readonly _onWillAddInteractiveDocument = this._register(new Emitter<{ notebookUri: URI; inputUri: URI; languageId: string; }>()); onWillAddInteractiveDocument = this._onWillAddInteractiveDocument.event; + private readonly _onWillRemoveInteractiveDocument = this._register(new Emitter<{ notebookUri: URI; inputUri: URI; }>()); + onWillRemoveInteractiveDocument = this._onWillRemoveInteractiveDocument.event; constructor() { super(); @@ -33,4 +37,8 @@ export class InteractiveDocumentService extends Disposable { }); } + willRemoveInteractiveDocument(notebookUri: URI, inputUri: URI) { + + } + } diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts index 6d7f4f3911c..9d7f20b4bb5 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts @@ -173,9 +173,16 @@ export class InteractiveEditor extends EditorPane { if (!editorModel) { this.#interactiveDocumentService.willCreateInteractiveDocument(input.resource!, input.inputResource, this.#notebookWidget.value?.activeKernel?.supportedLanguages[0] ?? 'plaintext'); editorModel = this.#modelService.createModel('', null, input.inputResource, false); + + // willCreateInteractiveDocument refs the input model, then we should de-ref it on close. + this.#widgetDisposableStore.add({ + dispose: () => { + this.#interactiveDocumentService.willRemoveInteractiveDocument(input.resource!, input.inputResource); + editorModel?.dispose(); + } + }); } - this.#widgetDisposableStore.add(editorModel); this.#codeEditorWidget.setModel(editorModel); this.#widgetDisposableStore.add(this.#codeEditorWidget.onDidContentSizeChange(e => { if (!e.contentHeightChanged) {