提交 ea02bca1 编写于 作者: R rebornix

replace insertCell with applyEdit.

上级 f88fca50
......@@ -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) {
......@@ -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;
});
......
......@@ -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;
}
......
......@@ -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) {
......@@ -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) {
......
......@@ -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';
......@@ -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 {
......@@ -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) {
......
......@@ -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';
......@@ -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];
}
......@@ -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
);
}
/**
......@@ -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;
}
......@@ -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);
......@@ -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);
......@@ -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);
......
......@@ -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;
}
......@@ -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();
......@@ -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;
......@@ -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({
......@@ -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);
}
......@@ -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) {
......@@ -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) => {
......@@ -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;
......@@ -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);
......@@ -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}`);
......@@ -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];
......
......@@ -423,7 +423,8 @@ export const enum CellEditType {
CellLanguage = 4,
DocumentMetadata = 5,
OutputsSplice = 6,
Unknown = 7
Move = 7,
Unknown = 8
}
export interface ICellDto2 {
......@@ -465,17 +466,24 @@ export interface IDocumentMetadataEdit {
metadata: NotebookDocumentMetadata;
}
export interface ICellOutputsSplice {
export interface ICellOutputsSpliceEdit {
editType: CellEditType.OutputsSplice;
index: number;
splices: NotebookCellOutputsSplice[];
}
export interface ICellMoveEdit {
editType: CellEditType.Move;
index: number;
length: number;
newIdx: number;
}
export interface IDocumentUnknownEdit {
editType: CellEditType.Unknown;
}
export type ICellEditOperation = ICellReplaceEdit | ICellOutputEdit | ICellMetadataEdit | ICellLanguageEdit | IDocumentMetadataEdit | ICellOutputsSplice | IDocumentUnknownEdit;
export type ICellEditOperation = ICellReplaceEdit | ICellOutputEdit | ICellMetadataEdit | ICellLanguageEdit | IDocumentMetadataEdit | ICellOutputsSpliceEdit | ICellMoveEdit | IDocumentUnknownEdit;
export interface INotebookEditData {
documentVersionId: number;
......
......@@ -7,7 +7,7 @@ import * as assert from 'assert';
import { URI } from 'vs/base/common/uri';
import { NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { CellKind, NotebookCellMetadata, diff, ICellRange, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { withTestNotebook, TestCell, NotebookEditorTestModel, setupInstantiationService } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
import { withTestNotebook, NotebookEditorTestModel, setupInstantiationService } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
......@@ -45,7 +45,7 @@ suite('NotebookViewModel', () => {
assert.equal(viewModel.viewCells[0].metadata?.editable, true);
assert.equal(viewModel.viewCells[1].metadata?.editable, false);
const cell = viewModel.insertCell(1, new TestCell(viewModel.viewType, 0, 'var c = 3;', 'javascript', CellKind.Code, [], textModelService), true);
const cell = viewModel.createCell(1, 'var c = 3', 'javascript', CellKind.Code, {}, [], true, true, []);
assert.equal(viewModel.viewCells.length, 3);
assert.equal(viewModel.notebookDocument.cells.length, 3);
assert.equal(viewModel.getCellIndex(cell), 1);
......@@ -128,13 +128,13 @@ suite('NotebookViewModel', () => {
const lastViewCell = viewModel.viewCells[viewModel.viewCells.length - 1];
const insertIndex = viewModel.getCellIndex(firstViewCell) + 1;
const cell = viewModel.insertCell(insertIndex, new TestCell(viewModel.viewType, 3, 'var c = 3;', 'javascript', CellKind.Code, [], textModelService), true);
const cell = viewModel.createCell(insertIndex, 'var c = 3;', 'javascript', CellKind.Code, {}, [], true);
const addedCellIndex = viewModel.getCellIndex(cell);
viewModel.deleteCell(addedCellIndex, true);
const secondInsertIndex = viewModel.getCellIndex(lastViewCell) + 1;
const cell2 = viewModel.insertCell(secondInsertIndex, new TestCell(viewModel.viewType, 4, 'var d = 4;', 'javascript', CellKind.Code, [], textModelService), true);
const cell2 = viewModel.createCell(secondInsertIndex, 'var d = 4;', 'javascript', CellKind.Code, {}, [], true);
assert.equal(viewModel.viewCells.length, 3);
assert.equal(viewModel.notebookDocument.cells.length, 3);
......@@ -261,7 +261,6 @@ function getVisibleCells<T>(cells: T[], hiddenRanges: ICellRange[]) {
suite('NotebookViewModel Decorations', () => {
const instantiationService = setupInstantiationService();
const textModelService = instantiationService.get(ITextModelService);
const blukEditService = instantiationService.get(IBulkEditService);
const undoRedoService = instantiationService.get(IUndoRedoService);
......@@ -285,7 +284,7 @@ suite('NotebookViewModel Decorations', () => {
end: 2,
});
viewModel.insertCell(0, new TestCell(viewModel.viewType, 5, 'var d = 6;', 'javascript', CellKind.Code, [], textModelService), true);
viewModel.createCell(0, 'var d = 6;', 'javascript', CellKind.Code, {}, [], true);
assert.deepEqual(viewModel.getTrackedRange(trackedId!), {
start: 2,
......@@ -299,7 +298,7 @@ suite('NotebookViewModel Decorations', () => {
end: 2
});
viewModel.insertCell(3, new TestCell(viewModel.viewType, 6, 'var d = 7;', 'javascript', CellKind.Code, [], textModelService), true);
viewModel.createCell(3, 'var d = 7;', 'javascript', CellKind.Code, {}, [], true);
assert.deepEqual(viewModel.getTrackedRange(trackedId!), {
start: 1,
......@@ -345,14 +344,14 @@ suite('NotebookViewModel Decorations', () => {
end: 3
});
viewModel.insertCell(5, new TestCell(viewModel.viewType, 8, 'var d = 9;', 'javascript', CellKind.Code, [], textModelService), true);
viewModel.createCell(5, 'var d = 9;', 'javascript', CellKind.Code, {}, [], true);
assert.deepEqual(viewModel.getTrackedRange(trackedId!), {
start: 1,
end: 3
});
viewModel.insertCell(4, new TestCell(viewModel.viewType, 9, 'var d = 10;', 'javascript', CellKind.Code, [], textModelService), true);
viewModel.createCell(4, 'var d = 10;', 'javascript', CellKind.Code, {}, [], true);
assert.deepEqual(viewModel.getTrackedRange(trackedId!), {
start: 1,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册