Skip to content

Commit fdf5b95

Browse files
committed
replace ICellInsertEdit, ICellDeleteEdit with ICellReplaceEdit, #105283
1 parent 0de8d51 commit fdf5b95

File tree

7 files changed

+103
-72
lines changed

7 files changed

+103
-72
lines changed

src/vs/workbench/api/browser/mainThreadNotebook.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
392392
mainthreadTextModel.transientOptions = options;
393393

394394
const edits: ICellEditOperation[] = [
395-
{ editType: CellEditType.Delete, count: mainthreadTextModel.cells.length, index: 0 },
396-
{ editType: CellEditType.Insert, index: 0, cells: data.cells }
395+
{ editType: CellEditType.Replace, index: 0, count: mainthreadTextModel.cells.length, cells: data.cells }
397396
];
398397

399398
this._notebookService.transformEditsOutputs(mainthreadTextModel, edits);

src/vs/workbench/api/common/extHostNotebook.ts

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePa
2222
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
2323
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
2424
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
25-
import { addIdToOutput, CellEditType, CellOutputKind, CellStatusbarAlignment, CellUri, diff, ICellDeleteEdit, ICellDto2, ICellEditOperation, ICellInsertEdit, IMainCellDto, INotebookCellStatusBarEntry, INotebookDisplayOrder, INotebookEditData, INotebookKernelInfoDto2, IProcessedOutput, NotebookCellMetadata, NotebookCellsChangedEvent, NotebookCellsChangeType, NotebookCellsSplice2, NotebookDataDto, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
25+
import { addIdToOutput, CellEditType, CellOutputKind, CellStatusbarAlignment, CellUri, diff, ICellEditOperation, ICellReplaceEdit, IMainCellDto, INotebookCellStatusBarEntry, INotebookDisplayOrder, INotebookEditData, INotebookKernelInfoDto2, IProcessedOutput, NotebookCellMetadata, NotebookCellsChangedEvent, NotebookCellsChangeType, NotebookCellsSplice2, NotebookDataDto, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
2626
import * as vscode from 'vscode';
2727
import { Cache } from './cache';
2828
import { ResourceMap } from 'vs/base/common/map';
@@ -539,29 +539,17 @@ export class NotebookEditorCellEditBuilder implements vscode.NotebookEditorCellE
539539
replaceCells(from: number, to: number, cells: vscode.NotebookCellData[]): void {
540540
this._throwIfFinalized();
541541

542-
// deletion
543-
if (to > from) {
544-
this._collectedEdits.push({
545-
editType: CellEditType.Delete,
546-
index: from,
547-
count: to - from
548-
});
549-
}
550-
// insert
551-
if (cells.length > 0) {
552-
this._collectedEdits.push({
553-
editType: CellEditType.Insert,
554-
index: from,
555-
cells: cells.map(data => {
556-
return <ICellDto2>{
557-
cellKind: data.cellKind,
558-
language: data.language,
559-
outputs: data.outputs.map(output => addIdToOutput(output)),
560-
source: data.source
561-
};
562-
})
563-
});
564-
}
542+
this._collectedEdits.push({
543+
editType: CellEditType.Replace,
544+
index: from,
545+
count: to - from,
546+
cells: cells.map(data => {
547+
return {
548+
...data,
549+
outputs: data.outputs.map(output => addIdToOutput(output)),
550+
};
551+
})
552+
});
565553
}
566554

567555
insert(index: number, content: string | string[], language: string, type: CellKind, outputs: vscode.CellOutput[], metadata: vscode.NotebookCellMetadata | undefined): void {
@@ -716,16 +704,10 @@ export class ExtHostNotebookEditor extends Disposable implements vscode.Notebook
716704
const prevIndex = compressedEditsIndex;
717705
const prev = compressedEdits[prevIndex];
718706

719-
if (prev.editType === CellEditType.Insert && editData.edits[i].editType === CellEditType.Insert) {
720-
if (prev.index === editData.edits[i].index) {
721-
prev.cells.push(...(editData.edits[i] as ICellInsertEdit).cells);
722-
continue;
723-
}
724-
}
725-
726-
if (prev.editType === CellEditType.Delete && editData.edits[i].editType === CellEditType.Delete) {
707+
if (prev.editType === CellEditType.Replace && editData.edits[i].editType === CellEditType.Replace) {
727708
if (prev.index === editData.edits[i].index) {
728-
prev.count += (editData.edits[i] as ICellDeleteEdit).count;
709+
prev.cells.push(...(editData.edits[i] as ICellReplaceEdit).cells);
710+
prev.count += (editData.edits[i] as ICellReplaceEdit).count;
729711
continue;
730712
}
731713
}

src/vs/workbench/api/common/extHostTypes.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,8 +632,7 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
632632
// --- cell
633633

634634
replaceCells(uri: URI, start: number, end: number, cells: vscode.NotebookCellData[], metadata?: vscode.WorkspaceEditEntryMetadata): void {
635-
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Delete, index: start, count: end - start } });
636-
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Insert, index: start, cells: cells.map(cell => ({ ...cell, outputs: cell.outputs.map(output => addIdToOutput(output)) })) } });
635+
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Replace, index: start, count: end - start, cells: cells.map(cell => ({ ...cell, outputs: cell.outputs.map(output => addIdToOutput(output)) })) } });
637636
}
638637

639638
replaceCellOutput(uri: URI, index: number, outputs: vscode.CellOutput[], metadata?: vscode.WorkspaceEditEntryMetadata): void {

src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu
720720

721721
transformEditsOutputs(textModel: NotebookTextModel, edits: ICellEditOperation[]) {
722722
edits.forEach((edit) => {
723-
if (edit.editType === CellEditType.Insert) {
723+
if (edit.editType === CellEditType.Replace) {
724724
edit.cells.forEach((cell) => {
725725
const outputs = cell.outputs;
726726
outputs.map((output) => {

src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
232232
const edits = rawEdits.map((edit, index) => {
233233
return {
234234
edit,
235-
end: edit.editType === CellEditType.Delete ? edit.index + edit.count : edit.index,
235+
end: edit.editType === CellEditType.Replace ? edit.index + edit.count : edit.index,
236236
originalIndex: index,
237237
};
238238
}).sort((a, b) => {
@@ -241,16 +241,8 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
241241

242242
for (const { edit } of edits) {
243243
switch (edit.editType) {
244-
case CellEditType.Insert:
245-
const mainCells = edit.cells.map(cell => {
246-
const cellHandle = this._cellhandlePool++;
247-
const cellUri = CellUri.generate(this.uri, cellHandle);
248-
return new NotebookCellTextModel(cellUri, cellHandle, cell.source, cell.language, cell.cellKind, cell.outputs || [], cell.metadata, this.transientOptions, this._modelService);
249-
});
250-
this.insertNewCell(edit.index, mainCells, false);
251-
break;
252-
case CellEditType.Delete:
253-
this.removeCell(edit.index, edit.count, false);
244+
case CellEditType.Replace:
245+
this._replaceCells(edit.index, edit.count, edit.cells);
254246
break;
255247
case CellEditType.Output:
256248
//TODO@joh,@rebornix no event, no undo stop (?)
@@ -302,6 +294,47 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
302294
return true;
303295
}
304296

297+
private _replaceCells(index: number, count: number, cellDtos: ICellDto2[]): void {
298+
299+
if (count === 0 && cellDtos.length === 0) {
300+
return;
301+
}
302+
303+
this._isUntitled = false; //TODO@rebornix fishy?
304+
305+
// prepare remove
306+
for (let i = index; i < index + count; i++) {
307+
const cell = this.cells[i];
308+
this._cellListeners.get(cell.handle)?.dispose();
309+
this._cellListeners.delete(cell.handle);
310+
}
311+
312+
// prepare add
313+
const cells = cellDtos.map(cellDto => {
314+
const cellHandle = this._cellhandlePool++;
315+
const cellUri = CellUri.generate(this.uri, cellHandle);
316+
const cell = new NotebookCellTextModel(
317+
cellUri, cellHandle,
318+
cellDto.source, cellDto.language, cellDto.cellKind, cellDto.outputs || [], cellDto.metadata, this.transientOptions,
319+
this._modelService
320+
);
321+
const dirtyStateListener = cell.onDidChangeContent(() => {
322+
this.setDirty(true);
323+
this._increaseVersionId();
324+
this._onDidChangeContent.fire();
325+
});
326+
this._cellListeners.set(cell.handle, dirtyStateListener);
327+
this._mapping.set(cell.handle, cell);
328+
return cell;
329+
});
330+
331+
// make change
332+
this.cells.splice(index, count, ...cells);
333+
this.setDirty(true);
334+
this._increaseVersionId();
335+
this._onDidChangeContent.fire();
336+
}
337+
305338
handleEdit(label: string | undefined, undo: () => void, redo: () => void): void {
306339
this._operationManager.pushEditOperation({
307340
type: UndoRedoElementType.Resource,

src/vs/workbench/contrib/notebook/common/notebookCommon.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -416,10 +416,9 @@ export interface NotebookCellsChangeMetadataEvent {
416416
export type NotebookCellsChangedEvent = NotebookCellsInitializeEvent | NotebookCellsModelChangedEvent | NotebookCellsModelMoveEvent | NotebookCellClearOutputEvent | NotebookCellsClearOutputEvent | NotebookCellsChangeLanguageEvent | NotebookCellsChangeMetadataEvent;
417417

418418
export const enum CellEditType {
419-
Insert = 1,
420-
Delete = 2,
421-
Output = 3,
422-
Metadata = 4,
419+
Replace = 1,
420+
Output = 2,
421+
Metadata = 3,
423422
}
424423

425424
export interface ICellDto2 {
@@ -430,16 +429,11 @@ export interface ICellDto2 {
430429
metadata?: NotebookCellMetadata;
431430
}
432431

433-
export interface ICellInsertEdit {
434-
editType: CellEditType.Insert;
435-
index: number;
436-
cells: ICellDto2[];
437-
}
438-
439-
export interface ICellDeleteEdit {
440-
editType: CellEditType.Delete;
432+
export interface ICellReplaceEdit {
433+
editType: CellEditType.Replace;
441434
index: number;
442435
count: number;
436+
cells: ICellDto2[];
443437
}
444438

445439
export interface ICellOutputEdit {
@@ -454,7 +448,7 @@ export interface ICellMetadataEdit {
454448
metadata: NotebookCellMetadata;
455449
}
456450

457-
export type ICellEditOperation = ICellInsertEdit | ICellDeleteEdit | ICellOutputEdit | ICellMetadataEdit;
451+
export type ICellEditOperation = ICellReplaceEdit | ICellOutputEdit | ICellMetadataEdit;
458452

459453
export interface INotebookEditData {
460454
documentVersionId: number;

src/vs/workbench/contrib/notebook/test/notebookTextModel.test.ts

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ suite('NotebookTextModel', () => {
3030
],
3131
(editor, viewModel, textModel) => {
3232
textModel.applyEdit(textModel.versionId, [
33-
{ editType: CellEditType.Insert, index: 1, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
34-
{ editType: CellEditType.Insert, index: 3, cells: [new TestCell(viewModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], textModelService)] },
33+
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
34+
{ editType: CellEditType.Replace, index: 3, count: 0, cells: [new TestCell(viewModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], textModelService)] },
3535
], true);
3636

3737
assert.equal(textModel.cells.length, 6);
@@ -55,8 +55,8 @@ suite('NotebookTextModel', () => {
5555
],
5656
(editor, viewModel, textModel) => {
5757
textModel.applyEdit(textModel.versionId, [
58-
{ editType: CellEditType.Insert, index: 1, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
59-
{ editType: CellEditType.Insert, index: 1, cells: [new TestCell(viewModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], textModelService)] },
58+
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
59+
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], textModelService)] },
6060
], true);
6161

6262
assert.equal(textModel.cells.length, 6);
@@ -80,8 +80,8 @@ suite('NotebookTextModel', () => {
8080
],
8181
(editor, viewModel, textModel) => {
8282
textModel.applyEdit(textModel.versionId, [
83-
{ editType: CellEditType.Delete, index: 1, count: 1 },
84-
{ editType: CellEditType.Delete, index: 3, count: 1 },
83+
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
84+
{ editType: CellEditType.Replace, index: 3, count: 1, cells: [] },
8585
], true);
8686

8787
assert.equal(textModel.cells[0].getValue(), 'var a = 1;');
@@ -103,8 +103,8 @@ suite('NotebookTextModel', () => {
103103
],
104104
(editor, viewModel, textModel) => {
105105
textModel.applyEdit(textModel.versionId, [
106-
{ editType: CellEditType.Delete, index: 1, count: 1 },
107-
{ editType: CellEditType.Insert, index: 3, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
106+
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
107+
{ editType: CellEditType.Replace, index: 3, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
108108
], true);
109109

110110
assert.equal(textModel.cells.length, 4);
@@ -128,8 +128,32 @@ suite('NotebookTextModel', () => {
128128
],
129129
(editor, viewModel, textModel) => {
130130
textModel.applyEdit(textModel.versionId, [
131-
{ editType: CellEditType.Delete, index: 1, count: 1 },
132-
{ editType: CellEditType.Insert, index: 1, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
131+
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
132+
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
133+
], true);
134+
135+
assert.equal(textModel.cells.length, 4);
136+
assert.equal(textModel.cells[0].getValue(), 'var a = 1;');
137+
assert.equal(textModel.cells[1].getValue(), 'var e = 5;');
138+
assert.equal(textModel.cells[2].getValue(), 'var c = 3;');
139+
}
140+
);
141+
});
142+
143+
test('(replace) delete + insert at same position', function () {
144+
withTestNotebook(
145+
instantiationService,
146+
blukEditService,
147+
undoRedoService,
148+
[
149+
['var a = 1;', 'javascript', CellKind.Code, [], { editable: true }],
150+
['var b = 2;', 'javascript', CellKind.Code, [], { editable: false }],
151+
['var c = 3;', 'javascript', CellKind.Code, [], { editable: false }],
152+
['var d = 4;', 'javascript', CellKind.Code, [], { editable: false }]
153+
],
154+
(editor, viewModel, textModel) => {
155+
textModel.applyEdit(textModel.versionId, [
156+
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
133157
], true);
134158

135159
assert.equal(textModel.cells.length, 4);

0 commit comments

Comments
 (0)