Skip to content

Commit 8bac4d1

Browse files
committed
combine events from edits from ext host.
1 parent 3158079 commit 8bac4d1

6 files changed

Lines changed: 125 additions & 85 deletions

File tree

extensions/vscode-notebook-tests/src/notebook.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,29 @@ suite('API tests', () => {
238238
await vscode.commands.executeCommand('workbench.action.splitEditor');
239239
await firstEditorDeactivate;
240240

241+
await vscode.commands.executeCommand('workbench.action.files.save');
241242
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
242243
});
244+
245+
test('edit API', async function () {
246+
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
247+
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
248+
249+
const cellsChangeEvent = getEventOncePromise<vscode.NotebookCellsChangeEvent>(vscode.notebook.onDidChangeNotebookCells);
250+
await vscode.notebook.activeNotebookEditor!.edit(editBuilder => {
251+
editBuilder.insert(1, 'test 2', 'javascript', vscode.CellKind.Code, [], undefined);
252+
});
253+
254+
const cellChangeEventRet = await cellsChangeEvent;
255+
assert.equal(cellChangeEventRet.document, vscode.notebook.activeNotebookEditor?.document);
256+
assert.equal(cellChangeEventRet.changes.length, 1);
257+
assert.deepEqual(cellChangeEventRet.changes[0].start, 1);
258+
assert.deepEqual(cellChangeEventRet.changes[0].deletedCount, 0);
259+
assert.equal(cellChangeEventRet.changes[0].items[0], vscode.notebook.activeNotebookEditor!.document.cells[1]);
260+
261+
await vscode.commands.executeCommand('workbench.action.files.save');
262+
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
263+
});
243264
});
244265

245266
suite('notebook workflow', () => {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class MainThreadNotebookDocument extends Disposable {
3434
) {
3535
super();
3636
this._textModel = new NotebookTextModel(handle, viewType, uri);
37-
this._register(this._textModel.onDidModelChange(e => {
37+
this._register(this._textModel.onDidModelChangeProxy(e => {
3838
this._proxy.$acceptModelChanged(this.uri, e);
3939
this._proxy.$acceptEditorPropertiesChanged(uri, { selections: { selections: this._textModel.selections }, metadata: null });
4040
}));

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

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
261261
accpetModelChanged(event: NotebookCellsChangedEvent): void {
262262
this._versionId = event.versionId;
263263
if (event.kind === NotebookCellsChangeType.ModelChange) {
264-
this.$spliceNotebookCells(event.change);
264+
this.$spliceNotebookCells(event.changes);
265265
} else if (event.kind === NotebookCellsChangeType.Move) {
266266
this.$moveCell(event.index, event.newIdx);
267267
} else if (event.kind === NotebookCellsChangeType.CellClearOutput) {
@@ -273,50 +273,52 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
273273
}
274274
}
275275

276-
private $spliceNotebookCells(splice: NotebookCellsSplice2): void {
276+
private $spliceNotebookCells(splices: NotebookCellsSplice2[]): void {
277277
if (this._disposed) {
278278
return;
279279
}
280280

281281
let contentChangeEvents: vscode.NotebookCellsChangeData[] = [];
282282

283-
let cellDtos = splice[2];
284-
let newCells = cellDtos.map(cell => {
285-
const extCell = new ExtHostCell(this.viewType, this.uri, cell.handle, URI.revive(cell.uri), cell.source.join('\n'), cell.cellKind, cell.language, cell.outputs, cell.metadata, this._proxy);
286-
const documentData = this._documentsAndEditors.getDocument(URI.revive(cell.uri));
283+
splices.reverse().forEach(splice => {
284+
let cellDtos = splice[2];
285+
let newCells = cellDtos.map(cell => {
286+
const extCell = new ExtHostCell(this.viewType, this.uri, cell.handle, URI.revive(cell.uri), cell.source.join('\n'), cell.cellKind, cell.language, cell.outputs, cell.metadata, this._proxy);
287+
const documentData = this._documentsAndEditors.getDocument(URI.revive(cell.uri));
287288

288-
if (documentData) {
289-
extCell.attachTextDocument(documentData);
290-
}
289+
if (documentData) {
290+
extCell.attachTextDocument(documentData);
291+
}
291292

292-
if (!this._cellDisposableMapping.has(extCell.handle)) {
293-
this._cellDisposableMapping.set(extCell.handle, new DisposableStore());
294-
}
293+
if (!this._cellDisposableMapping.has(extCell.handle)) {
294+
this._cellDisposableMapping.set(extCell.handle, new DisposableStore());
295+
}
295296

296-
let store = this._cellDisposableMapping.get(extCell.handle)!;
297+
let store = this._cellDisposableMapping.get(extCell.handle)!;
297298

298-
store.add(extCell.onDidChangeOutputs((diffs) => {
299-
this.eventuallyUpdateCellOutputs(extCell, diffs);
300-
}));
299+
store.add(extCell.onDidChangeOutputs((diffs) => {
300+
this.eventuallyUpdateCellOutputs(extCell, diffs);
301+
}));
301302

302-
return extCell;
303-
});
303+
return extCell;
304+
});
304305

305-
for (let j = splice[0]; j < splice[0] + splice[1]; j++) {
306-
this._cellDisposableMapping.get(this.cells[j].handle)?.dispose();
307-
this._cellDisposableMapping.delete(this.cells[j].handle);
306+
for (let j = splice[0]; j < splice[0] + splice[1]; j++) {
307+
this._cellDisposableMapping.get(this.cells[j].handle)?.dispose();
308+
this._cellDisposableMapping.delete(this.cells[j].handle);
308309

309-
}
310+
}
310311

311-
this.cells.splice(splice[0], splice[1], ...newCells);
312+
this.cells.splice(splice[0], splice[1], ...newCells);
312313

313-
const event: vscode.NotebookCellsChangeData = {
314-
start: splice[0],
315-
deletedCount: splice[1],
316-
items: newCells
317-
};
314+
const event: vscode.NotebookCellsChangeData = {
315+
start: splice[0],
316+
deletedCount: splice[1],
317+
items: newCells
318+
};
318319

319-
contentChangeEvents.push(event);
320+
contentChangeEvents.push(event);
321+
});
320322

321323
this._emitter.emitModelChange({
322324
document: this,
@@ -1096,11 +1098,11 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
10961098
document.accpetModelChanged({
10971099
kind: NotebookCellsChangeType.ModelChange,
10981100
versionId: modelData.versionId,
1099-
change: [
1101+
changes: [[
11001102
0,
11011103
0,
11021104
modelData.cells
1103-
]
1105+
]]
11041106
});
11051107

11061108
this._documents.get(revivedUriStr)?.dispose();

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

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Emitter, Event } from 'vs/base/common/event';
77
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
88
import { URI } from 'vs/base/common/uri';
99
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
10-
import { INotebookTextModel, NotebookCellOutputsSplice, NotebookCellTextModelSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, CellEditType, CellUri, ICellInsertEdit, NotebookCellsChangedEvent, CellKind, IProcessedOutput, notebookDocumentMetadataDefaults, diff, ICellDeleteEdit, NotebookCellsChangeType, ICellDto2 } from 'vs/workbench/contrib/notebook/common/notebookCommon';
10+
import { INotebookTextModel, NotebookCellOutputsSplice, NotebookCellTextModelSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, CellEditType, CellUri, ICellInsertEdit, NotebookCellsChangedEvent, CellKind, IProcessedOutput, notebookDocumentMetadataDefaults, diff, ICellDeleteEdit, NotebookCellsChangeType, ICellDto2, IMainCellDto } from 'vs/workbench/contrib/notebook/common/notebookCommon';
1111
import { ITextSnapshot } from 'vs/editor/common/model';
1212

1313
function compareRangesUsingEnds(a: [number, number], b: [number, number]): number {
@@ -71,7 +71,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
7171
private readonly _onDidChangeCells = new Emitter<NotebookCellTextModelSplice[]>();
7272
get onDidChangeCells(): Event<NotebookCellTextModelSplice[]> { return this._onDidChangeCells.event; }
7373
private _onDidModelChangeProxy = new Emitter<NotebookCellsChangedEvent>();
74-
get onDidModelChange(): Event<NotebookCellsChangedEvent> { return this._onDidModelChangeProxy.event; }
74+
get onDidModelChangeProxy(): Event<NotebookCellsChangedEvent> { return this._onDidModelChangeProxy.event; }
7575
private _onDidSelectionChangeProxy = new Emitter<number[] | null>();
7676
get onDidSelectionChange(): Event<number[] | null> { return this._onDidSelectionChangeProxy.event; }
7777
private _onDidChangeContent = new Emitter<void>();
@@ -182,10 +182,10 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
182182
const cellUri = CellUri.generate(this.uri, cellHandle);
183183
return new NotebookCellTextModel(cellUri, cellHandle, cell.source, cell.language, cell.cellKind, cell.outputs || [], cell.metadata);
184184
});
185-
this.insertNewCell(insertEdit.index, mainCells);
185+
this.insertNewCell(insertEdit.index, mainCells, false);
186186
break;
187187
case CellEditType.Delete:
188-
this.removeCell(operations[i].index, operations[i].end - operations[i].start);
188+
this.removeCell(operations[i].index, operations[i].end - operations[i].start, false);
189189
break;
190190
}
191191
}
@@ -196,10 +196,19 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
196196
return [diff.start, diff.deleteCount, diff.toInsert] as [number, number, NotebookCellTextModel[]];
197197
});
198198

199-
// this._onDidModelChangeProxy.fire({kind: NotebookCellsChangeType.ModelChange,
200-
// versionId: this._versionId, change: diffs
201-
// }
202-
// );
199+
this._onDidModelChangeProxy.fire({
200+
kind: NotebookCellsChangeType.ModelChange,
201+
versionId: this._versionId,
202+
changes: diffs.map(diff => [diff[0], diff[1], diff[2].map(cell => ({
203+
handle: cell.handle,
204+
uri: cell.uri,
205+
source: cell.textBuffer.getLinesContent(),
206+
language: cell.language,
207+
cellKind: cell.cellKind,
208+
outputs: cell.outputs,
209+
metadata: cell.metadata
210+
}))] as [number, number, IMainCellDto[]])
211+
});
203212

204213
this._onDidChangeCells.fire(diffs);
205214
return true;
@@ -260,8 +269,8 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
260269

261270
this._onDidModelChangeProxy.fire({
262271
kind: NotebookCellsChangeType.ModelChange,
263-
versionId: this._versionId, change:
264-
[
272+
versionId: this._versionId, changes:
273+
[[
265274
0,
266275
0,
267276
[{
@@ -273,13 +282,13 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
273282
outputs: cell.outputs,
274283
metadata: cell.metadata
275284
}]
276-
]
285+
]]
277286
});
278287

279288
return;
280289
}
281290

282-
insertNewCell(index: number, cells: NotebookCellTextModel[]): void {
291+
insertNewCell(index: number, cells: NotebookCellTextModel[], emitToExtHost: boolean = true): void {
283292
this._isUntitled = false;
284293

285294
for (let i = 0; i < cells.length; i++) {
@@ -294,28 +303,31 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
294303
this.cells.splice(index, 0, ...cells);
295304
this._onDidChangeContent.fire();
296305
this._increaseVersionId();
297-
this._onDidModelChangeProxy.fire({
298-
kind: NotebookCellsChangeType.ModelChange,
299-
versionId: this._versionId, change:
300-
[
301-
index,
302-
0,
303-
cells.map(cell => ({
304-
handle: cell.handle,
305-
uri: cell.uri,
306-
source: cell.textBuffer.getLinesContent(),
307-
language: cell.language,
308-
cellKind: cell.cellKind,
309-
outputs: cell.outputs,
310-
metadata: cell.metadata
311-
}))
312-
]
313-
});
306+
307+
if (emitToExtHost) {
308+
this._onDidModelChangeProxy.fire({
309+
kind: NotebookCellsChangeType.ModelChange,
310+
versionId: this._versionId, changes:
311+
[[
312+
index,
313+
0,
314+
cells.map(cell => ({
315+
handle: cell.handle,
316+
uri: cell.uri,
317+
source: cell.textBuffer.getLinesContent(),
318+
language: cell.language,
319+
cellKind: cell.cellKind,
320+
outputs: cell.outputs,
321+
metadata: cell.metadata
322+
}))
323+
]]
324+
});
325+
}
314326

315327
return;
316328
}
317329

318-
removeCell(index: number, count: number) {
330+
removeCell(index: number, count: number, emitToExtHost: boolean = true) {
319331
this._isUntitled = false;
320332

321333
for (let i = index; i < index + count; i++) {
@@ -327,18 +339,23 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
327339
this._onDidChangeContent.fire();
328340

329341
this._increaseVersionId();
330-
this._onDidModelChangeProxy.fire({ kind: NotebookCellsChangeType.ModelChange, versionId: this._versionId, change: [index, count, []] });
342+
if (emitToExtHost) {
343+
this._onDidModelChangeProxy.fire({ kind: NotebookCellsChangeType.ModelChange, versionId: this._versionId, changes: [[index, count, []]] });
344+
}
331345
}
332346

333-
moveCellToIdx(index: number, newIdx: number) {
347+
moveCellToIdx(index: number, newIdx: number, emitToExtHost: boolean = true) {
334348
this.assertIndex(index);
335349
this.assertIndex(newIdx);
336350

337351
const cells = this.cells.splice(index, 1);
338352
this.cells.splice(newIdx, 0, ...cells);
339353

340354
this._increaseVersionId();
341-
this._onDidModelChangeProxy.fire({ kind: NotebookCellsChangeType.Move, versionId: this._versionId, index, newIdx });
355+
356+
if (emitToExtHost) {
357+
this._onDidModelChangeProxy.fire({ kind: NotebookCellsChangeType.Move, versionId: this._versionId, index, newIdx });
358+
}
342359
}
343360

344361
assertIndex(index: number) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ export enum NotebookCellsChangeType {
304304

305305
export interface NotebookCellsModelChangedEvent {
306306
readonly kind: NotebookCellsChangeType.ModelChange;
307-
readonly change: NotebookCellsSplice2;
307+
readonly changes: NotebookCellsSplice2[];
308308
readonly versionId: number;
309309
}
310310

0 commit comments

Comments
 (0)