From d0cc52143b35092ebabe55009a79cc8d29e23375 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 10 Jun 2021 11:18:46 +0200 Subject: [PATCH] change IOutputItemDto to use real bytes, add many dedicated dto-types for transporting output (which cannot be bytes), remove metadata2 from renderer --- .../api/browser/mainThreadEditors.ts | 3 +- .../api/browser/mainThreadNotebook.ts | 15 +- .../browser/mainThreadNotebookDocuments.ts | 94 +++++++------ .../mainThreadNotebookDocumentsAndEditors.ts | 13 +- .../api/browser/mainThreadNotebookDto.ts | 122 +++++++++++++++++ .../api/browser/mainThreadNotebookEditors.ts | 9 +- .../api/browser/mainThreadNotebookKernels.ts | 11 +- .../workbench/api/common/extHost.protocol.ts | 129 +++++++++++++++--- .../workbench/api/common/extHostNotebook.ts | 16 +-- .../api/common/extHostNotebookDocument.ts | 75 +++++----- .../api/common/extHostNotebookDocuments.ts | 11 +- .../api/common/extHostNotebookEditor.ts | 16 +-- .../api/common/extHostNotebookKernels.ts | 19 +-- .../api/common/extHostTypeConverters.ts | 61 ++------- src/vs/workbench/api/common/extHostTypes.ts | 28 +--- .../notebook/browser/notebookServiceImpl.ts | 4 +- .../view/output/transforms/richTransform.ts | 5 +- .../view/renderers/backLayerWebView.ts | 9 +- .../browser/view/renderers/webviewMessages.ts | 2 +- .../browser/view/renderers/webviewPreloads.ts | 3 - .../contrib/notebook/common/notebookCommon.ts | 4 +- .../notebook/common/notebookEditorModel.ts | 4 +- .../notebook/common/notebookService.ts | 12 +- .../common/services/notebookSimpleWorker.ts | 4 +- .../notebook/test/notebookDiff.test.ts | 28 ++-- .../notebook/test/notebookEditorModel.test.ts | 14 +- .../notebook/test/notebookTextModel.test.ts | 42 +++--- .../browser/api/extHostNotebookKernel.test.ts | 32 ++--- 28 files changed, 470 insertions(+), 315 deletions(-) create mode 100644 src/vs/workbench/api/browser/mainThreadNotebookDto.ts diff --git a/src/vs/workbench/api/browser/mainThreadEditors.ts b/src/vs/workbench/api/browser/mainThreadEditors.ts index c18de551a26..9cf68817e11 100644 --- a/src/vs/workbench/api/browser/mainThreadEditors.ts +++ b/src/vs/workbench/api/browser/mainThreadEditors.ts @@ -27,6 +27,7 @@ import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/wo import { revive } from 'vs/base/common/marshalling'; import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { NotebookDto } from 'vs/workbench/api/browser/mainThreadNotebookDto'; export function reviveWorkspaceEditDto2(data: IWorkspaceEditDto | undefined): ResourceEdit[] { if (!data?.edits) { @@ -40,7 +41,7 @@ export function reviveWorkspaceEditDto2(data: IWorkspaceEditDto | undefined): Re } else if (edit._type === WorkspaceEditType.Text) { result.push(new ResourceTextEdit(edit.resource, edit.edit, edit.modelVersionId, edit.metadata)); } else if (edit._type === WorkspaceEditType.Cell) { - result.push(new ResourceNotebookCellEdit(edit.resource, edit.edit, edit.notebookVersionId, edit.metadata)); + result.push(new ResourceNotebookCellEdit(edit.resource, NotebookDto.fromCellEditOperationDto(edit.edit), edit.notebookVersionId, edit.metadata)); } } return result; diff --git a/src/vs/workbench/api/browser/mainThreadNotebook.ts b/src/vs/workbench/api/browser/mainThreadNotebook.ts index b95e973ad7f..cc20644d23b 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebook.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebook.ts @@ -8,9 +8,10 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter } from 'vs/base/common/event'; import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; +import { NotebookDto } from 'vs/workbench/api/browser/mainThreadNotebookDto'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService'; -import { INotebookCellStatusBarItemProvider, INotebookContributionData, NotebookDataDto, TransientCellMetadata, TransientDocumentMetadata, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { INotebookCellStatusBarItemProvider, INotebookContributionData, NotebookData as NotebookData, TransientCellMetadata, TransientDocumentMetadata, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookContentProvider, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, MainContext, MainThreadNotebookShape, NotebookExtensionDescription } from '../common/extHost.protocol'; @@ -56,7 +57,7 @@ export class MainThreadNotebooks implements MainThreadNotebookShape { 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, + data: NotebookDto.fromNotebookDataDto(data), transientOptions: contentOptions }; }, @@ -100,14 +101,16 @@ export class MainThreadNotebooks implements MainThreadNotebookShape { } } + $registerNotebookSerializer(handle: number, extension: NotebookExtensionDescription, viewType: string, options: TransientOptions, data: INotebookContributionData | undefined): void { const registration = this._notebookService.registerNotebookSerializer(viewType, extension, { options, - dataToNotebook: (data: VSBuffer): Promise => { - return this._proxy.$dataToNotebook(handle, data, CancellationToken.None); + dataToNotebook: async (data: VSBuffer): Promise => { + const dto = await this._proxy.$dataToNotebook(handle, data, CancellationToken.None); + return NotebookDto.fromNotebookDataDto(dto); }, - notebookToData: (data: NotebookDataDto): Promise => { - return this._proxy.$notebookToData(handle, data, CancellationToken.None); + notebookToData: (data: NotebookData): Promise => { + return this._proxy.$notebookToData(handle, NotebookDto.toNotebookDataDto(data), CancellationToken.None); } }); const disposables = new DisposableStore(); diff --git a/src/vs/workbench/api/browser/mainThreadNotebookDocuments.ts b/src/vs/workbench/api/browser/mainThreadNotebookDocuments.ts index 0f67be165ab..8388da36ca7 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebookDocuments.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebookDocuments.ts @@ -9,14 +9,15 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import { BoundModelReferenceCollection } from 'vs/workbench/api/browser/mainThreadDocuments'; import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; -import { IMainCellDto, NotebookCellsChangeType, NotebookDataDto } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity'; -import { ExtHostContext, ExtHostNotebookDocumentsShape, IExtHostContext, MainThreadNotebookDocumentsShape } from '../common/extHost.protocol'; +import { ExtHostContext, ExtHostNotebookDocumentsShape, IExtHostContext, MainThreadNotebookDocumentsShape, NotebookCellDto, NotebookCellsChangedEventDto, NotebookDataDto } from '../common/extHost.protocol'; import { MainThreadNotebooksAndEditors } from 'vs/workbench/api/browser/mainThreadNotebookDocumentsAndEditors'; import { Schemas } from 'vs/base/common/network'; import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider'; +import { NotebookDto } from 'vs/workbench/api/browser/mainThreadNotebookDto'; export class MainThreadNotebookDocuments implements MainThreadNotebookDocumentsShape { @@ -55,36 +56,59 @@ export class MainThreadNotebookDocuments implements MainThreadNotebookDocumentsS for (const textModel of notebooks) { const disposableStore = new DisposableStore(); disposableStore.add(textModel.onDidChangeContent(event => { - const dto = event.rawEvents.map(e => { - const data = - e.kind === NotebookCellsChangeType.ModelChange || e.kind === NotebookCellsChangeType.Initialize - ? { - kind: e.kind, - versionId: event.versionId, - changes: e.changes.map(diff => [diff[0], diff[1], diff[2].map(cell => MainThreadNotebookDocuments._cellToDto(cell as NotebookCellTextModel))] as [number, number, IMainCellDto[]]) - } - : ( - e.kind === NotebookCellsChangeType.Move - ? { - kind: e.kind, - index: e.index, - length: e.length, - newIdx: e.newIdx, - versionId: event.versionId, - cells: e.cells.map(cell => MainThreadNotebookDocuments._cellToDto(cell as NotebookCellTextModel)) - } - : e - ); - return data; - }); + const eventDto: NotebookCellsChangedEventDto = { + versionId: event.versionId, + rawEvents: [] + }; + + for (const e of event.rawEvents) { + + switch (e.kind) { + case NotebookCellsChangeType.ModelChange: + eventDto.rawEvents.push({ + kind: e.kind, + changes: e.changes.map(diff => [diff[0], diff[1], diff[2].map(cell => NotebookDto.toNotebookCellDto(cell as NotebookCellTextModel))] as [number, number, NotebookCellDto[]]) + }); + break; + case NotebookCellsChangeType.Move: + eventDto.rawEvents.push({ + kind: e.kind, + index: e.index, + length: e.length, + newIdx: e.newIdx, + }); + break; + case NotebookCellsChangeType.Output: + eventDto.rawEvents.push({ + kind: e.kind, + index: e.index, + outputs: e.outputs.map(NotebookDto.toNotebookOutputDto) + }); + break; + case NotebookCellsChangeType.OutputItem: + eventDto.rawEvents.push({ + kind: e.kind, + index: e.index, + outputId: e.outputId, + outputItems: e.outputItems.map(NotebookDto.toNotebookOutputItemDto), + append: e.append + }); + break; + case NotebookCellsChangeType.ChangeLanguage: + case NotebookCellsChangeType.ChangeCellMetadata: + case NotebookCellsChangeType.ChangeCellInternalMetadata: + eventDto.rawEvents.push(e); + break; + } + } // using the model resolver service to know if the model is dirty or not. // assuming this is the first listener it can mean that at first the model // is marked as dirty and that another event is fired this._proxy.$acceptModelChanged( textModel.uri, - { rawEvents: dto, versionId: event.versionId }, + eventDto, this._notebookEditorModelResolverService.isDirty(textModel.uri) ); @@ -105,19 +129,6 @@ export class MainThreadNotebookDocuments implements MainThreadNotebookDocumentsS } } - private static _cellToDto(cell: NotebookCellTextModel): IMainCellDto { - return { - handle: cell.handle, - uri: cell.uri, - source: cell.textBuffer.getLinesContent(), - eol: cell.textBuffer.getEOL(), - language: cell.language, - cellKind: cell.cellKind, - outputs: cell.outputs, - metadata: cell.metadata, - internalMetadata: cell.internalMetadata, - }; - } async $tryCreateNotebook(options: { viewType: string, content?: NotebookDataDto }): Promise { @@ -150,11 +161,8 @@ export class MainThreadNotebookDocuments implements MainThreadNotebookDocumentsS // apply content changes... slightly HACKY -> this triggers a change event if (options.content) { - ref.object.notebook.reset( - options.content.cells, - options.content.metadata, - ref.object.notebook.transientOptions - ); + const data = NotebookDto.fromNotebookDataDto(options.content); + ref.object.notebook.reset(data.cells, data.metadata, ref.object.notebook.transientOptions); } return uri; } diff --git a/src/vs/workbench/api/browser/mainThreadNotebookDocumentsAndEditors.ts b/src/vs/workbench/api/browser/mainThreadNotebookDocumentsAndEditors.ts index be97d15f096..0e0e867b7f5 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebookDocumentsAndEditors.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebookDocumentsAndEditors.ts @@ -9,6 +9,7 @@ import { combinedDisposable, DisposableStore, IDisposable } from 'vs/base/common import { URI } from 'vs/base/common/uri'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { MainThreadNotebookDocuments } from 'vs/workbench/api/browser/mainThreadNotebookDocuments'; +import { NotebookDto } from 'vs/workbench/api/browser/mainThreadNotebookDto'; import { MainThreadNotebookEditors } from 'vs/workbench/api/browser/mainThreadNotebookEditors'; import { extHostCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { editorGroupToViewColumn } from 'vs/workbench/common/editor'; @@ -226,17 +227,7 @@ export class MainThreadNotebooksAndEditors { uri: e.uri, metadata: e.metadata, versionId: e.versionId, - cells: e.cells.map(cell => ({ - handle: cell.handle, - uri: cell.uri, - source: cell.textBuffer.getLinesContent(), - eol: cell.textBuffer.getEOL(), - language: cell.language, - cellKind: cell.cellKind, - outputs: cell.outputs, - metadata: cell.metadata, - internalMetadata: cell.internalMetadata, - })) + cells: e.cells.map(NotebookDto.toNotebookCellDto) }; } diff --git a/src/vs/workbench/api/browser/mainThreadNotebookDto.ts b/src/vs/workbench/api/browser/mainThreadNotebookDto.ts new file mode 100644 index 00000000000..7766ea07366 --- /dev/null +++ b/src/vs/workbench/api/browser/mainThreadNotebookDto.ts @@ -0,0 +1,122 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol'; +import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; +import * as notebookCommon from 'vs/workbench/contrib/notebook/common/notebookCommon'; + +export namespace NotebookDto { + + export function toNotebookOutputItemDto(item: notebookCommon.IOutputItemDto): extHostProtocol.NotebookOutputItemDto { + return { + mime: item.mime, + valueBytes: Array.from(item.data) + }; + } + + export function toNotebookOutputDto(output: notebookCommon.IOutputDto): extHostProtocol.NotebookOutputDto { + return { + outputId: output.outputId, + metadata: output.metadata, + items: output.outputs.map(toNotebookOutputItemDto) + }; + } + + export function toNotebookCellDataDto(cell: notebookCommon.ICellDto2): extHostProtocol.NotebookCellDataDto { + return { + cellKind: cell.cellKind, + language: cell.language, + source: cell.source, + outputs: cell.outputs.map(toNotebookOutputDto) + }; + } + + export function toNotebookDataDto(data: notebookCommon.NotebookData): extHostProtocol.NotebookDataDto { + return { + metadata: data.metadata, + cells: data.cells.map(toNotebookCellDataDto) + }; + } + + export function fromNotebookOutputItemDto(item: extHostProtocol.NotebookOutputItemDto): notebookCommon.IOutputItemDto { + return { + mime: item.mime, + data: new Uint8Array(item.valueBytes) + }; + } + + export function fromNotebookOutputDto(output: extHostProtocol.NotebookOutputDto): notebookCommon.IOutputDto { + return { + outputId: output.outputId, + metadata: output.metadata, + outputs: output.items.map(fromNotebookOutputItemDto) + }; + } + + export function fromNotebookCellDataDto(cell: extHostProtocol.NotebookCellDataDto): notebookCommon.ICellDto2 { + return { + cellKind: cell.cellKind, + language: cell.language, + source: cell.source, + outputs: cell.outputs.map(fromNotebookOutputDto), + metadata: cell.metadata, + internalMetadata: cell.internalMetadata + }; + } + + export function fromNotebookDataDto(data: extHostProtocol.NotebookDataDto): notebookCommon.NotebookData { + return { + metadata: data.metadata, + cells: data.cells.map(fromNotebookCellDataDto) + }; + } + + export function toNotebookCellDto(cell: NotebookCellTextModel): extHostProtocol.NotebookCellDto { + return { + handle: cell.handle, + uri: cell.uri, + source: cell.textBuffer.getLinesContent(), + eol: cell.textBuffer.getEOL(), + language: cell.language, + cellKind: cell.cellKind, + outputs: cell.outputs.map(toNotebookOutputDto), + metadata: cell.metadata, + internalMetadata: cell.internalMetadata, + }; + } + + export function fromCellExecuteEditDto(data: extHostProtocol.CellExecuteEditDto): notebookCommon.IImmediateCellEditOperation { + if (data.editType === notebookCommon.CellEditType.PartialInternalMetadata) { + return data; + } else if (data.editType === notebookCommon.CellEditType.Output) { + return { + editType: data.editType, + handle: data.handle, + append: data.append, + outputs: data.outputs.map(fromNotebookOutputDto) + }; + } else { + return { + editType: data.editType, + append: data.append, + outputId: data.outputId, + items: data.items.map(fromNotebookOutputItemDto) + }; + } + } + + export function fromCellEditOperationDto(edit: extHostProtocol.ICellEditOperationDto): notebookCommon.ICellEditOperation { + if (edit.editType === notebookCommon.CellEditType.Replace) { + return { + editType: edit.editType, + index: edit.index, + count: edit.count, + cells: edit.cells.map(fromNotebookCellDataDto) + }; + } else { + return edit; + } + } +} diff --git a/src/vs/workbench/api/browser/mainThreadNotebookEditors.ts b/src/vs/workbench/api/browser/mainThreadNotebookEditors.ts index 76c0c0a4000..6714310ec0c 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebookEditors.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebookEditors.ts @@ -6,9 +6,9 @@ import { DisposableStore, dispose } from 'vs/base/common/lifecycle'; import { getNotebookEditorFromEditorPane, INotebookEditor, INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService'; -import { ExtHostContext, ExtHostNotebookEditorsShape, IExtHostContext, INotebookDocumentShowOptions, INotebookEditorViewColumnInfo, MainThreadNotebookEditorsShape, NotebookEditorRevealType } from '../common/extHost.protocol'; +import { ExtHostContext, ExtHostNotebookEditorsShape, ICellEditOperationDto, IExtHostContext, INotebookDocumentShowOptions, INotebookEditorViewColumnInfo, MainThreadNotebookEditorsShape, NotebookEditorRevealType } from '../common/extHost.protocol'; import { MainThreadNotebooksAndEditors } from 'vs/workbench/api/browser/mainThreadNotebookDocumentsAndEditors'; -import { ICellEditOperation, INotebookDecorationRenderOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { INotebookDecorationRenderOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange'; import { ILogService } from 'vs/platform/log/common/log'; import { URI, UriComponents } from 'vs/base/common/uri'; @@ -19,6 +19,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { editorGroupToViewColumn } from 'vs/workbench/common/editor'; import { equals } from 'vs/base/common/objects'; +import { NotebookDto } from 'vs/workbench/api/browser/mainThreadNotebookDto'; class MainThreadNotebook { @@ -104,7 +105,7 @@ export class MainThreadNotebookEditors implements MainThreadNotebookEditorsShape } } - async $tryApplyEdits(editorId: string, modelVersionId: number, cellEdits: ICellEditOperation[]): Promise { + async $tryApplyEdits(editorId: string, modelVersionId: number, cellEdits: ICellEditOperationDto[]): Promise { const wrapper = this._mainThreadEditors.get(editorId); if (!wrapper) { return false; @@ -118,7 +119,7 @@ export class MainThreadNotebookEditors implements MainThreadNotebookEditorsShape return false; } //todo@jrieken use proper selection logic! - return editor.textModel.applyEdits(cellEdits, true, undefined, () => undefined, undefined); + return editor.textModel.applyEdits(cellEdits.map(NotebookDto.fromCellEditOperationDto), true, undefined, () => undefined, undefined); } async $tryShowNotebookDocument(resource: UriComponents, viewType: string, options: INotebookDocumentShowOptions): Promise { diff --git a/src/vs/workbench/api/browser/mainThreadNotebookKernels.ts b/src/vs/workbench/api/browser/mainThreadNotebookKernels.ts index d0ab2ff506f..04883d351bc 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebookKernels.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebookKernels.ts @@ -10,13 +10,14 @@ import { combinedDisposable, DisposableStore, IDisposable } from 'vs/base/common import { URI, UriComponents } from 'vs/base/common/uri'; import { IModeService } from 'vs/editor/common/services/modeService'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { NotebookDto } from 'vs/workbench/api/browser/mainThreadNotebookDto'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService'; -import { IImmediateCellEditOperation, INotebookKernel, INotebookKernelChangeEvent } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { INotebookKernel, INotebookKernelChangeEvent } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; -import { ExtHostContext, ExtHostNotebookKernelsShape, IExtHostContext, INotebookKernelDto2, MainContext, MainThreadNotebookKernelsShape } from '../common/extHost.protocol'; +import { CellExecuteEditDto, ExtHostContext, ExtHostNotebookKernelsShape, IExtHostContext, INotebookKernelDto2, MainContext, MainThreadNotebookKernelsShape } from '../common/extHost.protocol'; abstract class MainThreadKernel implements INotebookKernel { @@ -225,14 +226,16 @@ export class MainThreadNotebookKernels implements MainThreadNotebookKernelsShape // --- execution editss - async $applyExecutionEdits(resource: UriComponents, cellEdits: IImmediateCellEditOperation[]): Promise { + async $applyExecutionEdits(resource: UriComponents, cellEdits: CellExecuteEditDto[]): Promise { const textModel = this._notebookService.getNotebookTextModel(URI.from(resource)); if (!textModel) { throw new Error(`Can't apply edits to unknown notebook model: ${URI.revive(resource).toString()}`); } + const edits = cellEdits.map(NotebookDto.fromCellExecuteEditDto); + try { - textModel.applyEdits(cellEdits, true, undefined, () => undefined, undefined, false); + textModel.applyEdits(edits, true, undefined, () => undefined, undefined, false); } catch (e) { // Clearing outputs at the same time as the EH calling append/replaceOutputItems is an expected race, and it should be a no-op. // And any other failure should not throw back to the extension. diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 61b9043f1b4..1830904e2ec 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -833,16 +833,6 @@ export enum CellOutputKind { Rich = 3 } -export interface ICellDto { - handle: number; - uri: UriComponents, - source: string[]; - language: string; - cellKind: notebookCommon.CellKind; - outputs: notebookCommon.IOutputDto[]; - metadata?: notebookCommon.NotebookCellMetadata; -} - export enum NotebookEditorRevealType { Default = 0, InCenter = 1, @@ -884,11 +874,11 @@ export interface MainThreadNotebookEditorsShape extends IDisposable { $removeNotebookEditorDecorationType(key: string): void; $trySetSelections(id: string, range: ICellRange[]): void; $trySetDecorations(id: string, range: ICellRange, decorationKey: string): void; - $tryApplyEdits(editorId: string, modelVersionId: number, cellEdits: notebookCommon.ICellEditOperation[]): Promise + $tryApplyEdits(editorId: string, modelVersionId: number, cellEdits: ICellEditOperationDto[]): Promise } export interface MainThreadNotebookDocumentsShape extends IDisposable { - $tryCreateNotebook(options: { viewType: string, content?: notebookCommon.NotebookDataDto }): Promise; + $tryCreateNotebook(options: { viewType: string, content?: NotebookDataDto }): Promise; $tryOpenNotebook(uriComponents: UriComponents): Promise; $trySaveNotebook(uri: UriComponents): Promise; } @@ -907,6 +897,22 @@ export interface INotebookKernelDto2 { preloads?: { uri: UriComponents; provides: string[] }[]; } +export interface CellExecuteOutputEditDto { + editType: notebookCommon.CellEditType.Output; + append?: boolean; + handle: number; + outputs: NotebookOutputDto[] +} + +export interface CellExecuteOutputItemEditDto { + editType: notebookCommon.CellEditType.OutputItems; + append?: boolean; + outputId: string; + items: NotebookOutputItemDto[] +} + +export type CellExecuteEditDto = CellExecuteOutputEditDto | CellExecuteOutputItemEditDto | notebookCommon.ICellPartialInternalMetadataEditByHandle; + export interface MainThreadNotebookKernelsShape extends IDisposable { $postMessage(handle: number, editorId: string | undefined, message: any): Promise; $addKernel(handle: number, data: INotebookKernelDto2): Promise; @@ -914,7 +920,7 @@ export interface MainThreadNotebookKernelsShape extends IDisposable { $removeKernel(handle: number): void; $updateNotebookPriority(handle: number, uri: UriComponents, value: number | undefined): void; - $applyExecutionEdits(resource: UriComponents, edits: notebookCommon.IImmediateCellEditOperation[]): Promise; + $applyExecutionEdits(resource: UriComponents, edits: CellExecuteEditDto[]): Promise; } export interface MainThreadNotebookRenderersShape extends IDisposable { @@ -1503,12 +1509,22 @@ export interface IWorkspaceTextEditDto { metadata?: IWorkspaceEditEntryMetadataDto; } +export type ICellEditOperationDto = + notebookCommon.ICellPartialMetadataEdit + | notebookCommon.IDocumentMetadataEdit + | { + editType: notebookCommon.CellEditType.Replace, + index: number, + count: number, + cells: NotebookCellDataDto[] + }; + export interface IWorkspaceCellEditDto { _type: WorkspaceEditType.Cell; resource: UriComponents; - edit: notebookCommon.ICellEditOperation; notebookVersionId?: number; metadata?: IWorkspaceEditEntryMetadataDto; + edit: ICellEditOperationDto; } export interface IWorkspaceEditDto { @@ -1877,7 +1893,7 @@ export interface INotebookDocumentPropertiesChangeData { export interface INotebookModelAddedData { uri: UriComponents; versionId: number; - cells: notebookCommon.IMainCellDto[], + cells: NotebookCellDto[], viewType: string; metadata?: notebookCommon.NotebookDocumentMetadata; } @@ -1899,17 +1915,54 @@ export interface INotebookDocumentsAndEditorsDelta { visibleEditors?: string[]; } +export interface NotebookOutputItemDto { + readonly mime: string; + readonly valueBytes: number[]; // todo@jrieken ugly, should be VSBuffer +} + +export interface NotebookOutputDto { + items: NotebookOutputItemDto[]; + outputId: string; + metadata?: Record; +} + +export interface NotebookCellDataDto { + source: string; + language: string; + cellKind: notebookCommon.CellKind; + outputs: NotebookOutputDto[]; + metadata?: notebookCommon.NotebookCellMetadata; + internalMetadata?: notebookCommon.NotebookCellInternalMetadata; +} + +export interface NotebookDataDto { + readonly cells: NotebookCellDataDto[]; + readonly metadata: notebookCommon.NotebookDocumentMetadata; +} + +export interface NotebookCellDto { + handle: number; + uri: UriComponents; + eol: string; + source: string[]; + language: string; + cellKind: notebookCommon.CellKind; + outputs: NotebookOutputDto[]; + metadata?: notebookCommon.NotebookCellMetadata; + internalMetadata?: notebookCommon.NotebookCellInternalMetadata; +} + export interface ExtHostNotebookShape extends ExtHostNotebookDocumentsAndEditorsShape { $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; + $openNotebook(viewType: string, uri: UriComponents, backupId: string | undefined, untitledDocumentData: VSBuffer | undefined, token: CancellationToken): Promise; $saveNotebook(viewType: string, uri: UriComponents, token: CancellationToken): Promise; $saveNotebookAs(viewType: string, uri: UriComponents, target: UriComponents, token: CancellationToken): Promise; $backupNotebook(viewType: string, uri: UriComponents, cancellation: CancellationToken): Promise; - $dataToNotebook(handle: number, data: VSBuffer, token: CancellationToken): Promise; - $notebookToData(handle: number, data: notebookCommon.NotebookDataDto, token: CancellationToken): Promise; + $dataToNotebook(handle: number, data: VSBuffer, token: CancellationToken): Promise; + $notebookToData(handle: number, data: NotebookDataDto, token: CancellationToken): Promise; } export interface ExtHostNotebookRenderersShape { @@ -1920,8 +1973,46 @@ export interface ExtHostNotebookDocumentsAndEditorsShape { $acceptDocumentAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta): void; } +export type NotebookRawContentEventDto = + // notebookCommon.NotebookCellsInitializeEvent + | { + + readonly kind: notebookCommon.NotebookCellsChangeType.ModelChange; + readonly changes: notebookCommon.NotebookCellTextModelSplice[]; + } + | { + readonly kind: notebookCommon.NotebookCellsChangeType.Move; + readonly index: number; + readonly length: number; + readonly newIdx: number; + } + | { + readonly kind: notebookCommon.NotebookCellsChangeType.Output; + readonly index: number; + readonly outputs: NotebookOutputDto[]; + } + | { + readonly kind: notebookCommon.NotebookCellsChangeType.OutputItem; + readonly index: number; + readonly outputId: string; + readonly outputItems: NotebookOutputItemDto[]; + readonly append: boolean; + } + | notebookCommon.NotebookCellsChangeLanguageEvent + | notebookCommon.NotebookCellsChangeMetadataEvent + | notebookCommon.NotebookCellsChangeInternalMetadataEvent + // | notebookCommon.NotebookDocumentChangeMetadataEvent + // | notebookCommon.NotebookCellContentChangeEvent + // | notebookCommon.NotebookDocumentUnknownChangeEvent + ; + +export type NotebookCellsChangedEventDto = { + readonly rawEvents: NotebookRawContentEventDto[]; + readonly versionId: number; +}; + export interface ExtHostNotebookDocumentsShape { - $acceptModelChanged(uriComponents: UriComponents, event: notebookCommon.NotebookCellsChangedEventDto, isDirty: boolean): void; + $acceptModelChanged(uriComponents: UriComponents, event: NotebookCellsChangedEventDto, isDirty: boolean): void; $acceptDirtyStateChanged(uriComponents: UriComponents, isDirty: boolean): void; $acceptModelSaved(uriComponents: UriComponents): void; $acceptDocumentPropertiesChanged(uriComponents: UriComponents, data: INotebookDocumentPropertiesChangeData): void; diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index f846afde578..5a1ddce9a66 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -15,14 +15,14 @@ import { assertIsDefined } from 'vs/base/common/types'; import { URI, UriComponents } from 'vs/base/common/uri'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { Cache } from 'vs/workbench/api/common/cache'; -import { ExtHostNotebookShape, IMainContext, IModelAddedData, INotebookCellStatusBarListDto, INotebookDocumentsAndEditorsDelta, INotebookDocumentShowOptions, INotebookEditorAddData, MainContext, MainThreadNotebookDocumentsShape, MainThreadNotebookEditorsShape, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostNotebookShape, IMainContext, IModelAddedData, INotebookCellStatusBarListDto, INotebookDocumentsAndEditorsDelta, INotebookDocumentShowOptions, INotebookEditorAddData, MainContext, MainThreadNotebookDocumentsShape, MainThreadNotebookEditorsShape, MainThreadNotebookShape, NotebookDataDto } from 'vs/workbench/api/common/extHost.protocol'; import { CommandsConverter, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; -import { INotebookExclusiveDocumentFilter, INotebookContributionData, NotebookCellsChangeType, NotebookDataDto } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { INotebookExclusiveDocumentFilter, INotebookContributionData } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import type * as vscode from 'vscode'; import { ExtHostCell, ExtHostNotebookDocument } from './extHostNotebookDocument'; import { ExtHostNotebookEditor } from './extHostNotebookEditor'; @@ -438,7 +438,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { for (const modelData of delta.addedDocuments) { const uri = URI.revive(modelData.uri); - const viewType = modelData.viewType; if (this._documents.has(uri)) { throw new Error(`adding EXISTING notebook ${uri} `); @@ -463,19 +462,10 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { that._onDidChangeCellExecutionState.fire(event); } }, - viewType, - modelData.metadata ?? Object.create({}), uri, + modelData ); - document.acceptModelChanged({ - versionId: modelData.versionId, - rawEvents: [{ - kind: NotebookCellsChangeType.Initialize, - changes: [[0, 0, modelData.cells]] - }] - }, false); - // add cell document as vscode.TextDocument addedCellDocuments.push(...modelData.cells.map(cell => ExtHostCell.asModelAddData(document.apiNotebook, cell))); diff --git a/src/vs/workbench/api/common/extHostNotebookDocument.ts b/src/vs/workbench/api/common/extHostNotebookDocument.ts index 55c2669a3d7..7a0ac1ea3f0 100644 --- a/src/vs/workbench/api/common/extHostNotebookDocument.ts +++ b/src/vs/workbench/api/common/extHostNotebookDocument.ts @@ -6,12 +6,12 @@ import { Schemas } from 'vs/base/common/network'; import { deepFreeze, equals } from 'vs/base/common/objects'; import { URI } from 'vs/base/common/uri'; -import { INotebookDocumentPropertiesChangeData, MainThreadNotebookDocumentsShape } from 'vs/workbench/api/common/extHost.protocol'; +import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostDocumentsAndEditors, IExtHostModelAddedData } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import * as extHostTypeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; -import { CellKind, IMainCellDto, IOutputDto, IOutputItemDto, NotebookCellInternalMetadata, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookCellsSplice2 } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import * as notebookCommon from 'vs/workbench/contrib/notebook/common/notebookCommon'; import * as vscode from 'vscode'; class RawContentChangeEvent { @@ -32,7 +32,7 @@ class RawContentChangeEvent { export class ExtHostCell { - static asModelAddData(notebook: vscode.NotebookDocument, cell: IMainCellDto): IExtHostModelAddedData { + static asModelAddData(notebook: vscode.NotebookDocument, cell: extHostProtocol.NotebookCellDto): IExtHostModelAddedData { return { EOL: cell.eol, lines: cell.source, @@ -45,20 +45,20 @@ export class ExtHostCell { } private _outputs: vscode.NotebookCellOutput[]; - private _metadata: NotebookCellMetadata; + private _metadata: notebookCommon.NotebookCellMetadata; private _previousResult: vscode.NotebookCellExecutionSummary | undefined; - private _internalMetadata: NotebookCellInternalMetadata; + private _internalMetadata: notebookCommon.NotebookCellInternalMetadata; readonly handle: number; readonly uri: URI; - readonly cellKind: CellKind; + readonly cellKind: notebookCommon.CellKind; private _apiCell: vscode.NotebookCell | undefined; constructor( readonly notebook: ExtHostNotebookDocument, private readonly _extHostDocument: ExtHostDocumentsAndEditors, - private readonly _cellData: IMainCellDto, + private readonly _cellData: extHostProtocol.NotebookCellDto, ) { this.handle = _cellData.handle; this.uri = URI.revive(_cellData.uri); @@ -69,7 +69,7 @@ export class ExtHostCell { this._previousResult = extHostTypeConverters.NotebookCellExecutionSummary.to(_cellData.internalMetadata ?? {}); } - get internalMetadata(): NotebookCellInternalMetadata { + get internalMetadata(): notebookCommon.NotebookCellInternalMetadata { return this._internalMetadata; } @@ -93,11 +93,11 @@ export class ExtHostCell { return this._apiCell; } - setOutputs(newOutputs: IOutputDto[]): void { + setOutputs(newOutputs: extHostProtocol.NotebookOutputDto[]): void { this._outputs = newOutputs.map(extHostTypeConverters.NotebookCellOutput.to); } - setOutputItems(outputId: string, append: boolean, newOutputItems: IOutputItemDto[]) { + setOutputItems(outputId: string, append: boolean, newOutputItems: extHostProtocol.NotebookOutputItemDto[]) { const newItems = newOutputItems.map(extHostTypeConverters.NotebookCellOutputItem.to); const output = this._outputs.find(op => op.id === outputId); if (output) { @@ -108,11 +108,11 @@ export class ExtHostCell { } } - setMetadata(newMetadata: NotebookCellMetadata): void { + setMetadata(newMetadata: notebookCommon.NotebookCellMetadata): void { this._metadata = newMetadata; } - setInternalMetadata(newInternalMetadata: NotebookCellInternalMetadata): void { + setInternalMetadata(newInternalMetadata: notebookCommon.NotebookCellInternalMetadata): void { this._internalMetadata = newInternalMetadata; this._previousResult = extHostTypeConverters.NotebookCellExecutionSummary.to(newInternalMetadata); } @@ -131,23 +131,30 @@ export class ExtHostNotebookDocument { private static _handlePool: number = 0; readonly handle = ExtHostNotebookDocument._handlePool++; - private _cells: ExtHostCell[] = []; + private readonly _cells: ExtHostCell[] = []; + + private readonly _notebookType: string; private _notebook: vscode.NotebookDocument | undefined; + private _metadata: Record; private _versionId: number = 0; private _isDirty: boolean = false; private _backup?: vscode.NotebookDocumentBackup; private _disposed: boolean = false; constructor( - private readonly _proxy: MainThreadNotebookDocumentsShape, + private readonly _proxy: extHostProtocol.MainThreadNotebookDocumentsShape, private readonly _textDocumentsAndEditors: ExtHostDocumentsAndEditors, private readonly _textDocuments: ExtHostDocuments, private readonly _emitter: INotebookEventEmitter, - private readonly _notebookType: string, - private _metadata: Record, readonly uri: URI, - ) { } + data: extHostProtocol.INotebookModelAddedData + ) { + this._notebookType = data.viewType; + this._metadata = data.metadata ?? Object.create(null); + this._spliceNotebookCells([[0, 0, data.cells]], true /* init -> no event*/); + this._versionId = data.versionId; + } dispose() { this._disposed = true; @@ -191,32 +198,34 @@ export class ExtHostNotebookDocument { this._backup = undefined; } - acceptDocumentPropertiesChanged(data: INotebookDocumentPropertiesChangeData) { + acceptDocumentPropertiesChanged(data: extHostProtocol.INotebookDocumentPropertiesChangeData) { if (data.metadata) { this._metadata = { ...this._metadata, ...data.metadata }; } } - acceptModelChanged(event: NotebookCellsChangedEventDto, isDirty: boolean): void { + acceptDirty(isDirty: boolean): void { + this._isDirty = isDirty; + } + + acceptModelChanged(event: extHostProtocol.NotebookCellsChangedEventDto, isDirty: boolean): void { this._versionId = event.versionId; this._isDirty = isDirty; for (const rawEvent of event.rawEvents) { - if (rawEvent.kind === NotebookCellsChangeType.Initialize) { - this._spliceNotebookCells(rawEvent.changes, true); - } if (rawEvent.kind === NotebookCellsChangeType.ModelChange) { + if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.ModelChange) { this._spliceNotebookCells(rawEvent.changes, false); - } else if (rawEvent.kind === NotebookCellsChangeType.Move) { + } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.Move) { this._moveCell(rawEvent.index, rawEvent.newIdx); - } else if (rawEvent.kind === NotebookCellsChangeType.Output) { + } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.Output) { this._setCellOutputs(rawEvent.index, rawEvent.outputs); - } else if (rawEvent.kind === NotebookCellsChangeType.OutputItem) { + } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.OutputItem) { this._setCellOutputItems(rawEvent.index, rawEvent.outputId, rawEvent.append, rawEvent.outputItems); - } else if (rawEvent.kind === NotebookCellsChangeType.ChangeLanguage) { + } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.ChangeLanguage) { this._changeCellLanguage(rawEvent.index, rawEvent.language); - } else if (rawEvent.kind === NotebookCellsChangeType.ChangeCellMetadata) { + } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.ChangeCellMetadata) { this._changeCellMetadata(rawEvent.index, rawEvent.metadata); - } else if (rawEvent.kind === NotebookCellsChangeType.ChangeCellInternalMetadata) { + } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.ChangeCellInternalMetadata) { this._changeCellInternalMetadata(rawEvent.index, rawEvent.internalMetadata); } } @@ -261,7 +270,7 @@ export class ExtHostNotebookDocument { return this._proxy.$trySaveNotebook(this.uri); } - private _spliceNotebookCells(splices: NotebookCellsSplice2[], initialization: boolean): void { + private _spliceNotebookCells(splices: notebookCommon.NotebookCellTextModelSplice[], initialization: boolean): void { if (this._disposed) { return; } @@ -317,13 +326,13 @@ export class ExtHostNotebookDocument { })); } - private _setCellOutputs(index: number, outputs: IOutputDto[]): void { + private _setCellOutputs(index: number, outputs: extHostProtocol.NotebookOutputDto[]): void { const cell = this._cells[index]; cell.setOutputs(outputs); this._emitter.emitCellOutputsChange(deepFreeze({ document: this.apiNotebook, cells: [cell.apiCell] })); } - private _setCellOutputItems(index: number, outputId: string, append: boolean, outputItems: IOutputItemDto[]): void { + private _setCellOutputItems(index: number, outputId: string, append: boolean, outputItems: extHostProtocol.NotebookOutputItemDto[]): void { const cell = this._cells[index]; cell.setOutputItems(outputId, append, outputItems); this._emitter.emitCellOutputsChange(deepFreeze({ document: this.apiNotebook, cells: [cell.apiCell] })); @@ -336,7 +345,7 @@ export class ExtHostNotebookDocument { } } - private _changeCellMetadata(index: number, newMetadata: NotebookCellMetadata): void { + private _changeCellMetadata(index: number, newMetadata: notebookCommon.NotebookCellMetadata): void { const cell = this._cells[index]; const originalExtMetadata = cell.apiCell.metadata; @@ -348,7 +357,7 @@ export class ExtHostNotebookDocument { } } - private _changeCellInternalMetadata(index: number, newInternalMetadata: NotebookCellInternalMetadata): void { + private _changeCellInternalMetadata(index: number, newInternalMetadata: notebookCommon.NotebookCellInternalMetadata): void { const cell = this._cells[index]; const originalInternalMetadata = cell.internalMetadata; diff --git a/src/vs/workbench/api/common/extHostNotebookDocuments.ts b/src/vs/workbench/api/common/extHostNotebookDocuments.ts index b5db1c40fa7..c4c22029379 100644 --- a/src/vs/workbench/api/common/extHostNotebookDocuments.ts +++ b/src/vs/workbench/api/common/extHostNotebookDocuments.ts @@ -6,12 +6,11 @@ import { Emitter } from 'vs/base/common/event'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ILogService } from 'vs/platform/log/common/log'; -import { ExtHostNotebookDocumentsShape, INotebookDocumentPropertiesChangeData } from 'vs/workbench/api/common/extHost.protocol'; +import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook'; -import { NotebookCellsChangedEventDto } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import type * as vscode from 'vscode'; -export class ExtHostNotebookDocuments implements ExtHostNotebookDocumentsShape { +export class ExtHostNotebookDocuments implements extHostProtocol.ExtHostNotebookDocumentsShape { private readonly _onDidChangeNotebookDocumentMetadata = new Emitter(); readonly onDidChangeNotebookDocumentMetadata = this._onDidChangeNotebookDocumentMetadata.event; @@ -24,14 +23,14 @@ export class ExtHostNotebookDocuments implements ExtHostNotebookDocumentsShape { private readonly _notebooksAndEditors: ExtHostNotebookController, ) { } - $acceptModelChanged(uri: UriComponents, event: NotebookCellsChangedEventDto, isDirty: boolean): void { + $acceptModelChanged(uri: UriComponents, event: extHostProtocol.NotebookCellsChangedEventDto, isDirty: boolean): void { const document = this._notebooksAndEditors.getNotebookDocument(URI.revive(uri)); document.acceptModelChanged(event, isDirty); } $acceptDirtyStateChanged(uri: UriComponents, isDirty: boolean): void { const document = this._notebooksAndEditors.getNotebookDocument(URI.revive(uri)); - document.acceptModelChanged({ rawEvents: [], versionId: document.apiNotebook.version }, isDirty); + document.acceptDirty(isDirty); } $acceptModelSaved(uri: UriComponents): void { @@ -39,7 +38,7 @@ export class ExtHostNotebookDocuments implements ExtHostNotebookDocumentsShape { this._onDidSaveNotebookDocument.fire(document.apiNotebook); } - $acceptDocumentPropertiesChanged(uri: UriComponents, data: INotebookDocumentPropertiesChangeData): void { + $acceptDocumentPropertiesChanged(uri: UriComponents, data: extHostProtocol.INotebookDocumentPropertiesChangeData): void { this._logService.debug('ExtHostNotebook#$acceptDocumentPropertiesChanged', uri.path, data); const document = this._notebooksAndEditors.getNotebookDocument(URI.revive(uri)); document.acceptDocumentPropertiesChanged(data); diff --git a/src/vs/workbench/api/common/extHostNotebookEditor.ts b/src/vs/workbench/api/common/extHostNotebookEditor.ts index 479d1469902..3b1a53197b3 100644 --- a/src/vs/workbench/api/common/extHostNotebookEditor.ts +++ b/src/vs/workbench/api/common/extHostNotebookEditor.ts @@ -3,17 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { MainThreadNotebookEditorsShape } from 'vs/workbench/api/common/extHost.protocol'; +import { ICellEditOperationDto, MainThreadNotebookEditorsShape } from 'vs/workbench/api/common/extHost.protocol'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; import * as extHostConverter from 'vs/workbench/api/common/extHostTypeConverters'; -import { CellEditType, ICellEditOperation, ICellReplaceEdit } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import * as vscode from 'vscode'; import { ExtHostNotebookDocument } from './extHostNotebookDocument'; import { illegalArgument } from 'vs/base/common/errors'; interface INotebookEditData { documentVersionId: number; - cellEdits: ICellEditOperation[]; + cellEdits: ICellEditOperationDto[]; } class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit { @@ -21,7 +21,7 @@ class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit { private readonly _documentVersionId: number; private _finalized: boolean = false; - private _collectedEdits: ICellEditOperation[] = []; + private _collectedEdits: ICellEditOperationDto[] = []; constructor(documentVersionId: number) { this._documentVersionId = documentVersionId; @@ -52,7 +52,7 @@ class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit { replaceCellMetadata(index: number, metadata: Record): void { this._throwIfFinalized(); this._collectedEdits.push({ - editType: CellEditType.Metadata, + editType: CellEditType.PartialMetadata, index, metadata }); @@ -174,7 +174,7 @@ export class ExtHostNotebookEditor { return Promise.resolve(true); } - const compressedEdits: ICellEditOperation[] = []; + const compressedEdits: ICellEditOperationDto[] = []; let compressedEditsIndex = -1; for (let i = 0; i < editData.cellEdits.length; i++) { @@ -190,8 +190,8 @@ export class ExtHostNotebookEditor { const edit = editData.cellEdits[i]; if (prev.editType === CellEditType.Replace && edit.editType === CellEditType.Replace) { if (prev.index === edit.index) { - prev.cells.push(...(editData.cellEdits[i] as ICellReplaceEdit).cells); - prev.count += (editData.cellEdits[i] as ICellReplaceEdit).count; + prev.cells.push(...(editData.cellEdits[i] as any).cells); + prev.count += (editData.cellEdits[i] as any).count; continue; } } diff --git a/src/vs/workbench/api/common/extHostNotebookKernels.ts b/src/vs/workbench/api/common/extHostNotebookKernels.ts index 142a8099360..91f25c7b7d9 100644 --- a/src/vs/workbench/api/common/extHostNotebookKernels.ts +++ b/src/vs/workbench/api/common/extHostNotebookKernels.ts @@ -5,7 +5,7 @@ import { Emitter } from 'vs/base/common/event'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { ExtHostNotebookKernelsShape, IMainContext, INotebookKernelDto2, MainContext, MainThreadNotebookKernelsShape } from 'vs/workbench/api/common/extHost.protocol'; +import { CellExecuteEditDto, ExtHostNotebookKernelsShape, IMainContext, INotebookKernelDto2, MainContext, MainThreadNotebookKernelsShape, NotebookOutputDto } from 'vs/workbench/api/common/extHost.protocol'; import * as vscode from 'vscode'; import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; @@ -16,7 +16,7 @@ import { asWebviewUri } from 'vs/workbench/api/common/shared/webview'; import { ResourceMap } from 'vs/base/common/map'; import { timeout } from 'vs/base/common/async'; import { ExtHostCell, ExtHostNotebookDocument } from 'vs/workbench/api/common/extHostNotebookDocument'; -import { CellEditType, IImmediateCellEditOperation, IOutputDto, NotebookCellExecutionState, NullablePartialNotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType, NotebookCellExecutionState, NullablePartialNotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { asArray } from 'vs/base/common/arrays'; import { ILogService } from 'vs/platform/log/common/log'; @@ -332,7 +332,7 @@ class NotebookCellExecutionTask extends Disposable { private readonly _tokenSource = this._register(new CancellationTokenSource()); - private readonly _collector: TimeoutBasedCollector; + private readonly _collector: TimeoutBasedCollector; private _executionOrder: number | undefined; @@ -356,11 +356,11 @@ class NotebookCellExecutionTask extends Disposable { this._tokenSource.cancel(); } - private async applyEditSoon(edit: IImmediateCellEditOperation): Promise { + private async applyEditSoon(edit: CellExecuteEditDto): Promise { await this._collector.addItem(edit); } - private async applyEdits(edits: IImmediateCellEditOperation[]): Promise { + private async applyEdits(edits: CellExecuteEditDto[]): Promise { return this._proxy.$applyExecutionEdits(this._document.uri, edits); } @@ -375,8 +375,11 @@ class NotebookCellExecutionTask extends Disposable { } private mixinMetadata(mixinMetadata: NullablePartialNotebookCellInternalMetadata) { - const edit: IImmediateCellEditOperation = { editType: CellEditType.PartialInternalMetadata, handle: this._cell.handle, internalMetadata: mixinMetadata }; - this.applyEdits([edit]); + this.applyEdits([{ + editType: CellEditType.PartialInternalMetadata, + handle: this._cell.handle, + internalMetadata: mixinMetadata + }]); } private cellIndexToHandle(cellOrCellIndex: vscode.NotebookCell | undefined): number { @@ -390,7 +393,7 @@ class NotebookCellExecutionTask extends Disposable { return cell.handle; } - private validateAndConvertOutputs(items: vscode.NotebookCellOutput[]): IOutputDto[] { + private validateAndConvertOutputs(items: vscode.NotebookCellOutput[]): NotebookOutputDto[] { return items.map(output => { const newOutput = NotebookCellOutput.ensureUniqueMimeTypes(output.items, true); if (newOutput === output.items) { diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index c5b64e74910..f17a1b750ff 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -548,33 +548,6 @@ export namespace WorkspaceEdit { notebookVersionId: extHostNotebooks?.getNotebookDocument(entry.uri, true)?.apiNotebook.version }); - } else if (entry._type === types.FileEditType.CellOutput) { - if (entry.newOutputs) { - result.edits.push({ - _type: extHostProtocol.WorkspaceEditType.Cell, - metadata: entry.metadata, - resource: entry.uri, - edit: { - editType: notebooks.CellEditType.Output, - index: entry.index, - append: entry.append, - outputs: entry.newOutputs.map(NotebookCellOutput.from) - } - }); - } - // todo@joh merge metadata and output edit? - if (entry.newMetadata) { - result.edits.push({ - _type: extHostProtocol.WorkspaceEditType.Cell, - metadata: entry.metadata, - resource: entry.uri, - edit: { - editType: notebooks.CellEditType.PartialMetadata, - index: entry.index, - metadata: entry.newMetadata - } - }); - } } else if (entry._type === types.FileEditType.CellReplace) { result.edits.push({ _type: extHostProtocol.WorkspaceEditType.Cell, @@ -588,18 +561,6 @@ export namespace WorkspaceEdit { cells: entry.cells.map(NotebookCellData.from) } }); - } else if (entry._type === types.FileEditType.CellOutputItem) { - result.edits.push({ - _type: extHostProtocol.WorkspaceEditType.Cell, - metadata: entry.metadata, - resource: entry.uri, - edit: { - editType: notebooks.CellEditType.OutputItems, - outputId: entry.outputId, - items: entry.newOutputItems?.map(NotebookCellOutputItem.from) || [], - append: entry.append - } - }); } } } @@ -1458,8 +1419,8 @@ export namespace NotebookCellKind { export namespace NotebookData { - export function from(data: vscode.NotebookData): notebooks.NotebookDataDto { - const res: notebooks.NotebookDataDto = { + export function from(data: vscode.NotebookData): extHostProtocol.NotebookDataDto { + const res: extHostProtocol.NotebookDataDto = { metadata: data.metadata ?? Object.create(null), cells: [], }; @@ -1470,7 +1431,7 @@ export namespace NotebookData { return res; } - export function to(data: notebooks.NotebookDataDto): vscode.NotebookData { + export function to(data: extHostProtocol.NotebookDataDto): vscode.NotebookData { const res = new types.NotebookData( data.cells.map(NotebookCellData.to), ); @@ -1483,7 +1444,7 @@ export namespace NotebookData { export namespace NotebookCellData { - export function from(data: vscode.NotebookCellData): notebooks.ICellDto2 { + export function from(data: vscode.NotebookCellData): extHostProtocol.NotebookCellDataDto { return { cellKind: NotebookCellKind.from(data.kind), language: data.languageId, @@ -1494,7 +1455,7 @@ export namespace NotebookCellData { }; } - export function to(data: notebooks.ICellDto2): vscode.NotebookCellData { + export function to(data: extHostProtocol.NotebookCellDataDto): vscode.NotebookCellData { return new types.NotebookCellData( NotebookCellKind.to(data.cellKind), data.source, @@ -1507,29 +1468,29 @@ export namespace NotebookCellData { } export namespace NotebookCellOutputItem { - export function from(item: types.NotebookCellOutputItem): notebooks.IOutputItemDto { + export function from(item: types.NotebookCellOutputItem): extHostProtocol.NotebookOutputItemDto { return { mime: item.mime, valueBytes: Array.from(item.data), //todo@jrieken this HACKY and SLOW... hoist VSBuffer instead }; } - export function to(item: notebooks.IOutputItemDto): types.NotebookCellOutputItem { + export function to(item: extHostProtocol.NotebookOutputItemDto): types.NotebookCellOutputItem { return new types.NotebookCellOutputItem(new Uint8Array(item.valueBytes), item.mime); } } export namespace NotebookCellOutput { - export function from(output: vscode.NotebookCellOutput): notebooks.IOutputDto { + export function from(output: vscode.NotebookCellOutput): extHostProtocol.NotebookOutputDto { return { outputId: output.id, - outputs: output.items.map(NotebookCellOutputItem.from), + items: output.items.map(NotebookCellOutputItem.from), metadata: output.metadata }; } - export function to(output: notebooks.IOutputDto): vscode.NotebookCellOutput { - const items = output.outputs.map(NotebookCellOutputItem.to); + export function to(output: extHostProtocol.NotebookOutputDto): vscode.NotebookCellOutput { + const items = output.items.map(NotebookCellOutputItem.to); return new types.NotebookCellOutput(items, output.outputId, output.metadata); } } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index ed30c969a70..42f29f0a2e7 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -15,7 +15,7 @@ import { generateUuid } from 'vs/base/common/uuid'; import { FileSystemProviderErrorCode, markAsFileSystemProviderError } from 'vs/platform/files/common/files'; import { RemoteAuthorityResolverErrorCode } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { getPrivateApiFor, ExtHostTestItemEventType, IExtHostTestItemApi } from 'vs/workbench/api/common/extHostTestingPrivateApi'; -import { CellEditType, ICellEditOperation } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType, ICellPartialMetadataEdit, IDocumentMetadataEdit } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import type * as vscode from 'vscode'; function es5ClassCompat(target: Function): any { @@ -588,9 +588,7 @@ export const enum FileEditType { File = 1, Text = 2, Cell = 3, - CellOutput = 4, CellReplace = 5, - CellOutputItem = 6 } export interface IFileOperation { @@ -611,7 +609,7 @@ export interface IFileTextEdit { export interface IFileCellEdit { _type: FileEditType.Cell; uri: URI; - edit?: ICellEditOperation; + edit?: ICellPartialMetadataEdit | IDocumentMetadataEdit; notebookMetadata?: Record; metadata?: vscode.WorkspaceEditEntryMetadata; } @@ -625,28 +623,8 @@ export interface ICellEdit { cells: vscode.NotebookCellData[]; } -export interface ICellOutputEdit { - _type: FileEditType.CellOutput; - uri: URI; - index: number; - append: boolean; - newOutputs?: NotebookCellOutput[]; - newMetadata?: Record; - metadata?: vscode.WorkspaceEditEntryMetadata; -} -export interface ICellOutputItemsEdit { - _type: FileEditType.CellOutputItem; - uri: URI; - index: number; - outputId: string; - append: boolean; - newOutputItems?: NotebookCellOutputItem[]; - metadata?: vscode.WorkspaceEditEntryMetadata; -} - - -type WorkspaceEditEntry = IFileOperation | IFileTextEdit | IFileCellEdit | ICellEdit | ICellOutputEdit | ICellOutputItemsEdit; +type WorkspaceEditEntry = IFileOperation | IFileTextEdit | IFileCellEdit | ICellEdit; @es5ClassCompat export class WorkspaceEdit implements vscode.WorkspaceEdit { diff --git a/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts index 394678a8dc4..2fed10ed6cd 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts @@ -32,7 +32,7 @@ import { INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/no import { NotebookDiffEditorInput } from 'vs/workbench/contrib/notebook/browser/notebookDiffEditorInput'; import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; -import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, BUILTIN_RENDERER_ID, CellUri, DisplayOrderKey, INotebookExclusiveDocumentFilter, INotebookContributionData, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, IOutputDto, mimeTypeIsAlwaysSecure, mimeTypeSupportedByCore, NotebookDataDto, NotebookEditorPriority, NotebookRendererMatch, NotebookTextDiffEditorPreview, RENDERER_NOT_AVAILABLE, sortMimeTypes, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, BUILTIN_RENDERER_ID, CellUri, DisplayOrderKey, INotebookExclusiveDocumentFilter, INotebookContributionData, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, IOutputDto, mimeTypeIsAlwaysSecure, mimeTypeSupportedByCore, NotebookData, NotebookEditorPriority, NotebookRendererMatch, NotebookTextDiffEditorPreview, RENDERER_NOT_AVAILABLE, sortMimeTypes, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput'; import { updateEditorTopPadding } from 'vs/workbench/contrib/notebook/common/notebookOptions'; import { NotebookOutputRendererInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer'; @@ -540,7 +540,7 @@ export class NotebookService extends Disposable implements INotebookService { // --- notebook documents: create, destory, retrieve, enumerate - createNotebookTextModel(viewType: string, uri: URI, data: NotebookDataDto, transientOptions: TransientOptions): NotebookTextModel { + createNotebookTextModel(viewType: string, uri: URI, data: NotebookData, transientOptions: TransientOptions): NotebookTextModel { if (this._models.has(uri)) { throw new Error(`notebook for ${uri} already exists`); } diff --git a/src/vs/workbench/contrib/notebook/browser/view/output/transforms/richTransform.ts b/src/vs/workbench/contrib/notebook/browser/view/output/transforms/richTransform.ts index 5f55e4926fe..d40252bbb03 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/output/transforms/richTransform.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/output/transforms/richTransform.ts @@ -310,8 +310,7 @@ class ImgRendererContrib extends Disposable implements IOutputRendererContributi render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement, notebookUri: URI): IRenderOutput { const disposable = new DisposableStore(); - const bytes = new Uint8Array(item.valueBytes); - const blob = new Blob([bytes], { type: item.mime }); + const blob = new Blob([item.data], { type: item.mime }); const src = URL.createObjectURL(blob); disposable.add(toDisposable(() => URL.revokeObjectURL(src))); @@ -340,7 +339,7 @@ OutputRendererRegistry.registerOutputTransform(StderrRendererContrib); // --- utils --- function getStringValue(item: IOutputItemDto): string { // todo@jrieken NOT proper, should be VSBuffer - return new TextDecoder().decode(new Uint8Array(item.valueBytes)); + return new TextDecoder().decode(item.data); } function getOutputSimpleEditorOptions(): IEditorConstructionOptions { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index 6d267dcabe4..4046b299395 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1015,9 +1015,9 @@ var requirejs = (function() { if (content.type === RenderOutputType.Extension) { const output = content.source.model; renderer = content.renderer; - const outputDto = output.outputs.find(op => op.mime === content.mimeType); + const first = output.outputs.find(op => op.mime === content.mimeType)!; - // TODO@notebook - the message can contain "bytes" and those are transferable + // TODO@jrieken - the message can contain "bytes" and those are transferable // which improves IPC performance and therefore should be used. However, it does // means that the bytes cannot be used here anymore message = { @@ -1027,10 +1027,9 @@ var requirejs = (function() { content: { type: RenderOutputType.Extension, outputId: output.outputId, - mimeType: content.mimeType, - valueBytes: new Uint8Array(outputDto?.valueBytes ?? []), + mimeType: first.mime, + valueBytes: first.data, metadata: output.metadata, - metadata2: output.metadata }, }; } else { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts index 78fc3ff7654..3229217f037 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts @@ -162,7 +162,7 @@ export interface IOutputRequestDto { export interface ICreationRequestMessage { readonly type: 'html'; readonly content: { type: RenderOutputType.Html; htmlContent: string; } | - { type: RenderOutputType.Extension; outputId: string; valueBytes: Uint8Array; metadata: unknown; metadata2: unknown; mimeType: string; }; + { type: RenderOutputType.Extension; outputId: string; valueBytes: Uint8Array; metadata: unknown; mimeType: string; }; readonly cellId: string; readonly outputId: string; cellTop: number; diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 2e6964f9de6..3f2620b98af 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -469,7 +469,6 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re readonly mime: string; metadata: unknown; - metadata2: unknown; text(): string; json(): any; @@ -616,7 +615,6 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re element: outputNode, mime: content.mimeType, metadata: content.metadata, - metadata2: content.metadata2, data() { return content.valueBytes; }, @@ -1117,7 +1115,6 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re // deprecated fields public readonly metadata = undefined; - public readonly metadata2 = undefined; public readonly outputId?: string | undefined; text() { return this._content; } diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 78cb628688a..d6ee63a642a 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -170,7 +170,7 @@ export interface IOrderedMimeType { export interface IOutputItemDto { readonly mime: string; - readonly valueBytes: number[]; + readonly data: Uint8Array; } export interface IOutputDto { @@ -469,7 +469,7 @@ export interface ICellMoveEdit { export type IImmediateCellEditOperation = ICellOutputEditByHandle | ICellPartialMetadataEditByHandle | ICellOutputItemEdit | ICellPartialInternalMetadataEdit | ICellPartialInternalMetadataEditByHandle | ICellPartialMetadataEdit; export type ICellEditOperation = IImmediateCellEditOperation | ICellReplaceEdit | ICellOutputEdit | ICellMetadataEdit | ICellPartialMetadataEdit | ICellPartialInternalMetadataEdit | IDocumentMetadataEdit | ICellMoveEdit | ICellOutputItemEdit | ICellLanguageEdit; -export interface NotebookDataDto { +export interface NotebookData { readonly cells: ICellDto2[]; readonly metadata: NotebookDocumentMetadata; } diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts index 9dcd7ea0826..ef85a11f661 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { IEditorInput, IRevertOptions, ISaveOptions } from 'vs/workbench/common/editor'; import { EditorModel } from 'vs/workbench/common/editor/editorModel'; import { Emitter, Event } from 'vs/base/common/event'; -import { ICellDto2, INotebookEditorModel, INotebookLoadOptions, IResolvedNotebookEditorModel, NotebookCellsChangeType, NotebookDataDto, NotebookDocumentBackupData } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { ICellDto2, INotebookEditorModel, INotebookLoadOptions, IResolvedNotebookEditorModel, NotebookCellsChangeType, NotebookData, NotebookDocumentBackupData } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; import { INotebookContentProvider, INotebookSerializer, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService'; import { URI } from 'vs/base/common/uri'; @@ -578,7 +578,7 @@ export class NotebookFileWorkingCopyModel implements IStoredFileWorkingCopyModel async snapshot(token: CancellationToken): Promise { - const data: NotebookDataDto = { + const data: NotebookData = { metadata: filter(this._notebookModel.metadata, key => !this._notebookSerializer.options.transientDocumentMetadata[key]), cells: [], }; diff --git a/src/vs/workbench/contrib/notebook/common/notebookService.ts b/src/vs/workbench/contrib/notebook/common/notebookService.ts index 0f3b5dd9f37..1293aa0b491 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookService.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookService.ts @@ -8,7 +8,7 @@ import { URI } from 'vs/base/common/uri'; import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider'; import { NotebookExtensionDescription } from 'vs/workbench/api/common/extHost.protocol'; import { Event } from 'vs/base/common/event'; -import { INotebookRendererInfo, NotebookDataDto, TransientOptions, IOrderedMimeType, IOutputDto, INotebookContributionData } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { INotebookRendererInfo, NotebookData, TransientOptions, IOrderedMimeType, IOutputDto, INotebookContributionData } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; import { CancellationToken } from 'vs/base/common/cancellation'; import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; @@ -21,7 +21,7 @@ export const INotebookService = createDecorator('notebookServi export interface INotebookContentProvider { options: TransientOptions; - open(uri: URI, backupId: string | undefined, untitledDocumentData: VSBuffer | undefined, token: CancellationToken): Promise<{ data: NotebookDataDto, transientOptions: TransientOptions; }>; + open(uri: URI, backupId: string | undefined, untitledDocumentData: VSBuffer | undefined, token: CancellationToken): Promise<{ data: NotebookData, transientOptions: TransientOptions; }>; save(uri: URI, token: CancellationToken): Promise; saveAs(uri: URI, target: URI, token: CancellationToken): Promise; backup(uri: URI, token: CancellationToken): Promise; @@ -29,12 +29,12 @@ export interface INotebookContentProvider { export interface INotebookSerializer { options: TransientOptions; - dataToNotebook(data: VSBuffer): Promise - notebookToData(data: NotebookDataDto): Promise; + dataToNotebook(data: VSBuffer): Promise + notebookToData(data: NotebookData): Promise; } export interface INotebookRawData { - data: NotebookDataDto; + data: NotebookData; transientOptions: TransientOptions; } @@ -78,7 +78,7 @@ export interface INotebookService { /** Updates the preferred renderer for the given mimetype in the workspace. */ updateMimePreferredRenderer(mimeType: string, rendererId: string): void; - createNotebookTextModel(viewType: string, uri: URI, data: NotebookDataDto, transientOptions: TransientOptions): NotebookTextModel; + createNotebookTextModel(viewType: string, uri: URI, data: NotebookData, transientOptions: TransientOptions): NotebookTextModel; getNotebookTextModel(uri: URI): NotebookTextModel | undefined; getNotebookTextModels(): Iterable; listNotebookDocuments(): readonly NotebookTextModel[]; diff --git a/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts b/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts index 01f1b0a09b5..b8ec9954c65 100644 --- a/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts +++ b/src/vs/workbench/contrib/notebook/common/services/notebookSimpleWorker.ts @@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri'; import { IRequestHandler } from 'vs/base/common/worker/simpleWorker'; import * as model from 'vs/editor/common/model'; import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder'; -import { CellKind, ICellDto2, IMainCellDto, INotebookDiffResult, IOutputDto, NotebookCellInternalMetadata, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookCellsSplice2, NotebookDataDto, NotebookDocumentMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellKind, ICellDto2, IMainCellDto, INotebookDiffResult, IOutputDto, NotebookCellInternalMetadata, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookCellsSplice2, NotebookData, NotebookDocumentMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { Range } from 'vs/editor/common/core/range'; import { EditorWorkerHost } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerServiceImpl'; @@ -173,7 +173,7 @@ export class NotebookEditorSimpleWorker implements IRequestHandler, IDisposable dispose(): void { } - public acceptNewModel(uri: string, data: NotebookDataDto): void { + public acceptNewModel(uri: string, data: NotebookData): void { this._models[uri] = new MirrorNotebookDocument(URI.parse(uri), data.cells.map(dto => new MirrorCell( (dto as unknown as IMainCellDto).handle, dto.source, diff --git a/src/vs/workbench/contrib/notebook/test/notebookDiff.test.ts b/src/vs/workbench/contrib/notebook/test/notebookDiff.test.ts index 3e612b388c9..70ab2ffaecf 100644 --- a/src/vs/workbench/contrib/notebook/test/notebookDiff.test.ts +++ b/src/vs/workbench/contrib/notebook/test/notebookDiff.test.ts @@ -14,9 +14,9 @@ suite('NotebookCommon', () => { test('diff different source', async () => { await withTestNotebookDiffModel([ - ['x', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: 'text/plain', valueBytes: [3] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }], + ['x', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }], ], [ - ['y', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: 'text/plain', valueBytes: [3] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }], + ['y', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }], ], (model, accessor) => { const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook)); const diffResult = diff.ComputeDiff(false); @@ -44,10 +44,10 @@ suite('NotebookCommon', () => { test('diff different output', async () => { await withTestNotebookDiffModel([ - ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [5] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }], + ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([5]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }], ['', 'javascript', CellKind.Code, [], {}] ], [ - ['x', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: 'text/plain', valueBytes: [3] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }], + ['x', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }], ['', 'javascript', CellKind.Code, [], {}] ], (model, accessor) => { const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook)); @@ -145,12 +145,12 @@ suite('NotebookCommon', () => { test('diff foo/foe', async () => { await withTestNotebookDiffModel([ - [['def foe(x, y):\n', ' return x + y\n', 'foe(3, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [6] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }], - [['def foo(x, y):\n', ' return x * y\n', 'foo(1, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [2] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 6 }], + [['def foe(x, y):\n', ' return x + y\n', 'foe(3, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([6]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }], + [['def foo(x, y):\n', ' return x * y\n', 'foo(1, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([2]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 6 }], ['', 'javascript', CellKind.Code, [], {}] ], [ - [['def foo(x, y):\n', ' return x * y\n', 'foo(1, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [6] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }], - [['def foe(x, y):\n', ' return x + y\n', 'foe(3, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [2] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 6 }], + [['def foo(x, y):\n', ' return x * y\n', 'foo(1, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([6]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }], + [['def foe(x, y):\n', ' return x + y\n', 'foe(3, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([2]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 6 }], ['', 'javascript', CellKind.Code, [], {}] ], (model, accessor) => { const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook)); @@ -272,13 +272,13 @@ suite('NotebookCommon', () => { await withTestNotebookDiffModel([ ['# Description', 'markdown', CellKind.Markup, [], { custom: { metadata: {} } }], ['x = 3', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: true } }, executionOrder: 1 }], - ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [3] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }], + ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }], ['x', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: false } } }] ], [ ['# Description', 'markdown', CellKind.Markup, [], { custom: { metadata: {} } }], ['x = 3', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: true } }, executionOrder: 1 }], ['x', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: false } } }], - ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [3] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }] + ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }] ], async (model) => { const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook)); const diffResult = diff.ComputeDiff(false); @@ -305,18 +305,18 @@ suite('NotebookCommon', () => { await withTestNotebookDiffModel([ ['# Description', 'markdown', CellKind.Markup, [], { custom: { metadata: {} } }], ['x = 3', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: true } }, executionOrder: 1 }], - ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [3] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }], + ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }], ['x', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: false } } }], ['x = 5', 'javascript', CellKind.Code, [], {}], ['x', 'javascript', CellKind.Code, [], {}], - ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [5] }] }], {}], + ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([5]) }] }], {}], ], [ ['# Description', 'markdown', CellKind.Markup, [], { custom: { metadata: {} } }], ['x = 3', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: true } }, executionOrder: 1 }], ['x', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: false } } }], - ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [3] }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }], + ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }], ['x = 5', 'javascript', CellKind.Code, [], {}], - ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', valueBytes: [5] }] }], {}], + ['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([5]) }] }], {}], ['x', 'javascript', CellKind.Code, [], {}], ], async (model) => { const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook)); diff --git a/src/vs/workbench/contrib/notebook/test/notebookEditorModel.test.ts b/src/vs/workbench/contrib/notebook/test/notebookEditorModel.test.ts index af1be838a68..664ae0b0957 100644 --- a/src/vs/workbench/contrib/notebook/test/notebookEditorModel.test.ts +++ b/src/vs/workbench/contrib/notebook/test/notebookEditorModel.test.ts @@ -21,7 +21,7 @@ import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/commo import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopy'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; -import { CellKind, NotebookDataDto, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellKind, NotebookData, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { setupInstantiationService } from 'vs/workbench/contrib/notebook/test/testNotebookEditor'; import { VSBuffer } from 'vs/base/common/buffer'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -46,7 +46,7 @@ suite('NotebookFileWorkingCopyModel', function () { notebook, new class extends mock() { override options: TransientOptions = { transientOutputs: true, transientCellMetadata: {}, transientDocumentMetadata: {} }; - override async notebookToData(notebook: NotebookDataDto) { + override async notebookToData(notebook: NotebookData) { callCount += 1; assert.strictEqual(notebook.cells.length, 1); assert.strictEqual(notebook.cells[0].outputs.length, 0); @@ -65,7 +65,7 @@ suite('NotebookFileWorkingCopyModel', function () { notebook, new class extends mock() { override options: TransientOptions = { transientOutputs: false, transientCellMetadata: {}, transientDocumentMetadata: {} }; - override async notebookToData(notebook: NotebookDataDto) { + override async notebookToData(notebook: NotebookData) { callCount += 1; assert.strictEqual(notebook.cells.length, 1); assert.strictEqual(notebook.cells[0].outputs.length, 1); @@ -94,7 +94,7 @@ suite('NotebookFileWorkingCopyModel', function () { notebook, new class extends mock() { override options: TransientOptions = { transientOutputs: true, transientCellMetadata: {}, transientDocumentMetadata: { bar: true } }; - override async notebookToData(notebook: NotebookDataDto) { + override async notebookToData(notebook: NotebookData) { callCount += 1; assert.strictEqual(notebook.metadata.foo, 123); assert.strictEqual(notebook.metadata.bar, undefined); @@ -113,7 +113,7 @@ suite('NotebookFileWorkingCopyModel', function () { notebook, new class extends mock() { override options: TransientOptions = { transientOutputs: false, transientCellMetadata: {}, transientDocumentMetadata: {} }; - override async notebookToData(notebook: NotebookDataDto) { + override async notebookToData(notebook: NotebookData) { callCount += 1; assert.strictEqual(notebook.metadata.foo, 123); assert.strictEqual(notebook.metadata.bar, 456); @@ -142,7 +142,7 @@ suite('NotebookFileWorkingCopyModel', function () { notebook, new class extends mock() { override options: TransientOptions = { transientOutputs: true, transientDocumentMetadata: {}, transientCellMetadata: { bar: true } }; - override async notebookToData(notebook: NotebookDataDto) { + override async notebookToData(notebook: NotebookData) { callCount += 1; assert.strictEqual(notebook.cells[0].metadata!.foo, 123); assert.strictEqual(notebook.cells[0].metadata!.bar, undefined); @@ -161,7 +161,7 @@ suite('NotebookFileWorkingCopyModel', function () { notebook, new class extends mock() { override options: TransientOptions = { transientOutputs: false, transientCellMetadata: {}, transientDocumentMetadata: {} }; - override async notebookToData(notebook: NotebookDataDto) { + override async notebookToData(notebook: NotebookData) { callCount += 1; assert.strictEqual(notebook.cells[0].metadata!.foo, 123); assert.strictEqual(notebook.cells[0].metadata!.bar, 456); diff --git a/src/vs/workbench/contrib/notebook/test/notebookTextModel.test.ts b/src/vs/workbench/contrib/notebook/test/notebookTextModel.test.ts index 3e799efe395..39433c04539 100644 --- a/src/vs/workbench/contrib/notebook/test/notebookTextModel.test.ts +++ b/src/vs/workbench/contrib/notebook/test/notebookTextModel.test.ts @@ -12,7 +12,7 @@ import { IModeService } from 'vs/editor/common/services/modeService'; suite('NotebookTextModel', () => { function valueBytesFromString(value: string) { - return Array.from(new TextEncoder().encode(value)); + return new TextEncoder().encode(value); } const instantiationService = setupInstantiationService(); @@ -189,7 +189,7 @@ suite('NotebookTextModel', () => { editType: CellEditType.Output, outputs: [{ outputId: 'someId', - outputs: [{ mime: 'text/markdown', valueBytes: valueBytesFromString('_Hello_') }] + outputs: [{ mime: 'text/markdown', data: valueBytesFromString('_Hello_') }] }] }], true, undefined, () => undefined, undefined); @@ -203,7 +203,7 @@ suite('NotebookTextModel', () => { append: true, outputs: [{ outputId: 'someId2', - outputs: [{ mime: 'text/markdown', valueBytes: valueBytesFromString('_Hello2_') }] + outputs: [{ mime: 'text/markdown', data: valueBytesFromString('_Hello2_') }] }] }], true, undefined, () => undefined, undefined); @@ -219,7 +219,7 @@ suite('NotebookTextModel', () => { editType: CellEditType.Output, outputs: [{ outputId: 'someId3', - outputs: [{ mime: 'text/plain', valueBytes: valueBytesFromString('Last, replaced output') }] + outputs: [{ mime: 'text/plain', data: valueBytesFromString('Last, replaced output') }] }] }], true, undefined, () => undefined, undefined); @@ -247,7 +247,7 @@ suite('NotebookTextModel', () => { append: true, outputs: [{ outputId: 'append1', - outputs: [{ mime: 'text/markdown', valueBytes: valueBytesFromString('append 1') }] + outputs: [{ mime: 'text/markdown', data: valueBytesFromString('append 1') }] }] }, { @@ -256,7 +256,7 @@ suite('NotebookTextModel', () => { append: true, outputs: [{ outputId: 'append2', - outputs: [{ mime: 'text/markdown', valueBytes: valueBytesFromString('append 2') }] + outputs: [{ mime: 'text/markdown', data: valueBytesFromString('append 2') }] }] } ], true, undefined, () => undefined, undefined); @@ -423,7 +423,7 @@ suite('NotebookTextModel', () => { const success1 = model.applyEdits( [{ editType: CellEditType.Output, index: 0, outputs: [ - { outputId: 'out1', outputs: [{ mime: 'application/x.notebook.stream', valueBytes: [1] }] } + { outputId: 'out1', outputs: [{ mime: 'application/x.notebook.stream', data: new Uint8Array([1]) }] } ], append: false }], true, undefined, () => undefined, undefined, false @@ -435,7 +435,7 @@ suite('NotebookTextModel', () => { const success2 = model.applyEdits( [{ editType: CellEditType.Output, index: 0, outputs: [ - { outputId: 'out2', outputs: [{ mime: 'application/x.notebook.stream', valueBytes: [1] }] } + { outputId: 'out2', outputs: [{ mime: 'application/x.notebook.stream', data: new Uint8Array([1]) }] } ], append: true }], true, undefined, () => undefined, undefined, false @@ -462,7 +462,7 @@ suite('NotebookTextModel', () => { const success = model.applyEdits( [{ editType: CellEditType.Output, index: 0, outputs: [ - { outputId: 'out1', outputs: [{ mime: 'application/x.notebook.stream', valueBytes: [1] }] } + { outputId: 'out1', outputs: [{ mime: 'application/x.notebook.stream', data: new Uint8Array([1]) }] } ], append: false }], true, undefined, () => undefined, undefined, false @@ -568,14 +568,14 @@ suite('NotebookTextModel', () => { test('Destructive sorting in _doApplyEdits #121994', async function () { await withTestNotebook([ - ['var a = 1;', 'javascript', CellKind.Code, [{ outputId: 'i42', outputs: [{ mime: 'm/ime', valueBytes: valueBytesFromString('test') }] }], {}] + ['var a = 1;', 'javascript', CellKind.Code, [{ outputId: 'i42', outputs: [{ mime: 'm/ime', data: valueBytesFromString('test') }] }], {}] ], async (editor) => { const notebook = editor.viewModel.notebookDocument; assert.strictEqual(notebook.cells[0].outputs.length, 1); assert.strictEqual(notebook.cells[0].outputs[0].outputs.length, 1); - assert.deepStrictEqual(notebook.cells[0].outputs[0].outputs[0].valueBytes, valueBytesFromString('test')); + assert.deepStrictEqual(notebook.cells[0].outputs[0].outputs[0].data, valueBytesFromString('test')); const edits: ICellEditOperation[] = [ { @@ -584,7 +584,7 @@ suite('NotebookTextModel', () => { { editType: CellEditType.Output, handle: 0, append: true, outputs: [{ outputId: 'newOutput', - outputs: [{ mime: 'text/plain', valueBytes: valueBytesFromString('cba') }, { mime: 'application/foo', valueBytes: valueBytesFromString('cba') }] + outputs: [{ mime: 'text/plain', data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }] }] } ]; @@ -598,9 +598,9 @@ suite('NotebookTextModel', () => { test('Destructive sorting in _doApplyEdits #121994. cell splice between output changes', async function () { await withTestNotebook([ - ['var a = 1;', 'javascript', CellKind.Code, [{ outputId: 'i42', outputs: [{ mime: 'm/ime', valueBytes: valueBytesFromString('test') }] }], {}], - ['var b = 2;', 'javascript', CellKind.Code, [{ outputId: 'i43', outputs: [{ mime: 'm/ime', valueBytes: valueBytesFromString('test') }] }], {}], - ['var c = 3;', 'javascript', CellKind.Code, [{ outputId: 'i44', outputs: [{ mime: 'm/ime', valueBytes: valueBytesFromString('test') }] }], {}] + ['var a = 1;', 'javascript', CellKind.Code, [{ outputId: 'i42', outputs: [{ mime: 'm/ime', data: valueBytesFromString('test') }] }], {}], + ['var b = 2;', 'javascript', CellKind.Code, [{ outputId: 'i43', outputs: [{ mime: 'm/ime', data: valueBytesFromString('test') }] }], {}], + ['var c = 3;', 'javascript', CellKind.Code, [{ outputId: 'i44', outputs: [{ mime: 'm/ime', data: valueBytesFromString('test') }] }], {}] ], async (editor) => { const notebook = editor.viewModel.notebookDocument; @@ -614,7 +614,7 @@ suite('NotebookTextModel', () => { { editType: CellEditType.Output, index: 2, append: true, outputs: [{ outputId: 'newOutput', - outputs: [{ mime: 'text/plain', valueBytes: valueBytesFromString('cba') }, { mime: 'application/foo', valueBytes: valueBytesFromString('cba') }] + outputs: [{ mime: 'text/plain', data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }] }] } ]; @@ -631,9 +631,9 @@ suite('NotebookTextModel', () => { test('Destructive sorting in _doApplyEdits #121994. cell splice between output changes 2', async function () { await withTestNotebook([ - ['var a = 1;', 'javascript', CellKind.Code, [{ outputId: 'i42', outputs: [{ mime: 'm/ime', valueBytes: valueBytesFromString('test') }] }], {}], - ['var b = 2;', 'javascript', CellKind.Code, [{ outputId: 'i43', outputs: [{ mime: 'm/ime', valueBytes: valueBytesFromString('test') }] }], {}], - ['var c = 3;', 'javascript', CellKind.Code, [{ outputId: 'i44', outputs: [{ mime: 'm/ime', valueBytes: valueBytesFromString('test') }] }], {}] + ['var a = 1;', 'javascript', CellKind.Code, [{ outputId: 'i42', outputs: [{ mime: 'm/ime', data: valueBytesFromString('test') }] }], {}], + ['var b = 2;', 'javascript', CellKind.Code, [{ outputId: 'i43', outputs: [{ mime: 'm/ime', data: valueBytesFromString('test') }] }], {}], + ['var c = 3;', 'javascript', CellKind.Code, [{ outputId: 'i44', outputs: [{ mime: 'm/ime', data: valueBytesFromString('test') }] }], {}] ], async (editor) => { const notebook = editor.viewModel.notebookDocument; @@ -641,7 +641,7 @@ suite('NotebookTextModel', () => { { editType: CellEditType.Output, index: 1, append: true, outputs: [{ outputId: 'newOutput', - outputs: [{ mime: 'text/plain', valueBytes: valueBytesFromString('cba') }, { mime: 'application/foo', valueBytes: valueBytesFromString('cba') }] + outputs: [{ mime: 'text/plain', data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }] }] }, { @@ -650,7 +650,7 @@ suite('NotebookTextModel', () => { { editType: CellEditType.Output, index: 1, append: true, outputs: [{ outputId: 'newOutput2', - outputs: [{ mime: 'text/plain', valueBytes: valueBytesFromString('cba') }, { mime: 'application/foo', valueBytes: valueBytesFromString('cba') }] + outputs: [{ mime: 'text/plain', data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }] }] } ]; diff --git a/src/vs/workbench/test/browser/api/extHostNotebookKernel.test.ts b/src/vs/workbench/test/browser/api/extHostNotebookKernel.test.ts index 9275604e665..90292cfe7fb 100644 --- a/src/vs/workbench/test/browser/api/extHostNotebookKernel.test.ts +++ b/src/vs/workbench/test/browser/api/extHostNotebookKernel.test.ts @@ -8,7 +8,7 @@ import { TestRPCProtocol } from 'vs/workbench/test/browser/api/testRPCProtocol'; import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook'; import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { mock } from 'vs/workbench/test/common/workbenchTestServices'; -import { INotebookKernelDto2, MainContext, MainThreadCommandsShape, MainThreadNotebookDocumentsShape, MainThreadNotebookKernelsShape, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol'; +import { CellExecuteEditDto, INotebookKernelDto2, MainContext, MainThreadCommandsShape, MainThreadNotebookDocumentsShape, MainThreadNotebookKernelsShape, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostNotebookKernels } from 'vs/workbench/api/common/extHostNotebookKernels'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; @@ -20,7 +20,7 @@ import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePa import { URI, UriComponents } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; -import { CellEditType, CellKind, CellUri, IImmediateCellEditOperation, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType, CellKind, CellUri, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ExtHostNotebookDocuments } from 'vs/workbench/api/common/extHostNotebookDocuments'; import { NotebookCellOutput, NotebookCellOutputItem } from 'vs/workbench/api/common/extHostTypes'; @@ -40,13 +40,13 @@ suite('NotebookKernel', function () { const kernelData = new Map(); const disposables = new DisposableStore(); - const edits: IImmediateCellEditOperation[] = []; + const cellExecuteEdits: CellExecuteEditDto[] = []; teardown(function () { disposables.clear(); }); setup(async function () { - edits.length = 0; + cellExecuteEdits.length = 0; kernelData.clear(); rpcProtocol = new TestRPCProtocol(); @@ -64,8 +64,8 @@ suite('NotebookKernel', function () { assert.strictEqual(kernelData.has(handle), true); kernelData.set(handle, { ...kernelData.get(handle)!, ...data, }); } - override async $applyExecutionEdits(resource: UriComponents, _edits: IImmediateCellEditOperation[]) { - edits.push(..._edits); + override async $applyExecutionEdits(resource: UriComponents, _edits: CellExecuteEditDto[]) { + cellExecuteEdits.push(..._edits); } }); rpcProtocol.set(MainContext.MainThreadNotebookDocuments, new class extends mock() { @@ -257,20 +257,20 @@ suite('NotebookKernel', function () { task.end(true); }); - edits.length = 0; + cellExecuteEdits.length = 0; await extHostNotebookKernels.$cancelCells(0, notebook.uri, [0]); await timeout(50); - assert.strictEqual(edits.length > 0, true); + assert.strictEqual(cellExecuteEdits.length > 0, true); let found = false; - for (let edit of edits) { + for (let edit of cellExecuteEdits) { if (edit.editType === CellEditType.Output) { assert.strictEqual(edit.append, false); assert.strictEqual(edit.outputs.length, 1); - assert.strictEqual(edit.outputs[0].outputs.length, 1); - assert.deepStrictEqual(edit.outputs[0].outputs[0].valueBytes, Array.from(new TextEncoder().encode('canceled'))); + assert.strictEqual(edit.outputs[0].items.length, 1); + assert.deepStrictEqual(edit.outputs[0].items[0].valueBytes, Array.from(new TextEncoder().encode('canceled'))); found = true; } } @@ -293,18 +293,18 @@ suite('NotebookKernel', function () { task.end(true); }; - edits.length = 0; + cellExecuteEdits.length = 0; await extHostNotebookKernels.$cancelCells(0, notebook.uri, [0]); - assert.strictEqual(edits.length > 0, true); + assert.strictEqual(cellExecuteEdits.length > 0, true); let found = false; - for (let edit of edits) { + for (let edit of cellExecuteEdits) { if (edit.editType === CellEditType.Output) { assert.strictEqual(edit.append, false); assert.strictEqual(edit.outputs.length, 1); - assert.strictEqual(edit.outputs[0].outputs.length, 1); - assert.deepStrictEqual(edit.outputs[0].outputs[0].valueBytes, Array.from(new TextEncoder().encode('interrupted'))); + assert.strictEqual(edit.outputs[0].items.length, 1); + assert.deepStrictEqual(edit.outputs[0].items[0].valueBytes, Array.from(new TextEncoder().encode('interrupted'))); found = true; } }