From 0a2a8d86ac586585036a629c1148a36563a149ca Mon Sep 17 00:00:00 2001 From: aamunger Date: Mon, 9 Jan 2023 15:24:57 -0800 Subject: [PATCH 1/6] IW notebook serializer --- .../browser/interactive.contribution.ts | 117 +++++++----------- 1 file changed, 45 insertions(+), 72 deletions(-) diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index f3f03f7ebd5..ce5bd8fd445 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { VSBuffer } from 'vs/base/common/buffer'; -import { CancellationToken } from 'vs/base/common/cancellation'; import { Iterable } from 'vs/base/common/iterator'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; @@ -56,9 +55,9 @@ import { INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/no import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidget'; import * as icons from 'vs/workbench/contrib/notebook/browser/notebookIcons'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService'; -import { CellEditType, CellKind, CellUri, ICellOutput, INTERACTIVE_WINDOW_EDITOR_ID } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType, CellKind, CellUri, ICellOutput, INTERACTIVE_WINDOW_EDITOR_ID, NotebookData } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService'; -import { INotebookContentProvider, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; +import { INotebookSerializer, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { columnToEditorGroup } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; @@ -93,87 +92,61 @@ export class InteractiveDocumentContribution extends Disposable implements IWork cellContentMetadata: {} }; - const controller: INotebookContentProvider = { - get options() { - return contentOptions; - }, - set options(newOptions) { - contentOptions.transientCellMetadata = newOptions.transientCellMetadata; - contentOptions.transientDocumentMetadata = newOptions.transientDocumentMetadata; - contentOptions.transientOutputs = newOptions.transientOutputs; - }, - open: async (_uri: URI, _backupId: string | VSBuffer | undefined, _untitledDocumentData: VSBuffer | undefined, _token: CancellationToken) => { - if (_backupId instanceof VSBuffer) { - const backup = _backupId.toString(); - try { - const document = JSON.parse(backup) as { cells: { kind: CellKind; language: string; metadata: any; mime: string | undefined; content: string; outputs?: ICellOutput[] }[] }; - return { - data: { - metadata: {}, - cells: document.cells.map(cell => ({ - source: cell.content, - language: cell.language, - cellKind: cell.kind, - mime: cell.mime, - outputs: cell.outputs - ? cell.outputs.map(output => ({ - outputId: output.outputId, - outputs: output.outputs.map(ot => ({ - mime: ot.mime, - data: ot.data - })) - })) - : [], - metadata: cell.metadata - })) - }, - transientOptions: contentOptions - }; - } catch (_e) { } - } - - return { - data: { - metadata: {}, - cells: [] - }, - transientOptions: contentOptions - }; - }, - backup: async (uri: URI, token: CancellationToken) => { - const doc = notebookService.listNotebookDocuments().find(document => document.uri.toString() === uri.toString()); - if (doc) { - const cells = doc.cells.map(cell => ({ - kind: cell.cellKind, + const serializer: INotebookSerializer = { + options: contentOptions, + dataToNotebook: async (data: VSBuffer): Promise => { + const document = JSON.parse(data.toString()) as { cells: { kind: CellKind; language: string; metadata: any; mime: string | undefined; content: string; outputs?: ICellOutput[] }[] }; + return Promise.resolve({ + cells: document.cells.map(cell => ({ + source: cell.content, language: cell.language, - metadata: cell.metadata, - mine: cell.mime, - outputs: cell.outputs.map(output => { - return { + cellKind: cell.kind, + mime: cell.mime, + outputs: cell.outputs + ? cell.outputs.map(output => ({ outputId: output.outputId, outputs: output.outputs.map(ot => ({ mime: ot.mime, data: ot.data })) - }; - }), - content: cell.getValue() - })); + })) + : [], + metadata: cell.metadata + })), + metadata: {} + }); - const buffer = VSBuffer.fromString(JSON.stringify({ - cells: cells - })); + }, + notebookToData(data: NotebookData): Promise { + const cells = data.cells.map(cell => ({ + kind: cell.cellKind, + language: cell.language, + metadata: cell.metadata, + mine: cell.mime, + outputs: cell.outputs.map(output => { + return { + outputId: output.outputId, + outputs: output.outputs.map(ot => ({ + mime: ot.mime, + data: ot.data + })) + }; + }), + content: cell.source + })); - return buffer; - } else { - return ''; - } + const buffer = VSBuffer.fromString(JSON.stringify({ + cells: cells + })); + + return Promise.resolve(buffer); } }; - this._register(notebookService.registerNotebookController('interactive', { + + this._register(notebookService.registerNotebookSerializer('interactive', { id: new ExtensionIdentifier('interactive.builtin'), location: undefined - }, controller)); + }, serializer)); const info = notebookService.getContributedNotebookType('interactive'); From 6f445eb7d227270e38a80896455da295b3bb755b Mon Sep 17 00:00:00 2001 From: aamunger Date: Fri, 13 Jan 2023 11:08:36 -0800 Subject: [PATCH 2/6] use dummy file system provider for IW notebook model --- .../browser/dummyFileSystemProvider.ts | 94 +++++++++++++++++++ .../browser/interactive.contribution.ts | 55 +++++++---- 2 files changed, 130 insertions(+), 19 deletions(-) create mode 100644 src/vs/workbench/contrib/interactive/browser/dummyFileSystemProvider.ts diff --git a/src/vs/workbench/contrib/interactive/browser/dummyFileSystemProvider.ts b/src/vs/workbench/contrib/interactive/browser/dummyFileSystemProvider.ts new file mode 100644 index 00000000000..1bc3099306b --- /dev/null +++ b/src/vs/workbench/contrib/interactive/browser/dummyFileSystemProvider.ts @@ -0,0 +1,94 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Emitter, Event } from 'vs/base/common/event'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { URI } from 'vs/base/common/uri'; +import { FileSystemProviderCapabilities, FileType, IFileChange, IFileDeleteOptions, IFileOpenOptions, IFileOverwriteOptions, IFileSystemProvider, IFileWriteOptions, IStat, IWatchOptions } from 'vs/platform/files/common/files'; + +export class DummyFileSystem implements IFileSystemProvider { + private fdCounter = 1; + + capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.FileOpenReadWriteClose; + + public readFile(_resource: URI): Promise { + return Promise.resolve(new Uint8Array); + } + + public open(_resource: URI, _opts: IFileOpenOptions): Promise { + return Promise.resolve(this.fdCounter++); + } + + public stat(_resource: URI): Promise { + return Promise.resolve({ + type: FileType.File, + ctime: 0, + mtime: 0, + size: 0, + }); + } + public mkdir(_resource: URI): Promise { + return Promise.resolve(); + } + + public readdir(_resource: URI): Promise<[string, FileType][]> { + return Promise.resolve([['', FileType.Unknown]]); + } + + public delete(_resource: URI, _opts: IFileDeleteOptions): Promise { + return Promise.resolve(); + } + + public rename(_from: URI, _to: URI, _opts: IFileOverwriteOptions): Promise { + return Promise.resolve(); + } + + copy?(_from: URI, _to: URI, _opts: IFileOverwriteOptions): Promise { + return Promise.resolve(); + } + writeFile?(_resource: URI, _content: Uint8Array, _opts: IFileWriteOptions): Promise { + return Promise.resolve(); + } + // readFileStream?(resource: URI, opts: IFileReadStreamOptions, token: CancellationToken): ReadableStreamEvents { + // return Promise.resolve(); + // } + close?(_fd: number): Promise { + return Promise.resolve(); + } + read?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { + // claim no more bytes to read + return Promise.resolve(0); + } + write?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { + // claim all bytes written + return Promise.resolve(data.byteLength); + } + cloneFile?(_from: URI, _to: URI): Promise { + return Promise.resolve(); + } + + private readonly _onDidChangeCapabilities = new Emitter(); + readonly onDidChangeCapabilities: Event = this._onDidChangeCapabilities.event; + + private readonly _onDidChangeFile = new Emitter(); + readonly onDidChangeFile: Event = this._onDidChangeFile.event; + + constructor(private disposableFactory: () => IDisposable = () => Disposable.None) { } + onDidWatchError?: Event | undefined; + + + + public emitFileChangeEvents(changes: IFileChange[]): void { + this._onDidChangeFile.fire(changes); + } + + public setCapabilities(capabilities: FileSystemProviderCapabilities): void { + this.capabilities = capabilities; + + this._onDidChangeCapabilities.fire(); + } + + public watch(_resource: URI, _opts: IWatchOptions): IDisposable { return this.disposableFactory(); } +} diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index ce5bd8fd445..e75c83aa1c3 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -30,6 +30,7 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'v import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { EditorActivation, IResourceEditorInput } from 'vs/platform/editor/common/editor'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { IFileService } from 'vs/platform/files/common/files'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; @@ -45,6 +46,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput'; // import { Color } from 'vs/base/common/color'; import { PANEL_BORDER } from 'vs/workbench/common/theme'; import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits'; +import { DummyFileSystem } from 'vs/workbench/contrib/interactive/browser/dummyFileSystemProvider'; import { InteractiveWindowSetting, INTERACTIVE_INPUT_CURSOR_BOUNDARY } from 'vs/workbench/contrib/interactive/browser/interactiveCommon'; import { IInteractiveDocumentService, InteractiveDocumentService } from 'vs/workbench/contrib/interactive/browser/interactiveDocumentService'; import { InteractiveEditor } from 'vs/workbench/contrib/interactive/browser/interactiveEditor'; @@ -82,6 +84,7 @@ export class InteractiveDocumentContribution extends Disposable implements IWork @INotebookService notebookService: INotebookService, @IEditorResolverService editorResolverService: IEditorResolverService, @IEditorService editorService: IEditorService, + @IFileService fileService: IFileService ) { super(); @@ -92,28 +95,42 @@ export class InteractiveDocumentContribution extends Disposable implements IWork cellContentMetadata: {} }; + const interactiveWindowFS = new DummyFileSystem(); + this._register(fileService.registerProvider('vscode-interactive', interactiveWindowFS)); + const serializer: INotebookSerializer = { options: contentOptions, dataToNotebook: async (data: VSBuffer): Promise => { - const document = JSON.parse(data.toString()) as { cells: { kind: CellKind; language: string; metadata: any; mime: string | undefined; content: string; outputs?: ICellOutput[] }[] }; + if (data.byteLength > 0) { + try { + const document = JSON.parse(data.toString()) as { cells: { kind: CellKind; language: string; metadata: any; mime: string | undefined; content: string; outputs?: ICellOutput[] }[] }; + return Promise.resolve({ + cells: document.cells.map(cell => ({ + source: cell.content, + language: cell.language, + cellKind: cell.kind, + mime: cell.mime, + outputs: cell.outputs + ? cell.outputs.map(output => ({ + outputId: output.outputId, + outputs: output.outputs.map(ot => ({ + mime: ot.mime, + data: ot.data + })) + })) + : [], + metadata: cell.metadata + })), + metadata: {} + }); + } catch (e) { + console.log(e); + } + } + return Promise.resolve({ - cells: document.cells.map(cell => ({ - source: cell.content, - language: cell.language, - cellKind: cell.kind, - mime: cell.mime, - outputs: cell.outputs - ? cell.outputs.map(output => ({ - outputId: output.outputId, - outputs: output.outputs.map(ot => ({ - mime: ot.mime, - data: ot.data - })) - })) - : [], - metadata: cell.metadata - })), - metadata: {} + metadata: {}, + cells: [] }); }, @@ -385,7 +402,7 @@ registerAction2(class extends Action2 { let inputUri: URI | undefined = undefined; let counter = 1; do { - notebookUri = URI.from({ scheme: Schemas.vscodeInteractive, path: `Interactive-${counter}.interactive` }); + notebookUri = URI.from({ scheme: Schemas.vscodeInteractive, path: `/Interactive-${counter}.interactive` }); inputUri = URI.from({ scheme: Schemas.vscodeInteractiveInput, path: `/InteractiveInput-${counter}` }); counter++; From 6c1c35131febee059b19e1fa626d79f182746ac0 Mon Sep 17 00:00:00 2001 From: aamunger Date: Tue, 17 Jan 2023 14:50:15 -0800 Subject: [PATCH 3/6] feedback --- ...ider.ts => InteractiveWindowFileSystem.ts} | 31 +++++++------------ .../browser/interactive.contribution.ts | 6 ++-- .../interactive/browser/interactiveEditor.ts | 4 --- 3 files changed, 14 insertions(+), 27 deletions(-) rename src/vs/workbench/contrib/interactive/browser/{dummyFileSystemProvider.ts => InteractiveWindowFileSystem.ts} (71%) diff --git a/src/vs/workbench/contrib/interactive/browser/dummyFileSystemProvider.ts b/src/vs/workbench/contrib/interactive/browser/InteractiveWindowFileSystem.ts similarity index 71% rename from src/vs/workbench/contrib/interactive/browser/dummyFileSystemProvider.ts rename to src/vs/workbench/contrib/interactive/browser/InteractiveWindowFileSystem.ts index 1bc3099306b..8cbc1ca0872 100644 --- a/src/vs/workbench/contrib/interactive/browser/dummyFileSystemProvider.ts +++ b/src/vs/workbench/contrib/interactive/browser/InteractiveWindowFileSystem.ts @@ -6,13 +6,16 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { FileSystemProviderCapabilities, FileType, IFileChange, IFileDeleteOptions, IFileOpenOptions, IFileOverwriteOptions, IFileSystemProvider, IFileWriteOptions, IStat, IWatchOptions } from 'vs/platform/files/common/files'; +import { FileSystemProviderCapabilities, FileType, IFileChange, IFileDeleteOptions, IFileOpenOptions, IFileOverwriteOptions, IFileSystemProvider, IStat, IWatchOptions } from 'vs/platform/files/common/files'; + +export class InteractiveWindowFileSystem implements IFileSystemProvider { -export class DummyFileSystem implements IFileSystemProvider { private fdCounter = 1; capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.FileOpenReadWriteClose; + public constructor(private disposableFactory: () => IDisposable = () => Disposable.None) { } + public readFile(_resource: URI): Promise { return Promise.resolve(new Uint8Array); } @@ -45,29 +48,19 @@ export class DummyFileSystem implements IFileSystemProvider { return Promise.resolve(); } - copy?(_from: URI, _to: URI, _opts: IFileOverwriteOptions): Promise { + public close?(_fd: number): Promise { return Promise.resolve(); } - writeFile?(_resource: URI, _content: Uint8Array, _opts: IFileWriteOptions): Promise { - return Promise.resolve(); - } - // readFileStream?(resource: URI, opts: IFileReadStreamOptions, token: CancellationToken): ReadableStreamEvents { - // return Promise.resolve(); - // } - close?(_fd: number): Promise { - return Promise.resolve(); - } - read?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { + + public read?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { // claim no more bytes to read return Promise.resolve(0); } - write?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { + + public write?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { // claim all bytes written return Promise.resolve(data.byteLength); } - cloneFile?(_from: URI, _to: URI): Promise { - return Promise.resolve(); - } private readonly _onDidChangeCapabilities = new Emitter(); readonly onDidChangeCapabilities: Event = this._onDidChangeCapabilities.event; @@ -75,11 +68,9 @@ export class DummyFileSystem implements IFileSystemProvider { private readonly _onDidChangeFile = new Emitter(); readonly onDidChangeFile: Event = this._onDidChangeFile.event; - constructor(private disposableFactory: () => IDisposable = () => Disposable.None) { } + onDidWatchError?: Event | undefined; - - public emitFileChangeEvents(changes: IFileChange[]): void { this._onDidChangeFile.fire(changes); } diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index e75c83aa1c3..ca0818290ff 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -46,7 +46,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput'; // import { Color } from 'vs/base/common/color'; import { PANEL_BORDER } from 'vs/workbench/common/theme'; import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits'; -import { DummyFileSystem } from 'vs/workbench/contrib/interactive/browser/dummyFileSystemProvider'; +import { InteractiveWindowFileSystem } from 'vs/workbench/contrib/interactive/browser/InteractiveWindowFileSystem'; import { InteractiveWindowSetting, INTERACTIVE_INPUT_CURSOR_BOUNDARY } from 'vs/workbench/contrib/interactive/browser/interactiveCommon'; import { IInteractiveDocumentService, InteractiveDocumentService } from 'vs/workbench/contrib/interactive/browser/interactiveDocumentService'; import { InteractiveEditor } from 'vs/workbench/contrib/interactive/browser/interactiveEditor'; @@ -95,8 +95,8 @@ export class InteractiveDocumentContribution extends Disposable implements IWork cellContentMetadata: {} }; - const interactiveWindowFS = new DummyFileSystem(); - this._register(fileService.registerProvider('vscode-interactive', interactiveWindowFS)); + const interactiveWindowFS = new InteractiveWindowFileSystem(); + this._register(fileService.registerProvider(Schemas.vscodeInteractive, interactiveWindowFS)); const serializer: INotebookSerializer = { options: contentOptions, diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts index 9be9ba01eed..05c72cf677f 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.ts @@ -34,7 +34,6 @@ import { ILanguageService } from 'vs/editor/common/languages/language'; import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { InteractiveWindowSetting, INTERACTIVE_INPUT_CURSOR_BOUNDARY } from 'vs/workbench/contrib/interactive/browser/interactiveCommon'; -import { ComplexNotebookEditorModel } from 'vs/workbench/contrib/notebook/common/notebookEditorModel'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions'; import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; @@ -416,9 +415,6 @@ export class InteractiveEditor extends EditorPane { this.#scrollIfNecessary(cvm); })); this.#widgetDisposableStore.add(this.#notebookWidget.value!.onDidFocusWidget(() => this.#onDidFocusWidget.fire())); - this.#widgetDisposableStore.add(model.notebook.onDidChangeContent(() => { - (model as ComplexNotebookEditorModel).setDirty(false); - })); this.#widgetDisposableStore.add(this.#notebookOptions.onDidChangeOptions(e => { if (e.compactView || e.focusIndicator) { // update the styling From 30c21205645846b9edbd70202b80309fb69679e1 Mon Sep 17 00:00:00 2001 From: aamunger Date: Wed, 18 Jan 2023 09:54:15 -0800 Subject: [PATCH 4/6] feedback --- .../browser/interactive.contribution.ts | 22 ++++----- ...stem.ts => interactiveWindowFileSystem.ts} | 45 ++++++++----------- 2 files changed, 29 insertions(+), 38 deletions(-) rename src/vs/workbench/contrib/interactive/browser/{InteractiveWindowFileSystem.ts => interactiveWindowFileSystem.ts} (63%) diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index ca0818290ff..8f9cf8f9922 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -36,6 +36,7 @@ import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ILogService } from 'vs/platform/log/common/log'; +import { LogService } from 'vs/platform/log/common/logService'; import { Registry } from 'vs/platform/registry/common/platform'; import { contrastBorder, listInactiveSelectionBackground, registerColor, transparent } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; @@ -46,12 +47,12 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput'; // import { Color } from 'vs/base/common/color'; import { PANEL_BORDER } from 'vs/workbench/common/theme'; import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits'; -import { InteractiveWindowFileSystem } from 'vs/workbench/contrib/interactive/browser/InteractiveWindowFileSystem'; import { InteractiveWindowSetting, INTERACTIVE_INPUT_CURSOR_BOUNDARY } from 'vs/workbench/contrib/interactive/browser/interactiveCommon'; import { IInteractiveDocumentService, InteractiveDocumentService } from 'vs/workbench/contrib/interactive/browser/interactiveDocumentService'; import { InteractiveEditor } from 'vs/workbench/contrib/interactive/browser/interactiveEditor'; import { InteractiveEditorInput } from 'vs/workbench/contrib/interactive/browser/interactiveEditorInput'; import { IInteractiveHistoryService, InteractiveHistoryService } from 'vs/workbench/contrib/interactive/browser/interactiveHistoryService'; +import { InteractiveWindowFileSystem } from 'vs/workbench/contrib/interactive/browser/interactiveWindowFileSystem'; import { NOTEBOOK_EDITOR_WIDGET_ACTION_WEIGHT } from 'vs/workbench/contrib/notebook/browser/controller/coreActions'; import { INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/notebookEditorWidget'; @@ -84,7 +85,8 @@ export class InteractiveDocumentContribution extends Disposable implements IWork @INotebookService notebookService: INotebookService, @IEditorResolverService editorResolverService: IEditorResolverService, @IEditorService editorService: IEditorService, - @IFileService fileService: IFileService + @IFileService fileService: IFileService, + @ILogService logService: ILogService ) { super(); @@ -104,7 +106,7 @@ export class InteractiveDocumentContribution extends Disposable implements IWork if (data.byteLength > 0) { try { const document = JSON.parse(data.toString()) as { cells: { kind: CellKind; language: string; metadata: any; mime: string | undefined; content: string; outputs?: ICellOutput[] }[] }; - return Promise.resolve({ + return { cells: document.cells.map(cell => ({ source: cell.content, language: cell.language, @@ -122,19 +124,19 @@ export class InteractiveDocumentContribution extends Disposable implements IWork metadata: cell.metadata })), metadata: {} - }); + }; } catch (e) { - console.log(e); + logService.error(`error when converting data to notebook data object: ${e}`); } } - return Promise.resolve({ + return { metadata: {}, cells: [] - }); + }; }, - notebookToData(data: NotebookData): Promise { + notebookToData: async (data: NotebookData): Promise => { const cells = data.cells.map(cell => ({ kind: cell.cellKind, language: cell.language, @@ -152,11 +154,9 @@ export class InteractiveDocumentContribution extends Disposable implements IWork content: cell.source })); - const buffer = VSBuffer.fromString(JSON.stringify({ + return VSBuffer.fromString(JSON.stringify({ cells: cells })); - - return Promise.resolve(buffer); } }; diff --git a/src/vs/workbench/contrib/interactive/browser/InteractiveWindowFileSystem.ts b/src/vs/workbench/contrib/interactive/browser/interactiveWindowFileSystem.ts similarity index 63% rename from src/vs/workbench/contrib/interactive/browser/InteractiveWindowFileSystem.ts rename to src/vs/workbench/contrib/interactive/browser/interactiveWindowFileSystem.ts index 8cbc1ca0872..c8afa004b44 100644 --- a/src/vs/workbench/contrib/interactive/browser/InteractiveWindowFileSystem.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveWindowFileSystem.ts @@ -16,50 +16,42 @@ export class InteractiveWindowFileSystem implements IFileSystemProvider { public constructor(private disposableFactory: () => IDisposable = () => Disposable.None) { } - public readFile(_resource: URI): Promise { - return Promise.resolve(new Uint8Array); + public async readFile(_resource: URI): Promise { + return new Uint8Array(); } - public open(_resource: URI, _opts: IFileOpenOptions): Promise { - return Promise.resolve(this.fdCounter++); + public async open(_resource: URI, _opts: IFileOpenOptions): Promise { + return this.fdCounter++; } - public stat(_resource: URI): Promise { - return Promise.resolve({ + public async stat(_resource: URI): Promise { + return { type: FileType.File, ctime: 0, mtime: 0, size: 0, - }); + }; } - public mkdir(_resource: URI): Promise { - return Promise.resolve(); + public async mkdir(_resource: URI): Promise { } + + public async readdir(_resource: URI): Promise<[string, FileType][]> { + return [['', FileType.Unknown]]; } - public readdir(_resource: URI): Promise<[string, FileType][]> { - return Promise.resolve([['', FileType.Unknown]]); - } + public async delete(_resource: URI, _opts: IFileDeleteOptions): Promise { } - public delete(_resource: URI, _opts: IFileDeleteOptions): Promise { - return Promise.resolve(); - } + public async rename(_from: URI, _to: URI, _opts: IFileOverwriteOptions): Promise { } - public rename(_from: URI, _to: URI, _opts: IFileOverwriteOptions): Promise { - return Promise.resolve(); - } + public async close?(_fd: number): Promise { } - public close?(_fd: number): Promise { - return Promise.resolve(); - } - - public read?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { + public async read?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { // claim no more bytes to read - return Promise.resolve(0); + return 0; } - public write?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { + public async write?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { // claim all bytes written - return Promise.resolve(data.byteLength); + return data.byteLength; } private readonly _onDidChangeCapabilities = new Emitter(); @@ -68,7 +60,6 @@ export class InteractiveWindowFileSystem implements IFileSystemProvider { private readonly _onDidChangeFile = new Emitter(); readonly onDidChangeFile: Event = this._onDidChangeFile.event; - onDidWatchError?: Event | undefined; public emitFileChangeEvents(changes: IFileChange[]): void { From 8428b644ec7cd2fe1a160f6cb717dc38763b2c1a Mon Sep 17 00:00:00 2001 From: aamunger Date: Thu, 19 Jan 2023 09:18:07 -0800 Subject: [PATCH 5/6] remove unused reference --- .../contrib/interactive/browser/interactive.contribution.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts index 8f9cf8f9922..205639642b7 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactive.contribution.ts @@ -36,7 +36,6 @@ import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ILogService } from 'vs/platform/log/common/log'; -import { LogService } from 'vs/platform/log/common/logService'; import { Registry } from 'vs/platform/registry/common/platform'; import { contrastBorder, listInactiveSelectionBackground, registerColor, transparent } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; From 801c09f14ec791b1a06690ce8c675de05c088137 Mon Sep 17 00:00:00 2001 From: aamunger Date: Fri, 20 Jan 2023 12:53:59 -0800 Subject: [PATCH 6/6] read unbuffered --- .../browser/interactiveWindowFileSystem.ts | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveWindowFileSystem.ts b/src/vs/workbench/contrib/interactive/browser/interactiveWindowFileSystem.ts index c8afa004b44..992a3a6ea88 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveWindowFileSystem.ts +++ b/src/vs/workbench/contrib/interactive/browser/interactiveWindowFileSystem.ts @@ -6,25 +6,19 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { FileSystemProviderCapabilities, FileType, IFileChange, IFileDeleteOptions, IFileOpenOptions, IFileOverwriteOptions, IFileSystemProvider, IStat, IWatchOptions } from 'vs/platform/files/common/files'; +import { FileSystemProviderCapabilities, FileType, IFileChange, IFileDeleteOptions, IFileOverwriteOptions, IFileSystemProvider, IStat, IWatchOptions } from 'vs/platform/files/common/files'; export class InteractiveWindowFileSystem implements IFileSystemProvider { - private fdCounter = 1; + capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.FileReadWrite; - capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.FileOpenReadWriteClose; + constructor(private disposableFactory: () => IDisposable = () => Disposable.None) { } - public constructor(private disposableFactory: () => IDisposable = () => Disposable.None) { } - - public async readFile(_resource: URI): Promise { + async readFile(_resource: URI): Promise { return new Uint8Array(); } - public async open(_resource: URI, _opts: IFileOpenOptions): Promise { - return this.fdCounter++; - } - - public async stat(_resource: URI): Promise { + async stat(_resource: URI): Promise { return { type: FileType.File, ctime: 0, @@ -32,27 +26,15 @@ export class InteractiveWindowFileSystem implements IFileSystemProvider { size: 0, }; } - public async mkdir(_resource: URI): Promise { } + async mkdir(_resource: URI): Promise { } - public async readdir(_resource: URI): Promise<[string, FileType][]> { + async readdir(_resource: URI): Promise<[string, FileType][]> { return [['', FileType.Unknown]]; } - public async delete(_resource: URI, _opts: IFileDeleteOptions): Promise { } + async delete(_resource: URI, _opts: IFileDeleteOptions): Promise { } - public async rename(_from: URI, _to: URI, _opts: IFileOverwriteOptions): Promise { } - - public async close?(_fd: number): Promise { } - - public async read?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { - // claim no more bytes to read - return 0; - } - - public async write?(_fd: number, _pos: number, data: Uint8Array, _offset: number, _length: number): Promise { - // claim all bytes written - return data.byteLength; - } + async rename(_from: URI, _to: URI, _opts: IFileOverwriteOptions): Promise { } private readonly _onDidChangeCapabilities = new Emitter(); readonly onDidChangeCapabilities: Event = this._onDidChangeCapabilities.event; @@ -62,15 +44,15 @@ export class InteractiveWindowFileSystem implements IFileSystemProvider { onDidWatchError?: Event | undefined; - public emitFileChangeEvents(changes: IFileChange[]): void { + emitFileChangeEvents(changes: IFileChange[]): void { this._onDidChangeFile.fire(changes); } - public setCapabilities(capabilities: FileSystemProviderCapabilities): void { + setCapabilities(capabilities: FileSystemProviderCapabilities): void { this.capabilities = capabilities; this._onDidChangeCapabilities.fire(); } - public watch(_resource: URI, _opts: IWatchOptions): IDisposable { return this.disposableFactory(); } + watch(_resource: URI, _opts: IWatchOptions): IDisposable { return this.disposableFactory(); } }