未验证 提交 02f0509f 编写于 作者: J Johannes Rieken 提交者: GitHub

Merge pull request #107426 from microsoft/joh/cell-output

proposal for NotebookCellOutput
......@@ -417,6 +417,34 @@ suite('Notebook API tests', () => {
await saveAllFilesAndCloseAll(resource);
});
test('edit API (replaceOutput, USE NotebookCellOutput-type)', async function () {
assertInitalState();
const resource = await createRandomFile('', undefined, 'first', '.vsctestnb');
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await vscode.notebook.activeNotebookEditor!.edit(editBuilder => {
editBuilder.replaceCellOutput(0, [new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('application/foo', 'bar'),
new vscode.NotebookCellOutputItem('application/json', { data: true }, { metadata: true }),
])]);
});
const document = vscode.notebook.activeNotebookEditor?.document!;
assert.strictEqual(document.isDirty, true);
assert.strictEqual(document.cells.length, 1);
assert.strictEqual(document.cells[0].outputs.length, 1);
// consuming is OLD api (for now)
const [output] = document.cells[0].outputs;
assert.strictEqual(output.outputKind, vscode.CellOutputKind.Rich);
assert.strictEqual((<vscode.CellDisplayOutput>output).data['application/foo'], 'bar');
assert.deepStrictEqual((<vscode.CellDisplayOutput>output).data['application/json'], { data: true });
assert.deepStrictEqual((<vscode.CellDisplayOutput>output).metadata, { custom: { 'application/json': { metadata: true } } });
await saveAllFilesAndCloseAll(undefined);
});
test('edit API (replaceOutput)', async function () {
assertInitalState();
const resource = await createRandomFile('', undefined, 'first', '.vsctestnb');
......
......@@ -1226,6 +1226,27 @@ declare module 'vscode' {
export type CellOutput = CellStreamOutput | CellErrorOutput | CellDisplayOutput;
export class NotebookCellOutputItem {
readonly mime: string;
readonly value: unknown;
readonly metadata?: Record<string, string | number | boolean>;
constructor(mime: string, value: unknown, metadata?: Record<string, string | number | boolean>);
}
//TODO@jrieken add id?
export class NotebookCellOutput {
readonly outputs: NotebookCellOutputItem[];
readonly metadata?: Record<string, string | number | boolean>;
constructor(outputs: NotebookCellOutputItem[], metadata?: Record<string, string | number | boolean>);
//TODO@jrieken HACK to workaround dependency issues...
toJSON(): any;
}
export enum NotebookCellRunState {
Running = 1,
Idle = 2,
......@@ -1407,14 +1428,14 @@ declare module 'vscode' {
export interface WorkspaceEdit {
replaceNotebookMetadata(uri: Uri, value: NotebookDocumentMetadata): void;
replaceNotebookCells(uri: Uri, start: number, end: number, cells: NotebookCellData[], metadata?: WorkspaceEditEntryMetadata): void;
replaceNotebookCellOutput(uri: Uri, index: number, outputs: CellOutput[], metadata?: WorkspaceEditEntryMetadata): void;
replaceNotebookCellOutput(uri: Uri, index: number, outputs: (NotebookCellOutput | CellOutput)[], metadata?: WorkspaceEditEntryMetadata): void;
replaceNotebookCellMetadata(uri: Uri, index: number, cellMetadata: NotebookCellMetadata, metadata?: WorkspaceEditEntryMetadata): void;
}
export interface NotebookEditorEdit {
replaceMetadata(value: NotebookDocumentMetadata): void;
replaceCells(start: number, end: number, cells: NotebookCellData[]): void;
replaceCellOutput(index: number, outputs: CellOutput[]): void;
replaceCellOutput(index: number, outputs: (NotebookCellOutput | CellOutput)[]): void;
replaceCellMetadata(index: number, metadata: NotebookCellMetadata): void;
}
......
......@@ -1147,7 +1147,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
NotebookCellRunState: extHostTypes.NotebookCellRunState,
NotebookRunState: extHostTypes.NotebookRunState,
NotebookCellStatusBarAlignment: extHostTypes.NotebookCellStatusBarAlignment,
NotebookEditorRevealType: extHostTypes.NotebookEditorRevealType
NotebookEditorRevealType: extHostTypes.NotebookEditorRevealType,
NotebookCellOutput: extHostTypes.NotebookCellOutput,
NotebookCellOutputItem: extHostTypes.NotebookCellOutputItem,
};
};
}
......
......@@ -54,12 +54,18 @@ class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit {
});
}
replaceCellOutput(index: number, outputs: vscode.CellOutput[]): void {
replaceCellOutput(index: number, outputs: (vscode.NotebookCellOutput | vscode.CellOutput)[]): void {
this._throwIfFinalized();
this._collectedEdits.push({
editType: CellEditType.Output,
index,
outputs: outputs.map(output => addIdToOutput(output))
outputs: outputs.map(output => {
if (extHostTypes.NotebookCellOutput.isNotebookCellOutput(output)) {
return addIdToOutput(output.toJSON());
} else {
return addIdToOutput(output);
}
})
});
}
......
......@@ -32,7 +32,7 @@ import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays';
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
import { CommandsConverter } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
import { INotebookDecorationRenderOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellOutputKind, IDisplayOutput, INotebookDecorationRenderOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
export interface PositionLike {
line: number;
......@@ -1297,6 +1297,22 @@ export namespace LogLevel {
}
}
export namespace NotebookCellOutput {
export function from(output: types.NotebookCellOutput): IDisplayOutput {
return output.toJSON();
}
}
export namespace NotebookCellOutputItem {
export function from(output: types.NotebookCellOutputItem): IDisplayOutput {
return {
outputKind: CellOutputKind.Rich,
data: { [output.mime]: output.value },
metadata: output.metadata && { custom: output.metadata }
};
}
}
export namespace NotebookExclusiveDocumentPattern {
export function from(pattern: { include: vscode.GlobPattern | undefined, exclude: vscode.GlobPattern | undefined }): { include: string | types.RelativePattern | undefined, exclude: string | types.RelativePattern | undefined };
export function from(pattern: vscode.GlobPattern): string | types.RelativePattern;
......
......@@ -14,7 +14,7 @@ import { URI } from 'vs/base/common/uri';
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 { addIdToOutput, CellEditType, ICellEditOperation } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { addIdToOutput, CellEditType, ICellEditOperation, IDisplayOutput } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import type * as vscode from 'vscode';
function es5ClassCompat(target: Function): any {
......@@ -641,8 +641,18 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
}
}
replaceNotebookCellOutput(uri: URI, index: number, outputs: vscode.CellOutput[], metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Output, index, outputs: outputs.map(output => addIdToOutput(output)) } });
replaceNotebookCellOutput(uri: URI, index: number, outputs: (vscode.NotebookCellOutput | vscode.CellOutput)[], metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({
_type: FileEditType.Cell, metadata, uri, edit: {
editType: CellEditType.Output, index, outputs: outputs.map(output => {
if (NotebookCellOutput.isNotebookCellOutput(output)) {
return addIdToOutput(output.toJSON());
} else {
return addIdToOutput(output);
}
})
}
});
}
replaceNotebookCellMetadata(uri: URI, index: number, cellMetadata: vscode.NotebookCellMetadata, metadata?: vscode.WorkspaceEditEntryMetadata): void {
......@@ -2772,6 +2782,50 @@ export enum ColorThemeKind {
//#region Notebook
export class NotebookCellOutputItem {
static isNotebookCellOutputItem(obj: unknown): obj is vscode.NotebookCellOutputItem {
return obj instanceof NotebookCellOutputItem;
}
constructor(
readonly mime: string,
readonly value: unknown, // JSON'able
readonly metadata?: Record<string, string | number | boolean>
) { }
}
export class NotebookCellOutput {
static isNotebookCellOutput(obj: unknown): obj is vscode.NotebookCellOutput {
return obj instanceof NotebookCellOutput;
}
constructor(
readonly outputs: NotebookCellOutputItem[],
readonly metadata?: Record<string, string | number | boolean>
) { }
toJSON(): IDisplayOutput {
let data: { [key: string]: unknown; } = {};
let custom: { [key: string]: unknown; } = {};
let hasMetadata = false;
for (let item of this.outputs) {
data[item.mime] = item.value;
if (item.metadata) {
custom[item.mime] = item.metadata;
hasMetadata = true;
}
}
return {
outputKind: CellOutputKind.Rich,
data,
metadata: hasMetadata ? { custom } : undefined
};
}
}
export enum CellKind {
Markdown = 1,
Code = 2
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册