Separate extension metadata from execution metadata

Fix #123235
This commit is contained in:
Rob Lourens 2021-05-12 17:25:50 -07:00
parent 21bb657ce2
commit dfb8c467ca
24 changed files with 212 additions and 191 deletions

View file

@ -114,7 +114,8 @@ export class MainThreadNotebookDocuments implements MainThreadNotebookDocumentsS
language: cell.language,
cellKind: cell.cellKind,
outputs: cell.outputs,
metadata: cell.metadata
metadata: cell.metadata,
internalMetadata: cell.internalMetadata,
};
}

View file

@ -234,7 +234,8 @@ export class MainThreadNotebooksAndEditors {
language: cell.language,
cellKind: cell.cellKind,
outputs: cell.outputs,
metadata: cell.metadata
metadata: cell.metadata,
internalMetadata: cell.internalMetadata,
}))
};
}

View file

@ -11,7 +11,7 @@ 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, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookCellsSplice2 } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, IMainCellDto, IOutputDto, IOutputItemDto, NotebookCellInternalMetadata, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookCellsSplice2 } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import * as vscode from 'vscode';
class RawContentChangeEvent {
@ -48,7 +48,7 @@ export class ExtHostCell {
private _metadata: extHostTypes.NotebookCellMetadata;
private _previousResult: vscode.NotebookCellExecutionSummary | undefined;
private _internalMetadata: NotebookCellMetadata;
private _internalMetadata: NotebookCellInternalMetadata;
readonly handle: number;
readonly uri: URI;
readonly cellKind: CellKind;
@ -64,12 +64,12 @@ export class ExtHostCell {
this.uri = URI.revive(_cellData.uri);
this.cellKind = _cellData.cellKind;
this._outputs = _cellData.outputs.map(extHostTypeConverters.NotebookCellOutput.to);
this._internalMetadata = _cellData.metadata ?? {};
this._metadata = extHostTypeConverters.NotebookCellMetadata.to(this._internalMetadata);
this._previousResult = extHostTypeConverters.NotebookCellPreviousExecutionResult.to(this._internalMetadata);
this._internalMetadata = _cellData.internalMetadata ?? {};
this._metadata = extHostTypeConverters.NotebookCellMetadata.to(_cellData.metadata ?? {});
this._previousResult = extHostTypeConverters.NotebookCellExecutionSummary.to(_cellData.internalMetadata ?? {});
}
get internalMetadata(): NotebookCellMetadata {
get internalMetadata(): NotebookCellInternalMetadata {
return this._internalMetadata;
}
@ -109,9 +109,12 @@ export class ExtHostCell {
}
setMetadata(newMetadata: NotebookCellMetadata): void {
this._internalMetadata = newMetadata;
this._metadata = extHostTypeConverters.NotebookCellMetadata.to(newMetadata);
this._previousResult = extHostTypeConverters.NotebookCellPreviousExecutionResult.to(newMetadata);
}
setInternalMetadata(newInternalMetadata: NotebookCellInternalMetadata): void {
this._internalMetadata = newInternalMetadata;
this._previousResult = extHostTypeConverters.NotebookCellExecutionSummary.to(newInternalMetadata);
}
}
@ -213,6 +216,8 @@ export class ExtHostNotebookDocument {
this._changeCellLanguage(rawEvent.index, rawEvent.language);
} else if (rawEvent.kind === NotebookCellsChangeType.ChangeCellMetadata) {
this._changeCellMetadata(rawEvent.index, rawEvent.metadata);
} else if (rawEvent.kind === NotebookCellsChangeType.ChangeCellInternalMetadata) {
this._changeCellInternalMetadata(rawEvent.index, rawEvent.internalMetadata);
}
}
}
@ -334,7 +339,6 @@ export class ExtHostNotebookDocument {
private _changeCellMetadata(index: number, newMetadata: NotebookCellMetadata): void {
const cell = this._cells[index];
const originalInternalMetadata = cell.internalMetadata;
const originalExtMetadata = cell.apiCell.metadata;
cell.setMetadata(newMetadata);
const newExtMetadata = cell.apiCell.metadata;
@ -342,9 +346,16 @@ export class ExtHostNotebookDocument {
if (!equals(originalExtMetadata, newExtMetadata)) {
this._emitter.emitCellMetadataChange(deepFreeze({ document: this.apiNotebook, cell: cell.apiCell }));
}
}
if (originalInternalMetadata.runState !== newMetadata.runState) {
const executionState = newMetadata.runState ?? extHostTypes.NotebookCellExecutionState.Idle;
private _changeCellInternalMetadata(index: number, newInternalMetadata: NotebookCellInternalMetadata): void {
const cell = this._cells[index];
const originalInternalMetadata = cell.internalMetadata;
cell.setInternalMetadata(newInternalMetadata);
if (originalInternalMetadata.runState !== newInternalMetadata.runState) {
const executionState = newInternalMetadata.runState ?? extHostTypes.NotebookCellExecutionState.Idle;
this._emitter.emitCellExecutionStateChange(deepFreeze({ document: this.apiNotebook, cell: cell.apiCell, executionState }));
}
}

View file

@ -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, NullablePartialNotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellEditType, IImmediateCellEditOperation, NullablePartialNotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { NotebookCellExecutionState } from 'vs/workbench/api/common/extHostTypes';
import { asArray } from 'vs/base/common/arrays';
@ -373,8 +373,8 @@ class NotebookCellExecutionTask extends Disposable {
}
}
private mixinMetadata(mixinMetadata: NullablePartialNotebookCellMetadata) {
const edit: IImmediateCellEditOperation = { editType: CellEditType.PartialMetadata, handle: this._cell.handle, metadata: mixinMetadata };
private mixinMetadata(mixinMetadata: NullablePartialNotebookCellInternalMetadata) {
const edit: IImmediateCellEditOperation = { editType: CellEditType.PartialInternalMetadata, handle: this._cell.handle, internalMetadata: mixinMetadata };
this.applyEdits([edit]);
}

View file

@ -1443,8 +1443,8 @@ export namespace NotebookDocumentMetadata {
}
}
export namespace NotebookCellPreviousExecutionResult {
export function to(data: notebooks.NotebookCellMetadata): vscode.NotebookCellExecutionSummary {
export namespace NotebookCellExecutionSummary {
export function to(data: notebooks.NotebookCellInternalMetadata): vscode.NotebookCellExecutionSummary {
return {
startTime: data.runStartTime,
endTime: data.runEndTime,
@ -1453,7 +1453,7 @@ export namespace NotebookCellPreviousExecutionResult {
};
}
export function from(data: vscode.NotebookCellExecutionSummary): Partial<notebooks.NotebookCellMetadata> {
export function from(data: vscode.NotebookCellExecutionSummary): Partial<notebooks.NotebookCellInternalMetadata> {
return {
lastRunSuccess: data.success,
runStartTime: data.startTime,
@ -1492,10 +1492,8 @@ export namespace NotebookCellData {
cellKind: NotebookCellKind.from(data.kind),
language: data.languageId,
source: data.value,
metadata: {
...data.metadata,
...NotebookCellPreviousExecutionResult.from(data.executionSummary ?? {})
},
metadata: data.metadata,
internalMetadata: NotebookCellExecutionSummary.from(data.executionSummary ?? {}),
outputs: data.outputs ? data.outputs.map(NotebookCellOutput.from) : []
};
}
@ -1642,15 +1640,7 @@ export namespace NotebookDocumentContentOptions {
export function from(options: vscode.NotebookDocumentContentOptions | undefined): notebooks.TransientOptions {
return {
transientOutputs: options?.transientOutputs ?? false,
transientCellMetadata: {
...options?.transientCellMetadata,
executionOrder: true,
runState: true,
runStartTime: true,
runStartTimeAdjustment: true,
runEndTime: true,
lastRunSuccess: true
},
transientCellMetadata: options?.transientCellMetadata ?? {},
transientDocumentMetadata: options?.transientDocumentMetadata ?? {}
};
}

View file

@ -803,7 +803,7 @@ async function runCell(accessor: ServicesAccessor, context: INotebookActionConte
}
if (context.ui && context.cell) {
if (context.cell.metadata?.runState === NotebookCellExecutionState.Executing) {
if (context.cell.internalMetadata?.runState === NotebookCellExecutionState.Executing) {
return;
}
return context.notebookEditor.executeNotebookCells(Iterable.single(context.cell));
@ -1251,10 +1251,9 @@ registerAction2(class ClearCellOutputsAction extends NotebookCellAction {
editor.viewModel.notebookDocument.applyEdits([{ editType: CellEditType.Output, index, outputs: [] }], true, undefined, () => undefined, undefined);
if (context.cell.metadata && context.cell.metadata?.runState !== NotebookCellExecutionState.Executing) {
if (context.cell.internalMetadata?.runState !== NotebookCellExecutionState.Executing) {
context.notebookEditor.viewModel.notebookDocument.applyEdits([{
editType: CellEditType.Metadata, index, metadata: {
...context.cell.metadata,
editType: CellEditType.PartialInternalMetadata, index, internalMetadata: {
runState: NotebookCellExecutionState.Idle,
runStartTime: undefined,
runStartTimeAdjustment: undefined,
@ -1465,10 +1464,9 @@ registerAction2(class ClearAllCellOutputsAction extends NotebookAction {
})), true, undefined, () => undefined, undefined);
const clearExecutionMetadataEdits = editor.viewModel.notebookDocument.cells.map((cell, index) => {
if (cell.metadata && cell.metadata?.runState !== NotebookCellExecutionState.Executing) {
if (cell.internalMetadata?.runState !== NotebookCellExecutionState.Executing) {
return {
editType: CellEditType.Metadata, index, metadata: {
...cell.metadata,
editType: CellEditType.PartialInternalMetadata, index, internalMetadata: {
runState: NotebookCellExecutionState.Idle,
runStartTime: undefined,
runStartTimeAdjustment: undefined,

View file

@ -87,6 +87,7 @@ class CellStatusBarHelper extends Disposable {
this._register(this._cell.model.onDidChangeContent(() => this._updateSoon()));
this._register(this._cell.model.onDidChangeLanguage(() => this._updateSoon()));
this._register(this._cell.model.onDidChangeMetadata(() => this._updateSoon()));
this._register(this._cell.model.onDidChangeInternalMetadata(() => this._updateSoon()));
this._register(this._cell.model.onDidChangeOutputs(() => this._updateSoon()));
}

View file

@ -89,7 +89,7 @@ class ExecutionStateCellStatusBarHelper extends Disposable {
super();
this._update();
this._register(this._cell.model.onDidChangeMetadata(() => this._update()));
this._register(this._cell.model.onDidChangeInternalMetadata(() => this._update()));
}
private async _update() {
@ -107,13 +107,13 @@ class ExecutionStateCellStatusBarHelper extends Disposable {
return;
}
const item = this._getItemForState(cell.metadata?.runState, cell.metadata?.lastRunSuccess);
const item = this._getItemForState(cell.internalMetadata?.runState ?? NotebookCellExecutionState.Idle, cell.internalMetadata?.lastRunSuccess);
// Show the execution spinner for a minimum time
if (cell.metadata?.runState === NotebookCellExecutionState.Executing) {
if (cell.internalMetadata?.runState === NotebookCellExecutionState.Executing) {
this._currentExecutingStateTimer = setTimeout(() => {
this._currentExecutingStateTimer = undefined;
if (cell.metadata?.runState !== NotebookCellExecutionState.Executing) {
if (cell.internalMetadata?.runState !== NotebookCellExecutionState.Executing) {
this._update();
}
}, ExecutionStateCellStatusBarHelper.MIN_SPINNER_TIME);
@ -179,21 +179,22 @@ class TimerCellStatusBarHelper extends Disposable {
this._scheduler = this._register(new RunOnceScheduler(() => this._update(), TimerCellStatusBarHelper.UPDATE_INTERVAL));
this._update();
this._register(this._cell.model.onDidChangeMetadata(() => this._update()));
this._register(this._cell.model.onDidChangeInternalMetadata(() => this._update()));
}
private async _update() {
let item: INotebookCellStatusBarItem | undefined;
if (this._cell.metadata?.runState === NotebookCellExecutionState.Executing) {
const startTime = this._cell.metadata.runStartTime;
const adjustment = this._cell.metadata.runStartTimeAdjustment;
const state = this._cell.internalMetadata?.runState ?? NotebookCellExecutionState.Idle;
if (state === NotebookCellExecutionState.Executing) {
const startTime = this._cell.internalMetadata?.runStartTime;
const adjustment = this._cell.internalMetadata?.runStartTimeAdjustment;
if (typeof startTime === 'number') {
item = this._getTimeItem(startTime, Date.now(), adjustment);
this._scheduler.schedule();
}
} else if (this._cell.metadata?.runState === NotebookCellExecutionState.Idle) {
const startTime = this._cell.metadata.runStartTime;
const endTime = this._cell.metadata.runEndTime;
} else if (state === NotebookCellExecutionState.Idle) {
const startTime = this._cell.internalMetadata?.runStartTime;
const endTime = this._cell.internalMetadata?.runEndTime;
if (typeof startTime === 'number' && typeof endTime === 'number') {
item = this._getTimeItem(startTime, endTime);
}
@ -250,7 +251,7 @@ class KeybindingPlaceholderStatusBarHelper extends Disposable {
NOTEBOOK_CELL_EXECUTION_STATE.bindTo(this._contextKeyService).set('idle');
this._update();
this._register(this._cell.model.onDidChangeMetadata(() => this._update()));
this._register(this._cell.model.onDidChangeInternalMetadata(() => this._update()));
}
private async _update() {
@ -261,7 +262,7 @@ class KeybindingPlaceholderStatusBarHelper extends Disposable {
}
private _getItemsForCell(cell: ICellViewModel): INotebookCellStatusBarItem[] {
if (typeof cell.metadata?.runState !== 'undefined' || typeof cell.metadata?.lastRunSuccess !== 'undefined') {
if (typeof cell.internalMetadata?.runState !== 'undefined' || typeof cell.internalMetadata?.lastRunSuccess !== 'undefined') {
return [];
}

View file

@ -490,22 +490,6 @@ abstract class AbstractElementRenderer extends Disposable {
}
break;
case 'executionOrder':
// number
if (typeof newMetadataObj[key] === 'number') {
result[key] = newMetadataObj[key];
} else {
result[key] = currentMetadata[key as keyof NotebookCellMetadata];
}
break;
case 'runState':
// enum
if (typeof newMetadataObj[key] === 'number' && [1, 2, 3, 4].indexOf(newMetadataObj[key]) >= 0) {
result[key] = newMetadataObj[key];
} else {
result[key] = currentMetadata[key as keyof NotebookCellMetadata];
}
break;
default:
result[key] = newMetadataObj[key];
break;

View file

@ -21,7 +21,7 @@ import { ContextKeyExpr, RawContextKey, IContextKeyService } from 'vs/platform/c
import { OutputRenderer } from 'vs/workbench/contrib/notebook/browser/view/output/outputRenderer';
import { CellViewModel, IModelDecorationsChangeAccessor, NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { CellKind, NotebookCellMetadata, INotebookKernel, IOrderedMimeType, INotebookRendererInfo, ICellOutput, IOutputItemDto, INotebookCellStatusBarItem } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, NotebookCellMetadata, INotebookKernel, IOrderedMimeType, INotebookRendererInfo, ICellOutput, IOutputItemDto, INotebookCellStatusBarItem, NotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { ICellRange, cellRangesToIndexes, reduceRanges } from 'vs/workbench/contrib/notebook/common/notebookRange';
import { Webview } from 'vs/workbench/contrib/webview/browser/webview';
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
@ -263,6 +263,7 @@ export interface ICellViewModel extends IGenericCellViewModel {
getTextLength(): number;
getHeight(lineHeight: number): number;
metadata: NotebookCellMetadata | undefined;
internalMetadata: NotebookCellInternalMetadata | undefined;
textModel: ITextModel | undefined;
hasModel(): this is IEditableCellViewModel;
resolveTextModel(): Promise<ITextModel>;
@ -822,6 +823,7 @@ export enum CursorAtBoundary {
export interface CellViewModelStateChangeEvent {
readonly metadataChanged?: boolean;
readonly internalMetadataChanged?: boolean;
readonly runStateChanged?: boolean;
readonly selectionChanged?: boolean;
readonly focusModeChanged?: boolean;

View file

@ -47,7 +47,7 @@ export class NotebookEditorKernelManager extends Disposable {
const cellHandles: number[] = [];
for (const cell of cells) {
if (cell.cellKind !== CellKind.Code || cell.metadata?.runState === NotebookCellExecutionState.Pending || cell.metadata?.runState === NotebookCellExecutionState.Executing) {
if (cell.cellKind !== CellKind.Code || cell.internalMetadata?.runState === NotebookCellExecutionState.Pending || cell.internalMetadata?.runState === NotebookCellExecutionState.Executing) {
continue;
}
if (!kernel.supportedLanguages.includes(cell.language)) {

View file

@ -69,9 +69,9 @@ export class NotebookEditorContextKeys {
if (!e.runStateChanged) {
return;
}
if (c.metadata?.runState === NotebookCellExecutionState.Pending) {
if (c.internalMetadata?.runState === NotebookCellExecutionState.Pending) {
executionCount++;
} else if (c.metadata?.runState === NotebookCellExecutionState.Idle) {
} else if (c.internalMetadata?.runState === NotebookCellExecutionState.Idle) {
executionCount--;
}
this._someCellRunning.set(executionCount > 0);

View file

@ -69,7 +69,7 @@ export class CellContextKeyManager extends Disposable {
this.contextKeyService.bufferChangeEvents(() => {
this.updateForFocusState();
this.updateForMetadata();
this.updateForInternalMetadata();
this.updateForEditState();
this.updateForCollapseState();
this.updateForOutputs();
@ -80,8 +80,8 @@ export class CellContextKeyManager extends Disposable {
private onDidChangeState(e: CellViewModelStateChangeEvent) {
this.contextKeyService.bufferChangeEvents(() => {
if (e.metadataChanged) {
this.updateForMetadata();
if (e.internalMetadataChanged) {
this.updateForInternalMetadata();
}
if (e.editStateChanged) {
@ -114,17 +114,17 @@ export class CellContextKeyManager extends Disposable {
}
private updateForMetadata() {
const metadata = this.element.metadata;
private updateForInternalMetadata() {
const internalMetadata = this.element.internalMetadata;
this.cellEditable.set(!this.notebookEditor.viewModel?.options.isReadOnly);
const runState = metadata.runState ?? NotebookCellExecutionState.Idle;
const runState = internalMetadata.runState ?? NotebookCellExecutionState.Idle;
if (this.element instanceof MarkdownCellViewModel) {
this.cellRunState.reset();
} else if (runState === NotebookCellExecutionState.Idle) {
if (metadata.lastRunSuccess === true) {
if (internalMetadata.lastRunSuccess === true) {
this.cellRunState.set('succeeded');
} else if (metadata.lastRunSuccess === false) {
} else if (internalMetadata.lastRunSuccess === false) {
this.cellRunState.set('failed');
} else {
this.cellRunState.set('idle');

View file

@ -46,7 +46,7 @@ import { StatefulMarkdownCell } from 'vs/workbench/contrib/notebook/browser/view
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { CellEditType, CellKind, NotebookCellMetadata, NotebookCellExecutionState, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellEditType, CellKind, NotebookCellMetadata, NotebookCellExecutionState, NotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CodiconActionViewItem } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellActionView';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { errorStateIcon, successStateIcon, unfoldIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons';
@ -843,25 +843,25 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
}
}
private updateForMetadata(element: CodeCellViewModel, templateData: CodeCellRenderTemplate, editorOptions: CellEditorOptions): void {
private updateForInternalMetadata(element: CodeCellViewModel, templateData: CodeCellRenderTemplate, editorOptions: CellEditorOptions): void {
if (!this.notebookEditor.hasModel()) {
return;
}
const metadata = element.metadata;
this.updateExecutionOrder(metadata, templateData);
const internalMetadata = element.internalMetadata;
this.updateExecutionOrder(internalMetadata, templateData);
if (metadata.runState === NotebookCellExecutionState.Executing) {
if (internalMetadata.runState === NotebookCellExecutionState.Executing) {
templateData.progressBar.infinite().show(500);
} else {
templateData.progressBar.hide();
}
}
private updateExecutionOrder(metadata: NotebookCellMetadata, templateData: CodeCellRenderTemplate): void {
private updateExecutionOrder(internalMetadata: NotebookCellInternalMetadata, templateData: CodeCellRenderTemplate): void {
if (this.notebookEditor.activeKernel?.implementsExecutionOrder) {
const executionOrderLabel = typeof metadata.executionOrder === 'number' ?
`[${metadata.executionOrder}]` :
const executionOrderLabel = typeof internalMetadata.executionOrder === 'number' ?
`[${internalMetadata.executionOrder}]` :
'[ ]';
templateData.executionOrderLabel.innerText = executionOrderLabel;
} else {
@ -950,13 +950,13 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
this.updateForLayout(element, templateData);
}));
this.updateForMetadata(element, templateData, cellEditorOptions);
this.updateForInternalMetadata(element, templateData, cellEditorOptions);
this.updateForHover(element, templateData);
this.updateForFocus(element, templateData);
cellEditorOptions.setLineNumbers(element.lineNumbers);
elementDisposables.add(element.onDidChangeState((e) => {
if (e.metadataChanged) {
this.updateForMetadata(element, templateData, cellEditorOptions);
if (e.internalMetadataChanged) {
this.updateForInternalMetadata(element, templateData, cellEditorOptions);
}
if (e.outputIsHoveredChanged) {
@ -971,11 +971,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
cellEditorOptions.setLineNumbers(element.lineNumbers);
}
}));
elementDisposables.add(this.notebookEditor.viewModel.notebookDocument.onDidChangeContent(e => {
if (e.rawEvents.find(event => event.kind === NotebookCellsChangeType.ChangeDocumentMetadata)) {
this.updateForMetadata(element, templateData, cellEditorOptions);
}
}));
this.updateForOutputs(element, templateData);
elementDisposables.add(element.onDidChangeOutputs(_e => this.updateForOutputs(element, templateData)));

View file

@ -39,6 +39,9 @@ export abstract class BaseCellViewModel extends Disposable {
get metadata() {
return this.model.metadata;
}
get internalMetadata() {
return this.model.internalMetadata;
}
get language() {
return this.model.language;
}
@ -135,8 +138,12 @@ export abstract class BaseCellViewModel extends Disposable {
) {
super();
this._register(model.onDidChangeMetadata(e => {
this._onDidChangeState.fire({ metadataChanged: true, runStateChanged: e.runStateChanged });
this._register(model.onDidChangeMetadata(() => {
this._onDidChangeState.fire({ metadataChanged: true });
}));
this._register(model.onDidChangeInternalMetadata(e => {
this._onDidChangeState.fire({ internalMetadataChanged: true, runStateChanged: e.runStateChanged });
}));
this._register(this._viewContext.notebookOptions.onDidChangeOptions(e => {

View file

@ -4,18 +4,18 @@
*--------------------------------------------------------------------------------------------*/
import { Emitter, Event } from 'vs/base/common/event';
import { ICell, NotebookCellOutputsSplice, CellKind, NotebookCellMetadata, TransientOptions, IOutputDto, ICellOutput, CellMetadataChangedEvent } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder';
import { hash } from 'vs/base/common/hash';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import * as UUID from 'vs/base/common/uuid';
import * as model from 'vs/editor/common/model';
import { Range } from 'vs/editor/common/core/range';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { hash } from 'vs/base/common/hash';
import * as model from 'vs/editor/common/model';
import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer';
import { NotebookCellOutputTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel';
import { IModeService } from 'vs/editor/common/services/modeService';
import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder';
import { TextModel } from 'vs/editor/common/model/textModel';
import { IModeService } from 'vs/editor/common/services/modeService';
import { NotebookCellOutputTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel';
import { CellInternalMetadataChangedEvent, CellKind, ICell, ICellOutput, IOutputDto, NotebookCellInternalMetadata, NotebookCellMetadata, NotebookCellOutputsSplice, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
export class NotebookCellTextModel extends Disposable implements ICell {
private _onDidChangeOutputs = new Emitter<NotebookCellOutputsSplice[]>();
@ -24,8 +24,11 @@ export class NotebookCellTextModel extends Disposable implements ICell {
private _onDidChangeContent = new Emitter<'content' | 'language'>();
onDidChangeContent: Event<'content' | 'language'> = this._onDidChangeContent.event;
private _onDidChangeMetadata = new Emitter<CellMetadataChangedEvent>();
onDidChangeMetadata: Event<CellMetadataChangedEvent> = this._onDidChangeMetadata.event;
private _onDidChangeMetadata = new Emitter<void>();
onDidChangeMetadata: Event<void> = this._onDidChangeMetadata.event;
private _onDidChangeInternalMetadata = new Emitter<CellInternalMetadataChangedEvent>();
onDidChangeInternalMetadata: Event<CellInternalMetadataChangedEvent> = this._onDidChangeInternalMetadata.event;
private _onDidChangeLanguage = new Emitter<string>();
onDidChangeLanguage: Event<string> = this._onDidChangeLanguage.event;
@ -43,14 +46,26 @@ export class NotebookCellTextModel extends Disposable implements ICell {
}
set metadata(newMetadata: NotebookCellMetadata) {
const runStateChanged = this._metadata.runState !== newMetadata.runState;
newMetadata = {
...newMetadata,
...{ runStartTimeAdjustment: computeRunStartTimeAdjustment(this._metadata, newMetadata) }
};
this._metadata = newMetadata;
this._hash = null;
this._onDidChangeMetadata.fire({ runStateChanged });
this._onDidChangeMetadata.fire();
}
private _internalMetadata: NotebookCellInternalMetadata;
get internalMetadata() {
return this._internalMetadata;
}
set internalMetadata(newInternalMetadata: NotebookCellInternalMetadata) {
const runStateChanged = this._internalMetadata.runState !== newInternalMetadata.runState;
newInternalMetadata = {
...newInternalMetadata,
...{ runStartTimeAdjustment: computeRunStartTimeAdjustment(this._internalMetadata, newInternalMetadata) }
};
this._internalMetadata = newInternalMetadata;
this._hash = null;
this._onDidChangeInternalMetadata.fire({ runStateChanged });
}
get language() {
@ -148,12 +163,14 @@ export class NotebookCellTextModel extends Disposable implements ICell {
public cellKind: CellKind,
outputs: IOutputDto[],
metadata: NotebookCellMetadata | undefined,
internalMetadata: NotebookCellInternalMetadata | undefined,
public readonly transientOptions: TransientOptions,
private readonly _modeService: IModeService
) {
super();
this._outputs = outputs.map(op => new NotebookCellOutputTextModel(op));
this._metadata = metadata || {};
this._internalMetadata = internalMetadata || {};
}
getValue(): string {
@ -220,12 +237,6 @@ export class NotebookCellTextModel extends Disposable implements ICell {
}
}
export function cloneMetadata(cell: NotebookCellTextModel) {
return {
...cell.metadata
};
}
export function cloneNotebookCellTextModel(cell: NotebookCellTextModel) {
return {
source: cell.getValue(),
@ -235,11 +246,12 @@ export function cloneNotebookCellTextModel(cell: NotebookCellTextModel) {
outputs: output.outputs,
/* paste should generate new outputId */ outputId: UUID.generateUuid()
})),
metadata: cloneMetadata(cell)
metadata: { ...cell.metadata },
internalMetadata: { ...cell.internalMetadata },
};
}
function computeRunStartTimeAdjustment(oldMetadata: NotebookCellMetadata, newMetadata: NotebookCellMetadata): number | undefined {
function computeRunStartTimeAdjustment(oldMetadata: NotebookCellInternalMetadata, newMetadata: NotebookCellInternalMetadata): number | undefined {
if (oldMetadata.runStartTime !== newMetadata.runStartTime && typeof newMetadata.runStartTime === 'number') {
const offset = Date.now() - newMetadata.runStartTime;
return offset < 0 ? Math.abs(offset) : 0;

View file

@ -8,7 +8,7 @@ import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { INotebookTextModel, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, CellEditType, CellUri, notebookDocumentMetadataDefaults, diff, NotebookCellsChangeType, ICellDto2, TransientOptions, NotebookTextModelChangedEvent, NotebookRawContentEvent, IOutputDto, ICellOutput, IOutputItemDto, ISelectionState, NullablePartialNotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookTextModel, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, CellEditType, CellUri, notebookDocumentMetadataDefaults, diff, NotebookCellsChangeType, ICellDto2, TransientOptions, NotebookTextModelChangedEvent, NotebookRawContentEvent, IOutputDto, ICellOutput, IOutputItemDto, ISelectionState, NullablePartialNotebookCellMetadata, NotebookCellInternalMetadata, NullablePartialNotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { IUndoRedoService, UndoRedoElementType, IUndoRedoElement, IResourceUndoRedoElement, UndoRedoGroup, IWorkspaceUndoRedoElement } from 'vs/platform/undoRedo/common/undoRedo';
import { MoveCellEdit, SpliceCellsEdit, CellMetadataEdit } from 'vs/workbench/contrib/notebook/common/model/cellEdit';
import { ISequence, LcsDiff } from 'vs/base/common/diff/diff';
@ -284,7 +284,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
const mainCells = cells.map(cell => {
const cellHandle = this._cellhandlePool++;
const cellUri = CellUri.generate(this.uri, cellHandle);
return new NotebookCellTextModel(cellUri, cellHandle, cell.source, cell.language, cell.cellKind, cell.outputs || [], cell.metadata, this.transientOptions, this._modeService);
return new NotebookCellTextModel(cellUri, cellHandle, cell.source, cell.language, cell.cellKind, cell.outputs || [], cell.metadata, cell.internalMetadata, this.transientOptions, this._modeService);
});
for (let i = 0; i < mainCells.length; i++) {
@ -475,6 +475,10 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
this._assertIndex(cellIndex);
this._changeCellMetadataPartial(this._cells[cellIndex], edit.metadata, computeUndoRedo);
break;
case CellEditType.PartialInternalMetadata:
this._assertIndex(cellIndex);
this._changeCellInternalMetadataPartial(this._cells[cellIndex], edit.internalMetadata);
break;
case CellEditType.CellLanguage:
this._assertIndex(edit.index);
this._changeCellLanguage(this._cells[edit.index], edit.language, computeUndoRedo);
@ -514,7 +518,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
const cellUri = CellUri.generate(this.uri, cellHandle);
const cell = new NotebookCellTextModel(
cellUri, cellHandle,
cellDto.source, cellDto.language, cellDto.cellKind, cellDto.outputs || [], cellDto.metadata, this.transientOptions,
cellDto.source, cellDto.language, cellDto.cellKind, cellDto.outputs || [], cellDto.metadata, cellDto.internalMetadata, this.transientOptions,
this._modeService
);
const textModel = this._modelService.getModel(cellUri);
@ -692,14 +696,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
private _isCellMetadataChanged(a: NotebookCellMetadata, b: NotebookCellMetadata) {
const keys = new Set([...Object.keys(a || {}), ...Object.keys(b || {})]);
for (let key of keys) {
if (key === 'custom') {
if (!this._customMetadataEqual(a[key], b[key])
&&
!(this.transientOptions.transientCellMetadata[key as keyof NotebookCellMetadata])
) {
return true;
}
} else if (
if (
(a[key as keyof NotebookCellMetadata] !== b[key as keyof NotebookCellMetadata])
&&
!(this.transientOptions.transientCellMetadata[key as keyof NotebookCellMetadata])
@ -745,7 +742,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
let k: keyof NullablePartialNotebookCellMetadata;
for (k in metadata) {
const value = metadata[k] ?? undefined;
newMetadata[k] = value as any; // TS...
newMetadata[k] = value as any;
}
return this._changeCellMetadata(cell, newMetadata, computeUndoRedo);
@ -763,10 +760,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
if (!cell) {
return;
}
this._changeCellMetadata(cell, {
...newMetadata,
runState: cell.metadata.runState
}, false);
this._changeCellMetadata(cell, newMetadata, false);
}
}), undefined, undefined);
}
@ -778,6 +772,20 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeCellMetadata, index: this._cells.indexOf(cell), metadata: cell.metadata, transient: !triggerDirtyChange }, true);
}
private _changeCellInternalMetadataPartial(cell: NotebookCellTextModel, internalMetadata: NullablePartialNotebookCellInternalMetadata) {
const newInternalMetadata: NotebookCellInternalMetadata = {
...cell.internalMetadata
};
let k: keyof NotebookCellInternalMetadata;
for (k in internalMetadata) {
const value = internalMetadata[k] ?? undefined;
newInternalMetadata[k] = value as any;
}
cell.internalMetadata = newInternalMetadata;
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeCellInternalMetadata, index: this._cells.indexOf(cell), internalMetadata: cell.internalMetadata, transient: true }, true);
}
private _changeCellLanguage(cell: NotebookCellTextModel, languageId: string, computeUndoRedo: boolean) {
if (cell.language === languageId) {
return;

View file

@ -80,12 +80,6 @@ export interface INotebookCellPreviousExecutionResult {
}
export interface NotebookCellMetadata {
executionOrder?: number;
lastRunSuccess?: boolean;
runState?: NotebookCellExecutionState;
runStartTime?: number;
runStartTimeAdjustment?: number;
runEndTime?: number;
inputCollapsed?: boolean;
outputCollapsed?: boolean;
@ -95,6 +89,15 @@ export interface NotebookCellMetadata {
[key: string]: unknown;
}
export interface NotebookCellInternalMetadata {
executionOrder?: number;
lastRunSuccess?: boolean;
runState?: NotebookCellExecutionState;
runStartTime?: number;
runStartTimeAdjustment?: number;
runEndTime?: number;
}
export type TransientCellMetadata = { [K in keyof NotebookCellMetadata]?: boolean };
export type TransientDocumentMetadata = { [K in keyof NotebookDocumentMetadata]?: boolean };
@ -182,7 +185,7 @@ export interface ICellOutput {
appendData(items: IOutputItemDto[]): void;
}
export interface CellMetadataChangedEvent {
export interface CellInternalMetadataChangedEvent {
readonly runStateChanged?: boolean;
}
@ -195,7 +198,8 @@ export interface ICell {
metadata?: NotebookCellMetadata;
onDidChangeOutputs?: Event<NotebookCellOutputsSplice[]>;
onDidChangeLanguage: Event<string>;
onDidChangeMetadata: Event<CellMetadataChangedEvent>;
onDidChangeMetadata: Event<void>;
onDidChangeInternalMetadata: Event<CellInternalMetadataChangedEvent>;
}
export interface INotebookTextModel {
@ -229,6 +233,7 @@ export interface IMainCellDto {
cellKind: CellKind;
outputs: IOutputDto[];
metadata?: NotebookCellMetadata;
internalMetadata?: NotebookCellInternalMetadata;
}
export type NotebookCellsSplice2 = [
@ -249,7 +254,8 @@ export enum NotebookCellsChangeType {
OutputItem = 9,
ChangeCellContent = 10,
ChangeDocumentMetadata = 11,
Unknown = 12
ChangeCellInternalMetadata = 12,
Unknown = 100
}
export interface NotebookCellsInitializeEvent<T> {
@ -300,6 +306,12 @@ export interface NotebookCellsChangeMetadataEvent {
readonly metadata: NotebookCellMetadata;
}
export interface NotebookCellsChangeInternalMetadataEvent {
readonly kind: NotebookCellsChangeType.ChangeCellInternalMetadata;
readonly index: number;
readonly internalMetadata: NotebookCellInternalMetadata;
}
export interface NotebookDocumentChangeMetadataEvent {
readonly kind: NotebookCellsChangeType.ChangeDocumentMetadata;
readonly metadata: NotebookDocumentMetadata;
@ -309,14 +321,14 @@ export interface NotebookDocumentUnknownChangeEvent {
readonly kind: NotebookCellsChangeType.Unknown;
}
export type NotebookRawContentEventDto = NotebookCellsInitializeEvent<IMainCellDto> | NotebookDocumentChangeMetadataEvent | NotebookCellContentChangeEvent | NotebookCellsModelChangedEvent<IMainCellDto> | NotebookCellsModelMoveEvent<IMainCellDto> | NotebookOutputChangedEvent | NotebookOutputItemChangedEvent | NotebookCellsChangeLanguageEvent | NotebookCellsChangeMetadataEvent | NotebookDocumentUnknownChangeEvent;
export type NotebookRawContentEventDto = NotebookCellsInitializeEvent<IMainCellDto> | NotebookDocumentChangeMetadataEvent | NotebookCellContentChangeEvent | NotebookCellsModelChangedEvent<IMainCellDto> | NotebookCellsModelMoveEvent<IMainCellDto> | NotebookOutputChangedEvent | NotebookOutputItemChangedEvent | NotebookCellsChangeLanguageEvent | NotebookCellsChangeMetadataEvent | NotebookCellsChangeInternalMetadataEvent | NotebookDocumentUnknownChangeEvent;
export type NotebookCellsChangedEventDto = {
readonly rawEvents: NotebookRawContentEventDto[];
readonly versionId: number;
};
export type NotebookRawContentEvent = (NotebookCellsInitializeEvent<ICell> | NotebookDocumentChangeMetadataEvent | NotebookCellContentChangeEvent | NotebookCellsModelChangedEvent<ICell> | NotebookCellsModelMoveEvent<ICell> | NotebookOutputChangedEvent | NotebookOutputItemChangedEvent | NotebookCellsChangeLanguageEvent | NotebookCellsChangeMetadataEvent | NotebookDocumentUnknownChangeEvent) & { transient: boolean; };
export type NotebookRawContentEvent = (NotebookCellsInitializeEvent<ICell> | NotebookDocumentChangeMetadataEvent | NotebookCellContentChangeEvent | NotebookCellsModelChangedEvent<ICell> | NotebookCellsModelMoveEvent<ICell> | NotebookOutputChangedEvent | NotebookOutputItemChangedEvent | NotebookCellsChangeLanguageEvent | NotebookCellsChangeMetadataEvent | NotebookCellsChangeInternalMetadataEvent | NotebookDocumentUnknownChangeEvent) & { transient: boolean; };
export enum SelectionStateType {
Handle = 0,
@ -352,7 +364,8 @@ export const enum CellEditType {
DocumentMetadata = 5,
Move = 6,
OutputItems = 7,
PartialMetadata = 8
PartialMetadata = 8,
PartialInternalMetadata = 9,
}
export interface ICellDto2 {
@ -361,6 +374,7 @@ export interface ICellDto2 {
cellKind: CellKind;
outputs: IOutputDto[];
metadata?: NotebookCellMetadata;
internalMetadata?: NotebookCellInternalMetadata;
}
export interface ICellReplaceEdit {
@ -404,7 +418,7 @@ export type NullablePartialNotebookCellMetadata = {
export interface ICellPartialMetadataEdit {
editType: CellEditType.PartialMetadata;
index: number;
metadata: Partial<NullablePartialNotebookCellMetadata>;
metadata: NullablePartialNotebookCellMetadata;
}
export interface ICellPartialMetadataEditByHandle {
@ -413,6 +427,21 @@ export interface ICellPartialMetadataEditByHandle {
metadata: Partial<NullablePartialNotebookCellMetadata>;
}
export type NullablePartialNotebookCellInternalMetadata = {
[Key in keyof Partial<NotebookCellInternalMetadata>]: NotebookCellInternalMetadata[Key] | null
};
export interface ICellPartialInternalMetadataEdit {
editType: CellEditType.PartialInternalMetadata;
index: number;
internalMetadata: NullablePartialNotebookCellInternalMetadata;
}
export interface ICellPartialInternalMetadataEditByHandle {
editType: CellEditType.PartialInternalMetadata;
handle: number;
internalMetadata: Partial<NullablePartialNotebookCellInternalMetadata>;
}
export interface ICellLanguageEdit {
editType: CellEditType.CellLanguage;
index: number;
@ -431,8 +460,8 @@ export interface ICellMoveEdit {
newIdx: number;
}
export type IImmediateCellEditOperation = ICellOutputEditByHandle | ICellPartialMetadataEditByHandle | ICellOutputItemEdit;
export type ICellEditOperation = IImmediateCellEditOperation | ICellReplaceEdit | ICellOutputEdit | ICellMetadataEdit | ICellPartialMetadataEdit | IDocumentMetadataEdit | ICellMoveEdit | ICellOutputItemEdit | ICellLanguageEdit;
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 {
readonly cells: ICellDto2[];

View file

@ -552,7 +552,8 @@ export class NotebookFileWorkingCopyModel implements IFileWorkingCopyModel {
cellKind: cell.cellKind,
language: cell.language,
source: cell.getValue(),
outputs: []
outputs: [],
internalMetadata: cell.internalMetadata
};
cellData.outputs = !this._notebookSerializer.options.transientOutputs ? cell.outputs : [];

View file

@ -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, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookCellsSplice2, NotebookDataDto, NotebookDocumentMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, ICellDto2, IMainCellDto, INotebookDiffResult, IOutputDto, NotebookCellInternalMetadata, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookCellsSplice2, NotebookDataDto, 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';
@ -46,7 +46,8 @@ class MirrorCell {
public language: string,
public cellKind: CellKind,
public outputs: IOutputDto[],
public metadata?: NotebookCellMetadata
public metadata?: NotebookCellMetadata,
public internalMetadata?: NotebookCellInternalMetadata,
) { }
@ -70,7 +71,7 @@ class MirrorCell {
return this._primaryKey!;
}
this._hash = hash([hash(this.language), hash(this.getValue()), this.metadata, this.outputs.map(op => ({
this._hash = hash([hash(this.language), hash(this.getValue()), this.metadata, this.internalMetadata, this.outputs.map(op => ({
outputs: op.outputs,
metadata: op.metadata
}))]);
@ -82,7 +83,7 @@ class MirrorCell {
return this._hash;
}
this._hash = hash([hash(this.getValue()), this.language, this.metadata]);
this._hash = hash([hash(this.getValue()), this.language, this.metadata, this.internalMetadata]);
return this._hash;
}
}
@ -114,6 +115,9 @@ class MirrorNotebookDocument {
} else if (e.kind === NotebookCellsChangeType.ChangeCellMetadata) {
const cell = this.cells[e.index];
cell.metadata = e.metadata;
} else if (e.kind === NotebookCellsChangeType.ChangeCellInternalMetadata) {
const cell = this.cells[e.index];
cell.internalMetadata = e.internalMetadata;
}
});
}

View file

@ -105,7 +105,8 @@ export class NotebookEditorModelManager extends Disposable {
language: cell.language,
cellKind: cell.cellKind,
outputs: cell.outputs.map(op => ({ outputId: op.outputId, outputs: op.outputs })),
metadata: cell.metadata
metadata: cell.metadata,
internalMetadata: cell.internalMetadata,
})),
metadata: model.metadata
}
@ -122,7 +123,8 @@ export class NotebookEditorModelManager extends Disposable {
language: cell.language,
cellKind: cell.cellKind,
outputs: cell.outputs,
metadata: cell.metadata
metadata: cell.metadata,
internalMetadata: cell.internalMetadata,
};
};

View file

@ -294,7 +294,7 @@ suite('NotebookTextModel', () => {
textModel.applyEdits([{
index: 0,
editType: CellEditType.Metadata,
metadata: { executionOrder: 15 },
metadata: { customProperty: 15 },
}], true, undefined, () => undefined, undefined);
textModel.applyEdits([{
@ -304,7 +304,7 @@ suite('NotebookTextModel', () => {
}], true, undefined, () => undefined, undefined);
assert.strictEqual(textModel.cells.length, 1);
assert.strictEqual(textModel.cells[0].metadata?.executionOrder, undefined);
assert.strictEqual(textModel.cells[0].metadata?.customProperty, undefined);
}
);
});
@ -320,7 +320,7 @@ suite('NotebookTextModel', () => {
textModel.applyEdits([{
index: 0,
editType: CellEditType.PartialMetadata,
metadata: { executionOrder: 15 },
metadata: { customProperty: 15 },
}], true, undefined, () => undefined, undefined);
textModel.applyEdits([{
@ -330,7 +330,7 @@ suite('NotebookTextModel', () => {
}], true, undefined, () => undefined, undefined);
assert.strictEqual(textModel.cells.length, 1);
assert.strictEqual(textModel.cells[0].metadata?.executionOrder, 15);
assert.strictEqual(textModel.cells[0].metadata?.customProperty, 15);
}
);
});

View file

@ -55,7 +55,7 @@ export class TestCell extends NotebookCellTextModel {
outputs: IOutputDto[],
modeService: IModeService,
) {
super(CellUri.generate(URI.parse('test:///fake/notebook'), handle), handle, source, language, cellKind, outputs, undefined, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false }, modeService);
super(CellUri.generate(URI.parse('test:///fake/notebook'), handle), handle, source, language, cellKind, outputs, undefined, undefined, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false }, modeService);
}
}

View file

@ -13,7 +13,7 @@ import { mock } from 'vs/base/test/common/mock';
import { IModelAddedData, MainContext, MainThreadCommandsShape, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
import { ExtHostNotebookDocument } from 'vs/workbench/api/common/extHostNotebookDocument';
import { CellKind, CellUri, NotebookCellExecutionState, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, CellUri, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { URI } from 'vs/base/common/uri';
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
@ -412,30 +412,4 @@ suite('NotebookCell#Document', function () {
assert.strictEqual(first.document.languageId, 'fooLang');
assert.ok(removedDoc === addedDoc);
});
test('change cell execution state does not trigger onDidChangeMetadata event', async function () {
let didFireOnDidChangeMetadata = false;
let e = extHostNotebooks.onDidChangeCellMetadata(() => {
didFireOnDidChangeMetadata = true;
});
const changeExeState = Event.toPromise(extHostNotebooks.onDidChangeNotebookCellExecutionState);
extHostNotebooks.$acceptModelChanged(notebook.uri, {
versionId: 12, rawEvents: [{
kind: NotebookCellsChangeType.ChangeCellMetadata,
index: 0,
metadata: {
...notebook.getCellFromIndex(0)?.internalMetadata,
...{
runState: NotebookCellExecutionState.Executing
}
}
}]
}, false);
await changeExeState;
assert.strictEqual(didFireOnDidChangeMetadata, false);
e.dispose();
});
});