use same notebook serializer for IW

This commit is contained in:
aamunger 2023-06-09 15:50:51 -07:00
parent 3b921a80a8
commit 2c37a5be5a
No known key found for this signature in database
GPG key ID: F2CA0C6303FC6B74
3 changed files with 57 additions and 80 deletions

View file

@ -43,6 +43,18 @@ export function activate(context: vscode.ExtensionContext) {
}
} as vscode.NotebookDocumentContentOptions));
context.subscriptions.push(vscode.workspace.registerNotebookSerializer('interactive', serializer, {
transientOutputs: false,
transientCellMetadata: {
breakpointMargin: true,
custom: false,
attachments: false
},
cellContentMetadata: {
attachments: true
}
} as vscode.NotebookDocumentContentOptions));
vscode.languages.registerCodeLensProvider({ pattern: '**/*.ipynb' }, {
provideCodeLenses: (document) => {
if (

View file

@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { VSBuffer } from 'vs/base/common/buffer';
import { Iterable } from 'vs/base/common/iterator';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
@ -29,7 +28,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
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';
@ -56,9 +54,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, NotebookData } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellEditType, CellKind, CellUri, INTERACTIVE_WINDOW_EDITOR_ID } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
import { INotebookSerializer, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { 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';
@ -88,78 +86,6 @@ export class InteractiveDocumentContribution extends Disposable implements IWork
) {
super();
const contentOptions = {
transientOutputs: true,
transientCellMetadata: {},
transientDocumentMetadata: {},
cellContentMetadata: {}
};
const serializer: INotebookSerializer = {
options: contentOptions,
dataToNotebook: async (data: VSBuffer): Promise<NotebookData> => {
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 {
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) {
logService.error(`error when converting data to notebook data object: ${e}`);
}
}
return {
metadata: {},
cells: []
};
},
notebookToData: async (data: NotebookData): Promise<VSBuffer> => {
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 VSBuffer.fromString(JSON.stringify({
cells: cells
}));
}
};
this._register(notebookService.registerNotebookSerializer('interactive', {
id: new ExtensionIdentifier('interactive.builtin'),
location: undefined
}, serializer));
const info = notebookService.getContributedNotebookType('interactive');
// We need to contribute a notebook type for the Interactive Window to provide notebook models.

View file

@ -7,11 +7,12 @@ import { VSBuffer } from 'vs/base/common/buffer';
import { Event } from 'vs/base/common/event';
import { IReference } from 'vs/base/common/lifecycle';
import * as paths from 'vs/base/common/path';
import { isEqual } from 'vs/base/common/resources';
import { isEqual, joinPath } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService';
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { EditorInputCapabilities, IUntypedEditorInput } from 'vs/workbench/common/editor';
import { EditorInputCapabilities, GroupIdentifier, ISaveOptions, IUntypedEditorInput } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { IInteractiveDocumentService } from 'vs/workbench/contrib/interactive/browser/interactiveDocumentService';
import { IInteractiveHistoryService } from 'vs/workbench/contrib/interactive/browser/interactiveHistoryService';
@ -19,6 +20,7 @@ import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/mode
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
import { CellKind, ICellDto2, IOutputDto, IResolvedNotebookEditorModel, NotebookCellCollapseState, NotebookCellInternalMetadata, NotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { ICompositeNotebookEditorInput, NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
export class InteractiveEditorInput extends EditorInput implements ICompositeNotebookEditorInput {
static create(instantiationService: IInstantiationService, resource: URI, inputResource: URI, title?: string) {
@ -76,9 +78,10 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot
title: string | undefined,
@IInstantiationService instantiationService: IInstantiationService,
@ITextModelService textModelService: ITextModelService,
@IInteractiveDocumentService interactiveDocumentService: IInteractiveDocumentService,
@IInteractiveHistoryService historyService: IInteractiveHistoryService
@IInteractiveHistoryService historyService: IInteractiveHistoryService,
@INotebookService private readonly _notebookService: INotebookService,
@IFileDialogService private readonly _fileDialogService: IFileDialogService,
) {
const input = NotebookEditorInput.create(instantiationService, resource, 'interactive', {});
super();
@ -162,6 +165,42 @@ export class InteractiveEditorInput extends EditorInput implements ICompositeNot
return this._inputModelRef.object.textEditorModel;
}
override async save(group: GroupIdentifier, options?: ISaveOptions): Promise<EditorInput | IUntypedEditorInput | undefined> {
if (this._editorModelReference) {
if (this.hasCapability(EditorInputCapabilities.Untitled)) {
return this.saveAs(group, options);
} else {
await this._editorModelReference.save(options);
}
return this;
}
return undefined;
}
override async saveAs(group: GroupIdentifier, options?: ISaveOptions): Promise<IUntypedEditorInput | undefined> {
if (!this._editorModelReference) {
return undefined;
}
const provider = this._notebookService.getContributedNotebookType('interactive');
if (!provider) {
return undefined;
}
const pathCandidate = joinPath(await this._fileDialogService.defaultFilePath(), 'scratch.ipynb');
const target = await this._fileDialogService.pickFileToSave(pathCandidate, options?.availableFileSystems);
if (!target) {
return undefined; // save cancelled
}
return await this._editorModelReference.saveAs(target);
}
override matches(otherInput: EditorInput | IUntypedEditorInput): boolean {
if (super.matches(otherInput)) {
return true;