diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts index fa92d91e8a21d..75b1b6fb4e0b1 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/notebook.kernel.test.ts @@ -85,15 +85,11 @@ async function assertKernel(kernel: Kernel, notebook: vscode.NotebookDocument): assert.ok(kernel.associatedNotebooks.has(notebook.uri.toString())); } -const apiTestContentProvider: vscode.NotebookContentProvider = { - openNotebook: async (resource: vscode.Uri): Promise => { - if (/.*empty\-.*\.vsctestnb$/.test(resource.path)) { - return { - metadata: {}, - cells: [] - }; - } - +const apiTestSerializer: vscode.NotebookSerializer = { + serializeNotebook(_data, _token) { + return new Uint8Array(); + }, + deserializeNotebook(_content, _token) { const dto: vscode.NotebookData = { metadata: { custom: { testMetadata: false } }, cells: [ @@ -143,8 +139,8 @@ const apiTestContentProvider: vscode.NotebookContentProvider = { suiteDisposables.length = 0; }); - suiteSetup(function () { - suiteDisposables.push(vscode.workspace.registerNotebookContentProvider('notebookCoreTest', apiTestContentProvider)); + suiteSetup(() => { + suiteDisposables.push(vscode.workspace.registerNotebookSerializer('notebookCoreTest', apiTestSerializer)); }); let defaultKernel: Kernel; diff --git a/src/vs/workbench/api/browser/mainThreadNotebook.ts b/src/vs/workbench/api/browser/mainThreadNotebook.ts index 51986a3ad3ce7..3b877b3dd485a 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebook.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebook.ts @@ -7,18 +7,18 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter } from 'vs/base/common/event'; import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { StopWatch } from 'vs/base/common/stopwatch'; +import { assertType } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { ILogService } from 'vs/platform/log/common/log'; import { NotebookDto } from 'vs/workbench/api/browser/mainThreadNotebookDto'; -import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService'; -import { INotebookCellStatusBarItemProvider, INotebookContributionData, NotebookData as NotebookData, NotebookExtensionDescription, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; -import { INotebookContentProvider, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService'; +import { INotebookCellStatusBarItemProvider, INotebookContributionData, NotebookData, NotebookExtensionDescription, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService'; +import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers'; import { SerializableObjectWithBuffers } from 'vs/workbench/services/extensions/common/proxyIdentifier'; import { ExtHostContext, ExtHostNotebookShape, MainContext, MainThreadNotebookShape } from '../common/extHost.protocol'; -import { ILogService } from 'vs/platform/log/common/log'; -import { StopWatch } from 'vs/base/common/stopwatch'; -import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { assertType } from 'vs/base/common/types'; @extHostNamedCustomer(MainContext.MainThreadNotebook) export class MainThreadNotebooks implements MainThreadNotebookShape { @@ -26,7 +26,6 @@ export class MainThreadNotebooks implements MainThreadNotebookShape { private readonly _disposables = new DisposableStore(); private readonly _proxy: ExtHostNotebookShape; - private readonly _notebookProviders = new Map(); private readonly _notebookSerializer = new Map(); private readonly _notebookCellStatusBarRegistrations = new Map(); @@ -41,51 +40,9 @@ export class MainThreadNotebooks implements MainThreadNotebookShape { dispose(): void { this._disposables.dispose(); - // remove all notebook providers - for (const item of this._notebookProviders.values()) { - item.disposable.dispose(); - } dispose(this._notebookSerializer.values()); } - async $registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string, options: TransientOptions, data: INotebookContributionData | undefined): Promise { - const contentOptions = { ...options }; - - const controller: INotebookContentProvider = { - get options() { - return contentOptions; - }, - set options(newOptions) { - contentOptions.transientCellMetadata = newOptions.transientCellMetadata; - contentOptions.transientDocumentMetadata = newOptions.transientDocumentMetadata; - contentOptions.transientOutputs = newOptions.transientOutputs; - }, - open: async (uri: URI, backupId: string | undefined, untitledDocumentData: VSBuffer | undefined, token: CancellationToken) => { - const data = await this._proxy.$openNotebook(viewType, uri, backupId, untitledDocumentData, token); - return { - data: NotebookDto.fromNotebookDataDto(data.value), - transientOptions: contentOptions - }; - }, - backup: async (uri: URI, token: CancellationToken) => '' - }; - - const disposable = new DisposableStore(); - disposable.add(this._notebookService.registerNotebookController(viewType, extension, controller)); - if (data) { - disposable.add(this._notebookService.registerContributedNotebookType(viewType, data)); - } - this._notebookProviders.set(viewType, { controller, disposable }); - } - - async $unregisterNotebookProvider(viewType: string): Promise { - const entry = this._notebookProviders.get(viewType); - if (entry) { - entry.disposable.dispose(); - this._notebookProviders.delete(viewType); - } - } - $registerNotebookSerializer(handle: number, extension: NotebookExtensionDescription, viewType: string, options: TransientOptions, data: INotebookContributionData | undefined): void { const registration = this._notebookService.registerNotebookSerializer(viewType, extension, { options, diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 52cd8c59cb3a2..67cd07bbe3917 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -937,14 +937,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I registerNotebookSerializer(viewType: string, serializer: vscode.NotebookSerializer, options?: vscode.NotebookDocumentContentOptions, registration?: vscode.NotebookRegistrationData) { return extHostNotebook.registerNotebookSerializer(extension, viewType, serializer, options, isProposedApiEnabled(extension, 'notebookLiveShare') ? registration : undefined); }, - registerNotebookContentProvider: (viewType: string, provider: vscode.NotebookContentProvider, options?: vscode.NotebookDocumentContentOptions, registration?: vscode.NotebookRegistrationData) => { - checkProposedApiEnabled(extension, 'notebookContentProvider'); - - extHostApiDeprecation.report('workspace.registerNotebookContentProvider', extension, - `The notebookContentProvider API is not on track for finalization and will be removed.`); - - return extHostNotebook.registerNotebookContentProvider(extension, viewType, provider, options); - }, onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => { return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables); }, diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 8b6a77a6e78aa..8236cc0a471e2 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -964,9 +964,6 @@ export interface INotebookCellStatusBarListDto { } export interface MainThreadNotebookShape extends IDisposable { - $registerNotebookProvider(extension: notebookCommon.NotebookExtensionDescription, viewType: string, options: notebookCommon.TransientOptions, registration: notebookCommon.INotebookContributionData | undefined): Promise; - $unregisterNotebookProvider(viewType: string): Promise; - $registerNotebookSerializer(handle: number, extension: notebookCommon.NotebookExtensionDescription, viewType: string, options: notebookCommon.TransientOptions, registration: notebookCommon.INotebookContributionData | undefined): void; $unregisterNotebookSerializer(handle: number): void; @@ -2063,8 +2060,6 @@ export interface ExtHostNotebookShape extends ExtHostNotebookDocumentsAndEditors $provideNotebookCellStatusBarItems(handle: number, uri: UriComponents, index: number, token: CancellationToken): Promise; $releaseNotebookCellStatusBarItems(id: number): void; - $openNotebook(viewType: string, uri: UriComponents, backupId: string | undefined, untitledDocumentData: VSBuffer | undefined, token: CancellationToken): Promise>; - $dataToNotebook(handle: number, data: VSBuffer, token: CancellationToken): Promise>; $notebookToData(handle: number, data: SerializableObjectWithBuffers, token: CancellationToken): Promise; } diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index bc4180dcd95f7..1b4063b5a0def 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -28,10 +28,6 @@ import { ExtHostCell, ExtHostNotebookDocument } from './extHostNotebookDocument' import { ExtHostNotebookEditor } from './extHostNotebookEditor'; -type NotebookContentProviderData = { - readonly provider: vscode.NotebookContentProvider; - readonly extension: IExtensionDescription; -}; export class ExtHostNotebookController implements ExtHostNotebookShape { private static _notebookStatusBarItemProviderHandlePool: number = 0; @@ -40,7 +36,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { private readonly _notebookDocumentsProxy: MainThreadNotebookDocumentsShape; private readonly _notebookEditorsProxy: MainThreadNotebookEditorsShape; - private readonly _notebookContentProviders = new Map(); private readonly _notebookStatusBarItemProviders = new Map(); private readonly _documents = new ResourceMap(); private readonly _editors = new Map(); @@ -137,41 +132,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { return result; } - private _getProviderData(viewType: string): NotebookContentProviderData { - const result = this._notebookContentProviders.get(viewType); - if (!result) { - throw new Error(`NO provider for '${viewType}'`); - } - return result; - } - - registerNotebookContentProvider( - extension: IExtensionDescription, - viewType: string, - provider: vscode.NotebookContentProvider, - options?: vscode.NotebookDocumentContentOptions - ): vscode.Disposable { - if (isFalsyOrWhitespace(viewType)) { - throw new Error(`viewType cannot be empty or just whitespace`); - } - if (this._notebookContentProviders.has(viewType)) { - throw new Error(`Notebook provider for '${viewType}' already registered`); - } - - this._notebookContentProviders.set(viewType, { extension, provider }); - this._notebookProxy.$registerNotebookProvider( - { id: extension.identifier, location: extension.extensionLocation }, - viewType, - typeConverters.NotebookDocumentContentOptions.from(options), - undefined, - ); - - return new extHostTypes.Disposable(() => { - this._notebookContentProviders.delete(viewType); - this._notebookProxy.$unregisterNotebookProvider(viewType); - }); - } private static _convertNotebookRegistrationData(extension: IExtensionDescription, registration: vscode.NotebookRegistrationData | undefined): INotebookContributionData | undefined { if (!registration) { @@ -341,14 +302,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { // --- open, save, saveAs, backup - async $openNotebook(viewType: string, uri: UriComponents, backupId: string | undefined, untitledDocumentData: VSBuffer | undefined, token: CancellationToken): Promise> { - const { provider } = this._getProviderData(viewType); - const data = await provider.openNotebook(URI.revive(uri), { backupId, untitledDocumentData: untitledDocumentData?.buffer }, token); - return new SerializableObjectWithBuffers({ - metadata: data.metadata ?? Object.create(null), - cells: data.cells.map(typeConverters.NotebookCellData.from), - }); - } private _createExtHostEditor(document: ExtHostNotebookDocument, editorId: string, data: INotebookEditorAddData) { diff --git a/src/vs/workbench/api/test/browser/extHostNotebook.test.ts b/src/vs/workbench/api/test/browser/extHostNotebook.test.ts index 0a9c0def1371b..ea7551f5856ae 100644 --- a/src/vs/workbench/api/test/browser/extHostNotebook.test.ts +++ b/src/vs/workbench/api/test/browser/extHostNotebook.test.ts @@ -47,17 +47,15 @@ suite('NotebookCell#Document', function () { override $registerCommand() { } }); rpcProtocol.set(MainContext.MainThreadNotebook, new class extends mock() { - override async $registerNotebookProvider() { } - override async $unregisterNotebookProvider() { } + override async $registerNotebookSerializer() { } + override async $unregisterNotebookSerializer() { } }); extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(rpcProtocol, new NullLogService()); extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors); extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments); extHostNotebookDocuments = new ExtHostNotebookDocuments(extHostNotebooks); - const reg = extHostNotebooks.registerNotebookContentProvider(nullExtensionDescription, 'test', new class extends mock() { - // async openNotebook() { } - }); + const reg = extHostNotebooks.registerNotebookSerializer(nullExtensionDescription, 'test', new class extends mock() { }); extHostNotebooks.$acceptDocumentAndEditorsDelta(new SerializableObjectWithBuffers({ addedDocuments: [{ uri: notebookUri, diff --git a/src/vs/workbench/api/test/browser/extHostNotebookKernel.test.ts b/src/vs/workbench/api/test/browser/extHostNotebookKernel.test.ts index d159691ba0353..c3c34868e1825 100644 --- a/src/vs/workbench/api/test/browser/extHostNotebookKernel.test.ts +++ b/src/vs/workbench/api/test/browser/extHostNotebookKernel.test.ts @@ -83,8 +83,8 @@ suite('NotebookKernel', function () { }); rpcProtocol.set(MainContext.MainThreadNotebook, new class extends mock() { - override async $registerNotebookProvider() { } - override async $unregisterNotebookProvider() { } + override async $registerNotebookSerializer() { } + override async $unregisterNotebookSerializer() { } }); extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(rpcProtocol, new NullLogService()); extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors); diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index 1b78f885ba3b1..bb855ef74559b 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -1246,7 +1246,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD } if (!this._webview) { - this._createWebview(this.getId(), this.textModel.viewType, this.textModel.uri); + this._ensureWebview(this.getId(), this.textModel.viewType, this.textModel.uri); } this._webviewResolvePromise = (async () => { @@ -1283,7 +1283,11 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD return this._webviewResolvePromise; } - private async _createWebview(id: string, viewType: string, resource: URI): Promise { + private _ensureWebview(id: string, viewType: string, resource: URI) { + if (this._webview) { + return; + } + const that = this; this._webview = this.instantiationService.createInstance(BackLayerWebView, { @@ -1316,7 +1320,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD } private async _attachModel(textModel: NotebookTextModel, viewState: INotebookEditorViewState | undefined, perf?: NotebookPerfMarks) { - await this._createWebview(this.getId(), textModel.viewType, textModel.uri); + this._ensureWebview(this.getId(), textModel.viewType, textModel.uri); + this.viewModel = this.instantiationService.createInstance(NotebookViewModel, textModel.viewType, textModel, this._viewContext, this.getLayoutInfo(), { isReadOnly: this._readOnly }); this._viewContext.eventDispatcher.emit([new NotebookLayoutChangedEvent({ width: true, fontInfo: true }, this.getLayoutInfo())]); diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index fc3c907c52f2f..533692c95d0aa 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -40,7 +40,6 @@ export const allApiProposals = Object.freeze({ interactiveWindow: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.interactiveWindow.d.ts', ipc: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.ipc.d.ts', notebookCellExecutionState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookCellExecutionState.d.ts', - notebookContentProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookContentProvider.d.ts', notebookControllerAffinityHidden: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookControllerAffinityHidden.d.ts', notebookControllerKind: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookControllerKind.d.ts', notebookDeprecated: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookDeprecated.d.ts', diff --git a/src/vscode-dts/vscode.proposed.notebookContentProvider.d.ts b/src/vscode-dts/vscode.proposed.notebookContentProvider.d.ts deleted file mode 100644 index d336c2ccf5415..0000000000000 --- a/src/vscode-dts/vscode.proposed.notebookContentProvider.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -declare module 'vscode' { - - // https://github.com/microsoft/vscode/issues/147248 - - /** @deprecated */ - interface NotebookDocumentOpenContext { - readonly backupId?: string; - readonly untitledDocumentData?: Uint8Array; - } - - // todo@API use openNotebookDOCUMENT to align with openCustomDocument etc? - // todo@API rename to NotebookDocumentContentProvider - /** @deprecated */ - export interface NotebookContentProvider { - - /** - * Content providers should always use {@link FileSystemProvider file system providers} to - * resolve the raw content for `uri` as the resource is not necessarily a file on disk. - */ - openNotebook(uri: Uri, openContext: NotebookDocumentOpenContext, token: CancellationToken): NotebookData | Thenable; - } - - export namespace workspace { - - // TODO@api use NotebookDocumentFilter instead of just notebookType:string? - // TODO@API options duplicates the more powerful variant on NotebookContentProvider - /** @deprecated */ - export function registerNotebookContentProvider(notebookType: string, provider: NotebookContentProvider, options?: NotebookDocumentContentOptions): Disposable; - } -}