Skip to content

Commit

Permalink
replace insertCell with applyEdit.
Browse files Browse the repository at this point in the history
  • Loading branch information
rebornix committed Sep 10, 2020
1 parent f88fca5 commit ea02bca
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ registerAction2(class extends NotebookAction {
}
}).forEach(pasteCell => {
const newIdx = typeof currCellIndex === 'number' ? currCellIndex + 1 : 0;
topPastedCell = viewModel.insertCell(newIdx, pasteCell, true);
topPastedCell = viewModel.createCell(newIdx, pasteCell.getValue(), pasteCell.language, pasteCell.cellKind, pasteCell.metadata, pasteCell.outputs, true);
});

if (topPastedCell) {
Expand Down Expand Up @@ -1032,7 +1032,7 @@ registerAction2(class extends NotebookCellAction {
return cell;
}
}).forEach(pasteCell => {
topPastedCell = viewModel.insertCell(currCellIndex, pasteCell, true);
topPastedCell = viewModel.createCell(currCellIndex, pasteCell.getValue(), pasteCell.language, pasteCell.cellKind, pasteCell.metadata, pasteCell.outputs, true);
return;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
(direction === 'above' ? index : nextIndex) :
index;
const focused = this._list?.getFocusedElements();
const newCell = this._notebookViewModel!.createCell(insertIndex, initialText, language, type, undefined, true, undefined, focused);
const newCell = this._notebookViewModel!.createCell(insertIndex, initialText, language, type, undefined, [], true, undefined, focused);
return newCell as CellViewModel;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu
}
}).forEach(pasteCell => {
const newIdx = typeof currCellIndex === 'number' ? currCellIndex + 1 : 0;
topPastedCell = viewModel.insertCell(newIdx, pasteCell, true);
topPastedCell = viewModel.createCell(newIdx, pasteCell.getValue(), pasteCell.language, pasteCell.cellKind, pasteCell.metadata, pasteCell.outputs, true);
});

if (topPastedCell) {
Expand All @@ -476,7 +476,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu
return cell;
}
}).forEach(pasteCell => {
topPastedCell = viewModel.insertCell(0, pasteCell, true);
topPastedCell = viewModel.createCell(0, pasteCell.getValue(), pasteCell.language, pasteCell.cellKind, pasteCell.metadata, pasteCell.outputs, true);
});

if (topPastedCell) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, IProcessedOutput, NotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { IResourceUndoRedoElement, UndoRedoElementType } from 'vs/platform/undoRedo/common/undoRedo';
import { URI } from 'vs/base/common/uri';
import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel';
Expand All @@ -16,7 +16,7 @@ import { ITextCellEditingDelegate } from 'vs/workbench/contrib/notebook/common/m

export interface IViewCellEditingDelegate extends ITextCellEditingDelegate {
createCellViewModel?(cell: NotebookCellTextModel): BaseCellViewModel;
createCell?(index: number, source: string | string[], language: string, type: CellKind): BaseCellViewModel;
createCell?(index: number, source: string, language: string, type: CellKind, metadata: NotebookCellMetadata | undefined, outputs: IProcessedOutput[]): BaseCellViewModel;
}

export class JoinCellEdit implements IResourceUndoRedoElement {
Expand Down Expand Up @@ -126,7 +126,7 @@ export class SplitCellEdit implements IResourceUndoRedoElement {
let insertIndex = this.index + 1;
let lastCell;
for (let j = 1; j < this.cellContents.length; j++, insertIndex++) {
lastCell = this.editingDelegate.createCell(insertIndex, this.cellContents[j], this.language, this.cellKind);
lastCell = this.editingDelegate.createCell(insertIndex, this.cellContents[j], this.language, this.cellKind, {}, []);
}

if (lastCell) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { NotebookEventDispatcher, NotebookMetadataChangedEvent } from 'vs/workbe
import { CellFoldingState, EditorFoldingStateDelegate } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel';
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { CellKind, NotebookCellMetadata, INotebookSearchOptions, ICellRange, NotebookCellsChangeType, ICell, NotebookCellTextModelSplice } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, NotebookCellMetadata, INotebookSearchOptions, ICellRange, NotebookCellsChangeType, ICell, NotebookCellTextModelSplice, CellEditType, IProcessedOutput } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { FoldingRegions } from 'vs/editor/contrib/folding/foldingRanges';
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
import { MarkdownRenderer } from 'vs/workbench/contrib/notebook/browser/view/renderers/mdRenderer';
Expand Down Expand Up @@ -623,17 +623,24 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
return result;
}

createCell(index: number, source: string, language: string, type: CellKind, metadata: NotebookCellMetadata | undefined, synchronous: boolean, pushUndoStop: boolean = true, previouslyFocused: ICellViewModel[] = []) {
createCell(index: number, source: string, language: string, type: CellKind, metadata: NotebookCellMetadata | undefined, outputs: IProcessedOutput[], synchronous: boolean, pushUndoStop: boolean = true, previouslyFocused: ICellViewModel[] = []): CellViewModel {
const beforeSelections = previouslyFocused.map(e => e.handle);
const cell = this._notebook.createCellTextModel(source, language, type, [], metadata);
this._notebook.insertCell(index, cell, synchronous, pushUndoStop, beforeSelections, undefined);
// TODO, rely on createCell to be sync
return this.viewCells[index];
}

insertCell(index: number, cell: NotebookCellTextModel, synchronous: boolean, pushUndoStop: boolean = true): CellViewModel {
this._notebook.insertCell(index, cell, synchronous, pushUndoStop, undefined, undefined);
// TODO, rely on createCell to be sync // this will trigger it to synchronous update
this._notebook.applyEdit(this._notebook.versionId, [
{
editType: CellEditType.Replace,
index,
count: 0,
cells: [
{
cellKind: type,
language: language,
outputs: outputs,
metadata: metadata,
source: source
}
]
}
], synchronous, beforeSelections, () => undefined);
return this._viewCells[index];
}

Expand All @@ -656,7 +663,18 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
}
}

this._notebook.deleteCell(index, synchronous, pushUndoStop, this.selectionHandles, endSelections);
this._notebook.applyEdit(this._notebook.versionId, [
{
editType: CellEditType.Replace,
index: index,
count: 1,
cells: []
}],
synchronous,
this.selectionHandles,
() => endSelections,
pushUndoStop
);
}

/**
Expand All @@ -673,7 +691,14 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
return false;
}

this._notebook.moveCellToIdx(index, length, newIdx, synchronous, pushedToUndoStack, undefined, [viewCell.handle]);
this._notebook.applyEdit(this._notebook.versionId, [
{
editType: CellEditType.Move,
index,
length,
newIdx
}
], synchronous, undefined, () => [viewCell.handle]);
return true;
}

Expand Down Expand Up @@ -771,8 +796,8 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
language,
kind,
{
createCell: (index: number, source: string, language: string, type: CellKind) => {
return this.createCell(index, source, language, type, undefined, true, false) as BaseCellViewModel;
createCell: (index: number, source: string, language: string, type: CellKind, metadata: NotebookCellMetadata | undefined, outputs: IProcessedOutput[]) => {
return this.createCell(index, source, language, type, metadata, outputs, true, false) as BaseCellViewModel;
},
deleteCell: (index: number) => {
this.deleteCell(index, true, false);
Expand Down Expand Up @@ -845,7 +870,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
cell,
{
insertCell: (index: number, cell: NotebookCellTextModel, endSelections?: number[]) => {
this.insertCell(index, cell, true, false);
this.createCell(index, cell.getValue(), cell.language, cell.cellKind, cell.metadata, cell.outputs, true, false);
},
deleteCell: (index: number) => {
this.deleteCell(index, true, false);
Expand Down Expand Up @@ -896,7 +921,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
below,
{
insertCell: (index: number, cell: NotebookCellTextModel, endSelections?: number[]) => {
this.insertCell(index, cell, true, false);
this.createCell(index, cell.getValue(), cell.language, cell.cellKind, cell.metadata, cell.outputs, true, false);
},
deleteCell: (index: number) => {
this.deleteCell(index, true, false);
Expand Down
91 changes: 42 additions & 49 deletions src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
this._operationManager.pushStackElement(label, selectionState);
}

applyEdit(modelVersionId: number, rawEdits: ICellEditOperation[], synchronous: boolean, beginSelectionState: number[] | undefined, endSelectionsComputer: () => number[] | undefined): boolean {
applyEdit(modelVersionId: number, rawEdits: ICellEditOperation[], synchronous: boolean, beginSelectionState: number[] | undefined, endSelectionsComputer: () => number[] | undefined, computeUndoRedo: boolean = true): boolean {
if (modelVersionId !== this._versionId) {
return false;
}
Expand Down Expand Up @@ -334,33 +334,36 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
for (const { edit } of edits) {
switch (edit.editType) {
case CellEditType.Replace:
this._replaceCells(edit.index, edit.count, edit.cells, synchronous);
this._replaceCells(edit.index, edit.count, edit.cells, synchronous, computeUndoRedo);
break;
case CellEditType.Output:
//TODO@joh,@rebornix no event, no undo stop (?)
this._assertIndex(edit.index);
const cell = this._cells[edit.index];
// TODO@rebornix, we should do diff first
this._spliceNotebookCellOutputs(cell.handle, [[0, cell.outputs.length, edit.outputs]]);
this._spliceNotebookCellOutputs(cell.handle, [[0, cell.outputs.length, edit.outputs]], computeUndoRedo);
break;
case CellEditType.OutputsSplice:
{
//TODO@joh,@rebornix no event, no undo stop (?)
this._assertIndex(edit.index);
const cell = this._cells[edit.index];
this._spliceNotebookCellOutputs(cell.handle, edit.splices);
this._spliceNotebookCellOutputs(cell.handle, edit.splices, computeUndoRedo);
break;
}
case CellEditType.Metadata:
this._assertIndex(edit.index);
this._changeCellMetadata(this._cells[edit.index].handle, edit.metadata, true);
this._changeCellMetadata(this._cells[edit.index].handle, edit.metadata, computeUndoRedo);
break;
case CellEditType.CellLanguage:
this._assertIndex(edit.index);
this._changeCellLanguage(this._cells[edit.index].handle, edit.language);
this._changeCellLanguage(this._cells[edit.index].handle, edit.language, computeUndoRedo);
break;
case CellEditType.DocumentMetadata:
this._updateNotebookMetadata(edit.metadata);
this._updateNotebookMetadata(edit.metadata, computeUndoRedo);
break;
case CellEditType.Move:
this._moveCellToIdx(edit.index, edit.length, edit.newIdx, synchronous, computeUndoRedo, undefined, undefined);
break;
case CellEditType.Unknown:
this._handleUnknownChange();
Expand Down Expand Up @@ -404,7 +407,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
}, true);
}

private _replaceCells(index: number, count: number, cellDtos: ICellDto2[], synchronous: boolean): void {
private _replaceCells(index: number, count: number, cellDtos: ICellDto2[], synchronous: boolean, computeUndoRedo: boolean): void {

if (count === 0 && cellDtos.length === 0) {
return;
Expand Down Expand Up @@ -446,15 +449,17 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
});

const undoDiff = diffs.map(diff => {
const deletedCells = this._cells.slice(diff[0], diff[0] + diff[1]);
const deletedCells = oldViewCells.slice(diff[0], diff[0] + diff[1]);

return [diff[0], deletedCells, diff[2]] as [number, NotebookCellTextModel[], NotebookCellTextModel[]];
});

this._operationManager.pushEditOperation(new SpliceCellsEdit(this.uri, undoDiff, {
insertCell: (index, cell, endSelections?: number[]) => { this._insertNewCell(index, [cell], true, endSelections); },
deleteCell: (index, endSelections?: number[]) => { this._removeCell(index, 1, true, endSelections); },
}, undefined, undefined), undefined, undefined);
if (computeUndoRedo) {
this._operationManager.pushEditOperation(new SpliceCellsEdit(this.uri, undoDiff, {
insertCell: (index, cell, endSelections?: number[]) => { this._insertNewCell(index, [cell], true, endSelections); },
deleteCell: (index, endSelections?: number[]) => { this._removeCell(index, 1, true, endSelections); },
}, undefined, undefined), undefined, undefined);
}

// should be deferred
this._eventEmitter.emit({
Expand All @@ -479,7 +484,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
}
}

private _updateNotebookMetadata(metadata: NotebookDocumentMetadata) {
private _updateNotebookMetadata(metadata: NotebookDocumentMetadata, computeUndoRedo: boolean) {
this.metadata = metadata;
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeDocumentMetadata, metadata: this.metadata, transient: false }, true);
}
Expand Down Expand Up @@ -534,7 +539,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
return false;
}

private _changeCellMetadata(handle: number, metadata: NotebookCellMetadata, pushUndoStop: boolean) {
private _changeCellMetadata(handle: number, metadata: NotebookCellMetadata, computeUndoRedo: boolean) {
const cell = this._cells.find(cell => cell.handle === handle);

if (!cell) {
Expand All @@ -544,7 +549,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
const triggerDirtyChange = this._isCellMetadataChanged(cell.metadata, metadata);

if (triggerDirtyChange) {
if (pushUndoStop) {
if (computeUndoRedo) {
const index = this._cells.indexOf(cell);
this._operationManager.pushEditOperation(new CellMetadataEdit(this.uri, index, Object.freeze(cell.metadata), Object.freeze(metadata), {
updateCellMetadata: (index, newMetadata) => {
Expand All @@ -565,7 +570,7 @@ 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 _changeCellLanguage(handle: number, languageId: string) {
private _changeCellLanguage(handle: number, languageId: string, computeUndoRedo: boolean) {
const cell = this._mapping.get(handle);
if (cell && cell.language !== languageId) {
cell.language = languageId;
Expand All @@ -574,7 +579,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
}
}

private _spliceNotebookCellOutputs(cellHandle: number, splices: NotebookCellOutputsSplice[]): void {
private _spliceNotebookCellOutputs(cellHandle: number, splices: NotebookCellOutputsSplice[], computeUndoRedo: boolean): void {
const cell = this._mapping.get(cellHandle);
if (cell) {
cell.spliceNotebookCellOutputs(splices);
Expand All @@ -588,6 +593,25 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
}
}

private _moveCellToIdx(index: number, length: number, newIdx: number, synchronous: boolean, pushedToUndoStack: boolean, beforeSelections: number[] | undefined, endSelections: number[] | undefined): boolean {
if (pushedToUndoStack) {
this._operationManager.pushEditOperation(new MoveCellEdit(this.uri, index, length, newIdx, {
moveCell: (fromIndex: number, length: number, toIndex: number, beforeSelections: number[] | undefined, endSelections: number[] | undefined) => {
this._moveCellToIdx(fromIndex, length, toIndex, true, false, beforeSelections, endSelections);
},
}, beforeSelections, endSelections), beforeSelections, endSelections);
}

this._assertIndex(index);
this._assertIndex(newIdx);

const cells = this._cells.splice(index, length);
this._cells.splice(newIdx, 0, ...cells);
this._eventEmitter.emit({ kind: NotebookCellsChangeType.Move, index, length, newIdx, cells, transient: false }, synchronous, endSelections);

return true;
}

private _assertIndex(index: number) {
if (index < 0 || index >= this._cells.length) {
throw new Error(`model index out of range ${index}`);
Expand All @@ -607,37 +631,6 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
this._insertNewCell(index, [cell], synchronous, endSelections);
}

deleteCell(index: number, synchronous: boolean, pushUndoStop: boolean, beforeSelections: number[] | undefined, endSelections: number[] | undefined) {
const cell = this._cells[index];
if (pushUndoStop) {
this._operationManager.pushEditOperation(new DeleteCellEdit(this.uri, index, cell, {
insertCell: (index, cell, endSelections) => { this._insertNewCell(index, [cell], true, endSelections); },
deleteCell: (index, endSelections) => { this._removeCell(index, 1, true, endSelections); },
}, beforeSelections, endSelections), beforeSelections, endSelections);
}

this._removeCell(index, 1, synchronous, endSelections);
}

moveCellToIdx(index: number, length: number, newIdx: number, synchronous: boolean, pushedToUndoStack: boolean, beforeSelections: number[] | undefined, endSelections: number[] | undefined): boolean {
if (pushedToUndoStack) {
this._operationManager.pushEditOperation(new MoveCellEdit(this.uri, index, length, newIdx, {
moveCell: (fromIndex: number, length: number, toIndex: number, beforeSelections: number[] | undefined, endSelections: number[] | undefined) => {
this.moveCellToIdx(fromIndex, length, toIndex, true, false, beforeSelections, endSelections);
},
}, beforeSelections, endSelections), beforeSelections, endSelections);
}

this._assertIndex(index);
this._assertIndex(newIdx);

const cells = this._cells.splice(index, length);
this._cells.splice(newIdx, 0, ...cells);
this._eventEmitter.emit({ kind: NotebookCellsChangeType.Move, index, length, newIdx, cells, transient: false }, synchronous, endSelections);

return true;
}

async splitNotebookCell(index: number, newLinesContents: string[], endSelections: number[]) {
const cell = this._cells[index];

Expand Down
Loading

0 comments on commit ea02bca

Please sign in to comment.