diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index c5af149c3bf..c14fc898172 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1599,6 +1599,11 @@ declare module 'vscode' { readonly language: string; } + export interface NotebookCellMetadataChangeEvent { + readonly document: NotebookDocument; + readonly cell: NotebookCell; + } + export interface NotebookCellData { readonly cellKind: CellKind; readonly source: string; @@ -1789,6 +1794,7 @@ declare module 'vscode' { export const onDidChangeNotebookCells: Event; export const onDidChangeCellOutputs: Event; export const onDidChangeCellLanguage: Event; + export const onDidChangeCellMetadata: Event; /** * Create a document that is the concatenation of all notebook cells. By default all code-cells are included * but a selector can be provided to narrow to down the set of cells. diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 88d5b279c23..9fceb27f945 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -973,6 +973,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I checkProposedApiEnabled(extension); return extHostNotebook.onDidChangeCellLanguage(listener, thisArgs, disposables); }, + onDidChangeCellMetadata(listener, thisArgs?, disposables?) { + checkProposedApiEnabled(extension); + return extHostNotebook.onDidChangeCellMetadata(listener, thisArgs, disposables); + }, createConcatTextDocument(notebook, selector) { checkProposedApiEnabled(extension); return new ExtHostNotebookConcatDocument(extHostNotebook, extHostDocuments, notebook, selector); diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index 683fbf3a236..24ae1bac5ab 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -14,7 +14,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' import { CellKind, ExtHostNotebookShape, IMainContext, MainContext, MainThreadNotebookShape, NotebookCellOutputsSplice, MainThreadDocumentsShape, INotebookEditorPropertiesChangeData, INotebookDocumentsAndEditorsDelta } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { CellEditType, diff, ICellEditOperation, ICellInsertEdit, INotebookDisplayOrder, INotebookEditData, NotebookCellsChangedEvent, NotebookCellsSplice2, ICellDeleteEdit, notebookDocumentMetadataDefaults, NotebookCellsChangeType, NotebookDataDto, IOutputRenderRequest, IOutputRenderResponse, IOutputRenderResponseOutputInfo, IOutputRenderResponseCellInfo, IRawOutput, CellOutputKind, IProcessedOutput, INotebookKernelInfoDto2, IMainCellDto } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellEditType, diff, ICellEditOperation, ICellInsertEdit, INotebookDisplayOrder, INotebookEditData, NotebookCellsChangedEvent, NotebookCellsSplice2, ICellDeleteEdit, notebookDocumentMetadataDefaults, NotebookCellsChangeType, NotebookDataDto, IOutputRenderRequest, IOutputRenderResponse, IOutputRenderResponseOutputInfo, IOutputRenderResponseCellInfo, IRawOutput, CellOutputKind, IProcessedOutput, INotebookKernelInfoDto2, IMainCellDto, NotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData'; @@ -52,6 +52,7 @@ interface INotebookEventEmitter { emitModelChange(events: vscode.NotebookCellsChangeEvent): void; emitCellOutputsChange(event: vscode.NotebookCellOutputsChangeEvent): void; emitCellLanguageChange(event: vscode.NotebookCellLanguageChangeEvent): void; + emitCellMetadataChange(event: vscode.NotebookCellMetadataChangeEvent): void; } const addIdToOutput = (output: IRawOutput, id = UUID.generateUuid()): IProcessedOutput => output.outputKind === CellOutputKind.Rich @@ -172,6 +173,11 @@ export class ExtHostCell extends Disposable implements vscode.NotebookCell { } set metadata(newMetadata: vscode.NotebookCellMetadata) { + this.setMetadata(newMetadata); + this._updateMetadata(); + } + + setMetadata(newMetadata: vscode.NotebookCellMetadata): void { // Don't apply metadata defaults here, 'undefined' means 'inherit from document metadata' this._metadataChangeListener.dispose(); const observableMetadata = getObservable(newMetadata); @@ -179,8 +185,6 @@ export class ExtHostCell extends Disposable implements vscode.NotebookCell { this._metadataChangeListener = this._register(observableMetadata.onDidChange(() => { this._updateMetadata(); })); - - this._updateMetadata(); } private _updateMetadata(): Promise { @@ -346,7 +350,7 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo get isDirty() { return false; } - accpetModelChanged(event: NotebookCellsChangedEvent): void { + acceptModelChanged(event: NotebookCellsChangedEvent): void { this._versionId = event.versionId; if (event.kind === NotebookCellsChangeType.Initialize) { this.$spliceNotebookCells(event.changes, true); @@ -360,6 +364,8 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo this.$clearAllCellOutputs(); } else if (event.kind === NotebookCellsChangeType.ChangeLanguage) { this.$changeCellLanguage(event.index, event.language); + } else if (event.kind === NotebookCellsChangeType.ChangeMetadata) { + this.$changeCellMetadata(event.index, event.metadata); } } @@ -461,6 +467,13 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo this._emitter.emitCellLanguageChange(event); } + private $changeCellMetadata(index: number, newMetadata: NotebookCellMetadata): void { + const cell = this.cells[index]; + cell.setMetadata(newMetadata); + const event: vscode.NotebookCellMetadataChangeEvent = { document: this, cell }; + this._emitter.emitCellMetadataChange(event); + } + async eventuallyUpdateCellOutputs(cell: ExtHostCell, diffs: ISplice[]) { let renderers = new Set(); let outputDtos: NotebookCellOutputsSplice[] = diffs.map(diff => { @@ -888,6 +901,8 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN readonly onDidChangeCellOutputs = this._onDidChangeCellOutputs.event; private readonly _onDidChangeCellLanguage = new Emitter(); readonly onDidChangeCellLanguage = this._onDidChangeCellLanguage.event; + private readonly _onDidChangeCellMetadata = new Emitter(); + readonly onDidChangeCellMetadata = this._onDidChangeCellMetadata.event; private readonly _onDidChangeActiveNotebookEditor = new Emitter(); readonly onDidChangeActiveNotebookEditor = this._onDidChangeActiveNotebookEditor.event; @@ -1179,7 +1194,10 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN }, emitCellLanguageChange(event: vscode.NotebookCellLanguageChangeEvent): void { that._onDidChangeCellLanguage.fire(event); - } + }, + emitCellMetadataChange(event: vscode.NotebookCellMetadataChangeEvent): void { + that._onDidChangeCellMetadata.fire(event); + }, }, viewType, revivedUri, this, storageRoot); this._unInitializedDocuments.set(revivedUri.toString(), document); } @@ -1424,7 +1442,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN const document = this._documents.get(URI.revive(uriComponents).toString()); if (document) { - document.accpetModelChanged(event); + document.acceptModelChanged(event); } } @@ -1538,6 +1556,9 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN }, emitCellLanguageChange(event: vscode.NotebookCellLanguageChangeEvent): void { that._onDidChangeCellLanguage.fire(event); + }, + emitCellMetadataChange(event: vscode.NotebookCellMetadataChangeEvent): void { + that._onDidChangeCellMetadata.fire(event); } }, viewType, revivedUri, this, storageRoot); @@ -1549,7 +1570,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN }; } - document.accpetModelChanged({ + document.acceptModelChanged({ kind: NotebookCellsChangeType.Initialize, versionId: modelData.versionId, changes: [[ diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts b/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts index 10a484d8c60..7c1d2d9cf4f 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/coreActions.ts @@ -17,7 +17,7 @@ import { InputFocusedContext, InputFocusedContextKey } from 'vs/platform/context 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, CellCollapseState, CellEditState, CellFocusMode, ICellViewModel, INotebookEditor, NOTEBOOK_CELL_INPUT_COLLAPSED, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_HAS_OUTPUTS, NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_OUTPUT_COLLAPSED, NOTEBOOK_CELL_TYPE, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_EDITOR_RUNNABLE, NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_OUTPUT_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { BaseCellRenderTemplate, CellEditState, CellFocusMode, ICellViewModel, INotebookEditor, NOTEBOOK_CELL_INPUT_COLLAPSED, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_HAS_OUTPUTS, NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_OUTPUT_COLLAPSED, NOTEBOOK_CELL_TYPE, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_EDITOR_RUNNABLE, NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_OUTPUT_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel'; import { CellKind, CellUri, NotebookCellRunState, NOTEBOOK_EDITOR_CURSOR_BOUNDARY } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; @@ -1314,7 +1314,7 @@ registerAction2(class extends NotebookCellAction { } async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise { - context.cell.collapseState = CellCollapseState.Collapsed; + context.notebookEditor.viewModel!.notebookDocument.changeCellMetadata(context.cell.handle, { inputCollapsed: true }); } }); @@ -1337,7 +1337,7 @@ registerAction2(class extends NotebookCellAction { } async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise { - context.cell.collapseState = CellCollapseState.Normal; + context.notebookEditor.viewModel!.notebookDocument.changeCellMetadata(context.cell.handle, { inputCollapsed: false }); } }); @@ -1360,7 +1360,7 @@ registerAction2(class extends NotebookCellAction { } async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise { - context.cell.outputCollapseState = CellCollapseState.Collapsed; + context.notebookEditor.viewModel!.notebookDocument.changeCellMetadata(context.cell.handle, { outputCollapsed: true }); } }); @@ -1383,6 +1383,6 @@ registerAction2(class extends NotebookCellAction { } async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise { - context.cell.outputCollapseState = CellCollapseState.Normal; + context.notebookEditor.viewModel!.notebookDocument.changeCellMetadata(context.cell.handle, { inputCollapsed: false }); } }); diff --git a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts index 06956b5c146..1747484b280 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts @@ -113,8 +113,6 @@ export interface ICellViewModel { readonly model: NotebookCellTextModel; readonly id: string; readonly textBuffer: IReadonlyTextBuffer; - collapseState: CellCollapseState; - outputCollapseState: CellCollapseState; dragging: boolean; handle: number; uri: URI; @@ -547,11 +545,6 @@ export enum CellEditState { Editing } -export enum CellCollapseState { - Normal, - Collapsed -} - export enum CellFocusMode { Container, Editor diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index b7495da8c96..e303984d8a5 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -14,7 +14,7 @@ import * as UUID from 'vs/base/common/uuid'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IOpenerService, matchesScheme } from 'vs/platform/opener/common/opener'; import { CELL_MARGIN, CELL_RUN_GUTTER, CODE_CELL_LEFT_MARGIN, CELL_OUTPUT_PADDING } from 'vs/workbench/contrib/notebook/browser/constants'; -import { CellCollapseState, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; import { CellOutputKind, IProcessedOutput } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; @@ -561,7 +561,7 @@ ${loaderJs} return; } - if (cell.outputCollapseState === CellCollapseState.Collapsed) { + if (cell.metadata?.outputCollapsed) { return false; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys.ts index 3272aff7d98..3c3b9eac7f4 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys.ts @@ -6,7 +6,7 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { INotebookTextModel, NotebookCellRunState } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel'; -import { NOTEBOOK_CELL_TYPE, NOTEBOOK_VIEW_TYPE, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_RUNNABLE, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_RUN_STATE, NOTEBOOK_CELL_HAS_OUTPUTS, CellViewModelStateChangeEvent, CellEditState, NOTEBOOK_CELL_INPUT_COLLAPSED, CellCollapseState, NOTEBOOK_CELL_OUTPUT_COLLAPSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { NOTEBOOK_CELL_TYPE, NOTEBOOK_VIEW_TYPE, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_RUNNABLE, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_RUN_STATE, NOTEBOOK_CELL_HAS_OUTPUTS, CellViewModelStateChangeEvent, CellEditState, NOTEBOOK_CELL_INPUT_COLLAPSED, NOTEBOOK_CELL_OUTPUT_COLLAPSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; @@ -109,8 +109,8 @@ export class CellContextKeyManager extends Disposable { } private updateForCollapseState() { - this.cellContentCollapsed.set(this.element.collapseState === CellCollapseState.Collapsed); - this.cellOutputCollapsed.set(this.element.outputCollapseState === CellCollapseState.Collapsed); + this.cellContentCollapsed.set(!!this.element.metadata?.inputCollapsed); + this.cellOutputCollapsed.set(!!this.element.metadata?.outputCollapsed); } private updateForOutputs() { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts index d0b8d958d68..b4fbd1618f0 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -38,7 +38,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_BOTTOM_MARGIN, CELL_TOP_MARGIN, EDITOR_BOTTOM_PADDING, EDITOR_TOOLBAR_HEIGHT, EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants'; import { CancelCellAction, ChangeCellLanguageAction, ExecuteCellAction, INotebookCellActionContext } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions'; -import { BaseCellRenderTemplate, CellCollapseState, CellEditState, CodeCellRenderTemplate, ICellViewModel, INotebookCellList, INotebookEditor, isCodeCellRenderTemplate, MarkdownCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { BaseCellRenderTemplate, CellEditState, CodeCellRenderTemplate, ICellViewModel, INotebookCellList, INotebookEditor, isCodeCellRenderTemplate, MarkdownCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellContextKeyManager } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys'; import { CellMenus } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellMenus'; import { CodeCell } from 'vs/workbench/contrib/notebook/browser/view/renderers/codeCell'; @@ -317,10 +317,10 @@ abstract class AbstractCellRenderer { return; } - if (templateData.currentRenderedCell.collapseState === CellCollapseState.Collapsed) { - templateData.currentRenderedCell.collapseState = CellCollapseState.Normal; - } else if (templateData.currentRenderedCell.outputCollapseState === CellCollapseState.Collapsed) { - templateData.currentRenderedCell.outputCollapseState = CellCollapseState.Normal; + if (templateData.currentRenderedCell.metadata?.inputCollapsed) { + this.notebookEditor.viewModel!.notebookDocument.changeCellMetadata(templateData.currentRenderedCell.handle, { inputCollapsed: false }); + } else if (templateData.currentRenderedCell.metadata?.outputCollapsed) { + this.notebookEditor.viewModel!.notebookDocument.changeCellMetadata(templateData.currentRenderedCell.handle, { outputCollapsed: false }); } })); } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts index 362316b3a15..7c50a3e7b47 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts @@ -11,7 +11,7 @@ import { IModeService } from 'vs/editor/common/services/modeService'; import * as nls from 'vs/nls'; import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { EDITOR_BOTTOM_PADDING, EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants'; -import { CellCollapseState, CellFocusMode, CodeCellRenderTemplate, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellFocusMode, CodeCellRenderTemplate, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { getResizesObserver } from 'vs/workbench/contrib/notebook/browser/view/renderers/sizeObserver'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; @@ -305,11 +305,11 @@ export class CodeCell extends Disposable { } private viewUpdate(): void { - if (this.viewCell.collapseState === CellCollapseState.Collapsed && this.viewCell.outputCollapseState === CellCollapseState.Collapsed) { + if (this.viewCell.metadata?.inputCollapsed && this.viewCell.metadata.outputCollapsed) { this.viewUpdateAllCollapsed(); - } else if (this.viewCell.collapseState === CellCollapseState.Collapsed) { + } else if (this.viewCell.metadata?.inputCollapsed) { this.viewUpdateInputCollapsed(); - } else if (this.viewCell.outputCollapseState === CellCollapseState.Collapsed && this.viewCell.outputs.length) { + } else if (this.viewCell.metadata?.outputCollapsed && this.viewCell.outputs.length) { this.viewUpdateOutputCollapsed(); } else { this.viewUpdateExpanded(); diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/markdownCell.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/markdownCell.ts index 1ef055e3161..334187e139e 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/markdownCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/markdownCell.ts @@ -12,7 +12,7 @@ import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { EDITOR_BOTTOM_PADDING, EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants'; -import { CellEditState, CellFocusMode, INotebookEditor, MarkdownCellRenderTemplate, ICellViewModel, CellCollapseState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellEditState, CellFocusMode, INotebookEditor, MarkdownCellRenderTemplate, ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellFoldingState } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel'; import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -132,7 +132,7 @@ export class StatefulMarkdownCell extends Disposable { } private viewUpdate(): void { - if (this.viewCell.collapseState === CellCollapseState.Collapsed) { + if (this.viewCell.metadata?.inputCollapsed) { this.viewUpdateCollapsed(); } else if (this.viewCell.editState === CellEditState.Editing) { this.viewUpdateEditing(); diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts index 4a1c3cafb32..01de3cfb56a 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts @@ -13,7 +13,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import * as model from 'vs/editor/common/model'; import { SearchParams } from 'vs/editor/common/model/textModelSearch'; import { EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants'; -import { CellEditState, CellFocusMode, CursorAtBoundary, CellViewModelStateChangeEvent, IEditableCellViewModel, INotebookCellDecorationOptions, CellCollapseState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellEditState, CellFocusMode, CursorAtBoundary, CellViewModelStateChangeEvent, IEditableCellViewModel, INotebookCellDecorationOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellKind, NotebookCellMetadata, NotebookDocumentMetadata, INotebookSearchOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; @@ -60,28 +60,6 @@ export abstract class BaseCellViewModel extends Disposable { } } - public get collapseState(): CellCollapseState { - return this.metadata?.inputCollapsed ? CellCollapseState.Collapsed : CellCollapseState.Normal; - } - - public set collapseState(v: CellCollapseState) { - this.model.metadata = { - ...this.metadata, - ...{ inputCollapsed: v === CellCollapseState.Collapsed } - }; - } - - public get outputCollapseState(): CellCollapseState { - return this.metadata?.outputCollapsed ? CellCollapseState.Collapsed : CellCollapseState.Normal; - } - - public set outputCollapseState(v: CellCollapseState) { - this.model.metadata = { - ...this.metadata, - ...{ outputCollapsed: v === CellCollapseState.Collapsed } - }; - } - private _focusMode: CellFocusMode = CellFocusMode.Container; get focusMode() { return this._focusMode; diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel.ts index e941147a358..306c9722c8d 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel.ts @@ -9,7 +9,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import * as model from 'vs/editor/common/model'; import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer'; import { BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_MARGIN, CELL_RUN_GUTTER, CELL_STATUSBAR_HEIGHT, EDITOR_BOTTOM_PADDING, EDITOR_TOOLBAR_HEIGHT, CELL_TOP_MARGIN, EDITOR_TOP_PADDING, CELL_BOTTOM_MARGIN, CODE_CELL_LEFT_MARGIN, BOTTOM_CELL_TOOLBAR_OFFSET, COLLAPSED_INDICATOR_HEIGHT } from 'vs/workbench/contrib/notebook/browser/constants'; -import { CellEditState, CellFindMatch, CodeCellLayoutChangeEvent, CodeCellLayoutInfo, ICellViewModel, NotebookLayoutInfo, CodeCellLayoutState, CellCollapseState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellEditState, CellFindMatch, CodeCellLayoutChangeEvent, CodeCellLayoutInfo, ICellViewModel, NotebookLayoutInfo, CodeCellLayoutState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; import { CellKind, NotebookCellOutputsSplice, INotebookSearchOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { BaseCellViewModel } from './baseCellViewModel'; @@ -99,9 +99,9 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod layoutChange(state: CodeCellLayoutChangeEvent) { // recompute this._ensureOutputsTop(); - let outputTotalHeight = this.outputCollapseState === CellCollapseState.Normal ? this._outputsTop!.getTotalValue() : COLLAPSED_INDICATOR_HEIGHT; + let outputTotalHeight = this.metadata?.outputCollapsed ? COLLAPSED_INDICATOR_HEIGHT : this._outputsTop!.getTotalValue(); - if (this.collapseState === CellCollapseState.Normal) { + if (!this.metadata?.inputCollapsed) { let newState: CodeCellLayoutState; let editorHeight: number; let totalHeight: number; @@ -138,7 +138,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod layoutState: newState }; } else { - outputTotalHeight = this.collapseState === CellCollapseState.Collapsed && this.outputCollapseState === CellCollapseState.Collapsed ? 0 : outputTotalHeight; + outputTotalHeight = this.metadata?.inputCollapsed && this.metadata.outputCollapsed ? 0 : outputTotalHeight; const indicatorHeight = COLLAPSED_INDICATOR_HEIGHT + outputTotalHeight; const outputContainerOffset = CELL_TOP_MARGIN + COLLAPSED_INDICATOR_HEIGHT; const totalHeight = CELL_TOP_MARGIN + COLLAPSED_INDICATOR_HEIGHT + CELL_BOTTOM_MARGIN + BOTTOM_CELL_TOOLBAR_HEIGHT + outputTotalHeight; diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel.ts index babc68f178d..75f80035264 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel.ts @@ -9,7 +9,7 @@ import * as UUID from 'vs/base/common/uuid'; import * as editorCommon from 'vs/editor/common/editorCommon'; import * as model from 'vs/editor/common/model'; import { BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_MARGIN, CELL_STATUSBAR_HEIGHT, CELL_TOP_MARGIN, CELL_BOTTOM_MARGIN, CODE_CELL_LEFT_MARGIN, BOTTOM_CELL_TOOLBAR_OFFSET, COLLAPSED_INDICATOR_HEIGHT } from 'vs/workbench/contrib/notebook/browser/constants'; -import { CellCollapseState, CellFindMatch, ICellViewModel, MarkdownCellLayoutChangeEvent, MarkdownCellLayoutInfo, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellFindMatch, ICellViewModel, MarkdownCellLayoutChangeEvent, MarkdownCellLayoutInfo, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { MarkdownRenderer } from 'vs/workbench/contrib/notebook/browser/view/renderers/mdRenderer'; import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel'; import { EditorFoldingStateDelegate } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel'; @@ -93,7 +93,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie layoutChange(state: MarkdownCellLayoutChangeEvent) { // recompute - if (this.collapseState === CellCollapseState.Normal) { + if (!this.metadata?.inputCollapsed) { const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo.editorWidth; const totalHeight = state.totalHeight === undefined ? this._layoutInfo.totalHeight : state.totalHeight; diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts index 702d445cc32..26dbd42de3a 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts @@ -527,6 +527,19 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel } } + changeCellMetadata(handle: number, newMetadata: NotebookCellMetadata) { + const cell = this._mapping.get(handle); + if (cell) { + cell.metadata = { + ...cell.metadata, + ...newMetadata + }; + + this._increaseVersionId(); + this._onDidModelChangeProxy.fire({ kind: NotebookCellsChangeType.ChangeMetadata, versionId: this._versionId, index: this.cells.indexOf(cell), metadata: newMetadata }); + } + } + clearAllCellOutputs() { this.cells.forEach(cell => { cell.spliceNotebookCellOutputs([ diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 700712384ea..99d94fc20f4 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -325,7 +325,8 @@ export enum NotebookCellsChangeType { CellClearOutput = 3, CellsClearOutput = 4, ChangeLanguage = 5, - Initialize = 6 + Initialize = 6, + ChangeMetadata = 7 } export interface NotebookCellsInitializeEvent { @@ -365,7 +366,14 @@ export interface NotebookCellsChangeLanguageEvent { readonly language: string; } -export type NotebookCellsChangedEvent = NotebookCellsInitializeEvent | NotebookCellsModelChangedEvent | NotebookCellsModelMoveEvent | NotebookCellClearOutputEvent | NotebookCellsClearOutputEvent | NotebookCellsChangeLanguageEvent; +export interface NotebookCellsChangeMetadataEvent { + readonly kind: NotebookCellsChangeType.ChangeMetadata; + readonly versionId: number; + readonly index: number; + readonly metadata: NotebookCellMetadata; +} + +export type NotebookCellsChangedEvent = NotebookCellsInitializeEvent | NotebookCellsModelChangedEvent | NotebookCellsModelMoveEvent | NotebookCellClearOutputEvent | NotebookCellsClearOutputEvent | NotebookCellsChangeLanguageEvent | NotebookCellsChangeMetadataEvent; export enum CellEditType { Insert = 1, Delete = 2