diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 2f25fa41fe0..3dd87ac446e 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1035,10 +1035,21 @@ declare module 'vscode' { transientOutputs?: boolean; /** - * Controls if a meetadata property change will trigger notebook document content change and if it will be used in the diff editor - * Default to false. If the content provider doesn't persisit a metadata property in the file document, it should be set to true. + * @deprecated use transientCellMetadata instead */ transientMetadata?: { [K in keyof NotebookCellMetadata]?: boolean }; + + /** + * Controls if a cell metadata property change will trigger notebook document content change and if it will be used in the diff editor + * Default to false. If the content provider doesn't persisit a metadata property in the file document, it should be set to true. + */ + transientCellMetadata?: { [K in keyof NotebookCellMetadata]?: boolean }; + + /** + * Controls if a document metadata property change will trigger notebook document content change and if it will be used in the diff editor + * Default to false. If the content provider doesn't persisit a metadata property in the file document, it should be set to true. + */ + transientDocumentMetadata?: { [K in keyof NotebookDocumentMetadata]?: boolean }; } export interface NotebookDocument { diff --git a/src/vs/workbench/api/browser/mainThreadNotebook.ts b/src/vs/workbench/api/browser/mainThreadNotebook.ts index be31750123b..ad7fc64e50b 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebook.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebook.ts @@ -14,7 +14,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService'; import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService'; -import { ICellRange, INotebookCellStatusBarItemProvider, INotebookDocumentFilter, INotebookExclusiveDocumentFilter, INotebookKernel, NotebookDataDto, TransientMetadata, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { ICellRange, INotebookCellStatusBarItemProvider, INotebookDocumentFilter, INotebookExclusiveDocumentFilter, INotebookKernel, NotebookDataDto, TransientCellMetadata, TransientDocumentMetadata, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { IMainNotebookController, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, MainContext, MainThreadNotebookShape, NotebookExtensionDescription } from '../common/extHost.protocol'; @@ -65,17 +65,19 @@ export class MainThreadNotebooks implements MainThreadNotebookShape { async $registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string, options: { transientOutputs: boolean; - transientMetadata: TransientMetadata; + transientCellMetadata: TransientCellMetadata; + transientDocumentMetadata: TransientDocumentMetadata; viewOptions?: { displayName: string; filenamePattern: (string | IRelativePattern | INotebookExclusiveDocumentFilter)[]; exclusive: boolean; }; }): Promise { - let contentOptions = { transientOutputs: options.transientOutputs, transientMetadata: options.transientMetadata }; + let contentOptions = { transientOutputs: options.transientOutputs, transientCellMetadata: options.transientCellMetadata, transientDocumentMetadata: options.transientDocumentMetadata }; const controller: IMainNotebookController = { get options() { return contentOptions; }, set options(newOptions) { - contentOptions.transientMetadata = newOptions.transientMetadata; + contentOptions.transientCellMetadata = newOptions.transientCellMetadata; + contentOptions.transientDocumentMetadata = newOptions.transientDocumentMetadata; contentOptions.transientOutputs = newOptions.transientOutputs; }, viewOptions: options.viewOptions, @@ -107,7 +109,7 @@ export class MainThreadNotebooks implements MainThreadNotebookShape { this._notebookProviders.set(viewType, { controller, disposable }); } - async $updateNotebookProviderOptions(viewType: string, options?: { transientOutputs: boolean; transientMetadata: TransientMetadata; }): Promise { + async $updateNotebookProviderOptions(viewType: string, options?: { transientOutputs: boolean; transientCellMetadata: TransientCellMetadata; transientDocumentMetadata: TransientDocumentMetadata; }): Promise { const provider = this._notebookProviders.get(viewType); if (provider && options) { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 8d2b7126b29..eba9420ea93 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -50,7 +50,7 @@ import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService'; import { TunnelCreationOptions, TunnelProviderFeatures, TunnelOptions, ProvidedPortAttributes } from 'vs/platform/remote/common/tunnel'; import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor, InternalTimelineOptions } from 'vs/workbench/contrib/timeline/common/timeline'; import { revive } from 'vs/base/common/marshalling'; -import { NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEventDto, NotebookDataDto, IMainCellDto, INotebookDocumentFilter, TransientMetadata, ICellRange, INotebookDecorationRenderOptions, INotebookExclusiveDocumentFilter, IOutputDto, TransientOptions, IImmediateCellEditOperation, INotebookCellStatusBarItem } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEventDto, NotebookDataDto, IMainCellDto, INotebookDocumentFilter, TransientCellMetadata, ICellRange, INotebookDecorationRenderOptions, INotebookExclusiveDocumentFilter, IOutputDto, TransientOptions, IImmediateCellEditOperation, INotebookCellStatusBarItem, TransientDocumentMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { CallHierarchyItem } from 'vs/workbench/contrib/callHierarchy/common/callHierarchy'; import { Dto } from 'vs/base/common/types'; import { DebugConfigurationProviderTriggerKind, TestResultState } from 'vs/workbench/api/common/extHostTypes'; @@ -874,10 +874,11 @@ export interface INotebookCellStatusBarListDto { export interface MainThreadNotebookShape extends IDisposable { $registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string, options: { transientOutputs: boolean; - transientMetadata: TransientMetadata; + transientCellMetadata: TransientCellMetadata; + transientDocumentMetadata: TransientDocumentMetadata; viewOptions?: { displayName: string; filenamePattern: (string | IRelativePattern | INotebookExclusiveDocumentFilter)[]; exclusive: boolean; }; }): Promise; - $updateNotebookProviderOptions(viewType: string, options?: { transientOutputs: boolean; transientMetadata: TransientMetadata; }): Promise; + $updateNotebookProviderOptions(viewType: string, options?: { transientOutputs: boolean; transientCellMetadata: TransientCellMetadata; transientDocumentMetadata: TransientDocumentMetadata; }): Promise; $unregisterNotebookProvider(viewType: string): Promise; $registerNotebookSerializer(handle: number, extension: NotebookExtensionDescription, viewType: string, options: TransientOptions): void; diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index 7c2367c41f2..534c4e6b32f 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -18,7 +18,7 @@ import { ICommandsExecutor, RemoveFromRecentlyOpenedAPICommand, OpenIssueReporte import { isFalsyOrEmpty } from 'vs/base/common/arrays'; import { IRange } from 'vs/editor/common/core/range'; import { IPosition } from 'vs/editor/common/core/position'; -import { TransientMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { TransientCellMetadata, TransientDocumentMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { VSBuffer } from 'vs/base/common/buffer'; import { decodeSemanticTokensDto } from 'vs/editor/common/services/semanticTokensDto'; @@ -343,7 +343,7 @@ const newCommands: ApiCommand[] = [ new ApiCommandResult<{ viewType: string; displayName: string; - options: { transientOutputs: boolean; transientMetadata: TransientMetadata }; + options: { transientOutputs: boolean; transientCellMetadata: TransientCellMetadata; transientDocumentMetadata: TransientDocumentMetadata; }; filenamePattern: (string | types.RelativePattern | { include: string | types.RelativePattern, exclude: string | types.RelativePattern })[] }[], { viewType: string; @@ -354,7 +354,12 @@ const newCommands: ApiCommand[] = [ return { viewType: item.viewType, displayName: item.displayName, - options: { transientOutputs: item.options.transientOutputs, transientMetadata: item.options.transientMetadata }, + options: { + transientOutputs: item.options.transientOutputs, + transientMetadata: item.options.transientCellMetadata, + transientCellMetadata: item.options.transientCellMetadata, + transientDocumentMetadata: item.options.transientDocumentMetadata + }, filenamePattern: item.filenamePattern.map(pattern => typeConverters.NotebookExclusiveDocumentPattern.to(pattern)) }; })) diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index 76d2868f15f..a391c3fc2cd 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -376,7 +376,8 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { const internalOptions = typeConverters.NotebookDocumentContentOptions.from(options); this._notebookProxy.$registerNotebookProvider({ id: extension.identifier, location: extension.extensionLocation, description: extension.description }, viewType, { transientOutputs: internalOptions.transientOutputs, - transientMetadata: internalOptions.transientMetadata, + transientCellMetadata: internalOptions.transientCellMetadata, + transientDocumentMetadata: internalOptions.transientDocumentMetadata, viewOptions: options?.viewOptions && viewOptionsFilenamePattern ? { displayName: options.viewOptions.displayName, filenamePattern: viewOptionsFilenamePattern, exclusive: options.viewOptions.exclusive || false } : undefined }); diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 66a4a2096c7..0e038d0388d 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -1633,15 +1633,16 @@ export namespace NotebookDocumentContentOptions { export function from(options: vscode.NotebookDocumentContentOptions | undefined): notebooks.TransientOptions { return { transientOutputs: options?.transientOutputs ?? false, - transientMetadata: { - ...options?.transientMetadata, + transientCellMetadata: { + ...(options?.transientCellMetadata ?? options?.transientMetadata), executionOrder: true, runState: true, runStartTime: true, runStartTimeAdjustment: true, runEndTime: true, lastRunSuccess: true - } + }, + transientDocumentMetadata: options?.transientDocumentMetadata ?? {} }; } } diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts b/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts index 824b8e53b48..24c56ad1139 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts @@ -19,7 +19,7 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IQuickInputService, IQuickPickItem, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; import { BaseCellRenderTemplate, CellEditState, CellFocusMode, EXECUTE_CELL_COMMAND_ID, EXPAND_CELL_INPUT_COMMAND_ID, getNotebookEditorFromEditorPane, IActiveNotebookEditor, ICellViewModel, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_HAS_OUTPUTS, NOTEBOOK_CELL_INPUT_COLLAPSED, NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_OUTPUT_COLLAPSED, NOTEBOOK_CELL_EXECUTION_STATE, NOTEBOOK_CELL_TYPE, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_KERNEL_COUNT, NOTEBOOK_OUTPUT_FOCUSED, NOTEBOOK_INTERRUPTIBLE_KERNEL, NOTEBOOK_HAS_RUNNING_CELL, CHANGE_CELL_LANGUAGE, QUIT_EDIT_CELL_COMMAND_ID } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; -import { CellEditType, CellKind, ICellEditOperation, ICellRange, INotebookDocumentFilter, isDocumentExcludePattern, NotebookCellMetadata, NotebookCellExecutionState, NOTEBOOK_EDITOR_CURSOR_BOUNDARY, TransientMetadata, SelectionStateType, ICellReplaceEdit } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType, CellKind, ICellEditOperation, ICellRange, INotebookDocumentFilter, isDocumentExcludePattern, NotebookCellMetadata, NotebookCellExecutionState, NOTEBOOK_EDITOR_CURSOR_BOUNDARY, TransientCellMetadata, TransientDocumentMetadata, SelectionStateType, ICellReplaceEdit } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -1692,7 +1692,7 @@ CommandsRegistry.registerCommand('notebook.trust', (accessor, args) => { CommandsRegistry.registerCommand('_resolveNotebookContentProvider', (accessor, args): { viewType: string; displayName: string; - options: { transientOutputs: boolean; transientMetadata: TransientMetadata; }; + options: { transientOutputs: boolean; transientCellMetadata: TransientCellMetadata; transientDocumentMetadata: TransientDocumentMetadata; }; filenamePattern: (string | glob.IRelativePattern | { include: string | glob.IRelativePattern, exclude: string | glob.IRelativePattern; })[]; }[] => { const notebookService = accessor.get(INotebookService); @@ -1721,7 +1721,11 @@ CommandsRegistry.registerCommand('_resolveNotebookContentProvider', (accessor, a viewType: provider.id, displayName: provider.displayName, filenamePattern: filenamePatterns, - options: { transientMetadata: provider.options.transientMetadata, transientOutputs: provider.options.transientOutputs } + options: { + transientCellMetadata: provider.options.transientCellMetadata, + transientDocumentMetadata: provider.options.transientDocumentMetadata, + transientOutputs: provider.options.transientOutputs + } }; }); }); diff --git a/src/vs/workbench/contrib/notebook/browser/diff/diffElementViewModel.ts b/src/vs/workbench/contrib/notebook/browser/diff/diffElementViewModel.ts index 53c6484ba10..925415cd8ba 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/diffElementViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/diffElementViewModel.ts @@ -493,11 +493,11 @@ export function getFormatedMetadataJSON(documentTextModel: NotebookTextModel, me let filteredMetadata: { [key: string]: any } = {}; if (documentTextModel) { - const transientMetadata = documentTextModel.transientOptions.transientMetadata; + const transientCellMetadata = documentTextModel.transientOptions.transientCellMetadata; const keys = new Set([...Object.keys(metadata)]); for (let key of keys) { - if (!(transientMetadata[key as keyof NotebookCellMetadata]) + if (!(transientCellMetadata[key as keyof NotebookCellMetadata]) ) { filteredMetadata[key] = metadata[key as keyof NotebookCellMetadata]; } diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts index 31d4fb746b9..b5e6a193a79 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts @@ -159,11 +159,11 @@ export class NotebookCellTextModel extends Disposable implements ICell { private _getPersisentMetadata() { let filteredMetadata: { [key: string]: any } = {}; - const transientMetadata = this.transientOptions.transientMetadata; + const transientCellMetadata = this.transientOptions.transientCellMetadata; const keys = new Set([...Object.keys(this.metadata)]); for (let key of keys) { - if (!(transientMetadata[key as keyof NotebookCellMetadata]) + if (!(transientCellMetadata[key as keyof NotebookCellMetadata]) ) { filteredMetadata[key] = this.metadata[key as keyof NotebookCellMetadata]; } diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts index 2db4d08fc7e..9b89f9d44d6 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts @@ -193,7 +193,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel private _cells: NotebookCellTextModel[] = []; metadata: NotebookDocumentMetadata = notebookDocumentMetadataDefaults; - transientOptions: TransientOptions = { transientMetadata: {}, transientOutputs: false }; + transientOptions: TransientOptions = { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false }; private _versionId = 0; /** @@ -601,14 +601,14 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel if (key === 'custom') { if (!this._customMetadataEqual(a[key], b[key]) && - !(this.transientOptions.transientMetadata[key as keyof NotebookCellMetadata]) + !(this.transientOptions.transientCellMetadata[key as keyof NotebookCellMetadata]) ) { return true; } } else if ( (a[key as keyof NotebookCellMetadata] !== b[key as keyof NotebookCellMetadata]) && - !(this.transientOptions.transientMetadata[key as keyof NotebookCellMetadata]) + !(this.transientOptions.transientCellMetadata[key as keyof NotebookCellMetadata]) ) { return true; } diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index aab2b90d113..a22954a200e 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -92,11 +92,13 @@ export interface NotebookCellMetadata { custom?: { [key: string]: unknown }; } -export type TransientMetadata = { [K in keyof NotebookCellMetadata]?: boolean }; +export type TransientCellMetadata = { [K in keyof NotebookCellMetadata]?: boolean }; +export type TransientDocumentMetadata = { [K in keyof NotebookDocumentMetadata]?: boolean }; export interface TransientOptions { transientOutputs: boolean; - transientMetadata: TransientMetadata; + transientCellMetadata: TransientCellMetadata; + transientDocumentMetadata: TransientDocumentMetadata; } export interface INotebookMimeTypeSelector { diff --git a/src/vs/workbench/contrib/notebook/common/notebookProvider.ts b/src/vs/workbench/contrib/notebook/common/notebookProvider.ts index a47f5375465..25fe5afc6bd 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookProvider.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookProvider.ts @@ -61,7 +61,8 @@ export class NotebookProviderInfo { this.dynamicContribution = descriptor.dynamicContribution; this.exclusive = descriptor.exclusive; this._options = { - transientMetadata: {}, + transientCellMetadata: {}, + transientDocumentMetadata: {}, transientOutputs: false }; } diff --git a/src/vs/workbench/contrib/notebook/test/notebookViewModel.test.ts b/src/vs/workbench/contrib/notebook/test/notebookViewModel.test.ts index 213b6c019be..86556d7032b 100644 --- a/src/vs/workbench/contrib/notebook/test/notebookViewModel.test.ts +++ b/src/vs/workbench/contrib/notebook/test/notebookViewModel.test.ts @@ -34,7 +34,7 @@ suite('NotebookViewModel', () => { instantiationService.stub(IThemeService, new TestThemeService()); test('ctor', function () { - const notebook = new NotebookTextModel('notebook', URI.parse('test'), [], notebookDocumentMetadataDefaults, { transientMetadata: {}, transientOutputs: false }, undoRedoService, modelService, modeService); + const notebook = new NotebookTextModel('notebook', URI.parse('test'), [], notebookDocumentMetadataDefaults, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false }, undoRedoService, modelService, modeService); const model = new NotebookEditorTestModel(notebook); const eventDispatcher = new NotebookEventDispatcher(); const viewModel = new NotebookViewModel('notebook', model.notebook, eventDispatcher, null, instantiationService, bulkEditService, undoRedoService, textModelService); diff --git a/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts b/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts index ddc046d8f79..70a88c92cb3 100644 --- a/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/test/testNotebookEditor.ts @@ -47,7 +47,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, { transientMetadata: {}, transientOutputs: false }, modeService); + super(CellUri.generate(URI.parse('test:///fake/notebook'), handle), handle, source, language, cellKind, outputs, undefined, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false }, modeService); } } @@ -152,7 +152,7 @@ function _createTestNotebookEditor(instantiationService: TestInstantiationServic outputs: cell[3] ?? [], metadata: cell[4] }; - }), notebookDocumentMetadataDefaults, { transientMetadata: {}, transientOutputs: false }); + }), notebookDocumentMetadataDefaults, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false }); const model = new NotebookEditorTestModel(notebook); const eventDispatcher = new NotebookEventDispatcher();