Skip to content

Commit 600528d

Browse files
committed
1 parent 582ced0 commit 600528d

7 files changed

Lines changed: 76 additions & 21 deletions

File tree

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,15 @@ suite('notebook workflow', () => {
100100

101101
// ---- move up and down ---- //
102102

103-
// await vscode.commands.executeCommand('workbench.notebook.cell.moveDown');
104-
// await vscode.commands.executeCommand('workbench.notebook.cell.moveDown');
105-
// activeCell = vscode.notebook.activeNotebookEditor!.selection;
106-
107-
// assert.equal(vscode.notebook.activeNotebookEditor!.document.cells.indexOf(activeCell!), 2);
108-
// assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[0].source, 'test');
109-
// assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[1].source, '');
110-
// assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[2].source, 'test');
111-
// assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[3].source, '');
103+
await vscode.commands.executeCommand('workbench.notebook.cell.moveDown');
104+
await vscode.commands.executeCommand('workbench.notebook.cell.moveDown');
105+
activeCell = vscode.notebook.activeNotebookEditor!.selection;
112106

107+
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells.indexOf(activeCell!), 2);
108+
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[0].source, 'test');
109+
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[1].source, '');
110+
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[2].source, 'test');
111+
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[3].source, '');
113112

114113
// ---- ---- //
115114

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'
1313
import { CellKind, CellOutputKind, ExtHostNotebookShape, IMainContext, MainContext, MainThreadNotebookShape, NotebookCellOutputsSplice, MainThreadDocumentsShape, INotebookEditorPropertiesChangeData } from 'vs/workbench/api/common/extHost.protocol';
1414
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
1515
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
16-
import { CellEditType, CellUri, diff, ICellEditOperation, ICellInsertEdit, IErrorOutput, INotebookDisplayOrder, INotebookEditData, IOrderedMimeType, IStreamOutput, ITransformedDisplayOutputDto, mimeTypeSupportedByCore, NotebookCellsChangedEvent, NotebookCellsSplice2, sortMimeTypes, ICellDeleteEdit, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
16+
import { CellEditType, CellUri, diff, ICellEditOperation, ICellInsertEdit, IErrorOutput, INotebookDisplayOrder, INotebookEditData, IOrderedMimeType, IStreamOutput, ITransformedDisplayOutputDto, mimeTypeSupportedByCore, NotebookCellsChangedEvent, NotebookCellsSplice2, sortMimeTypes, ICellDeleteEdit, notebookDocumentMetadataDefaults, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
1717
import { Disposable as VSCodeDisposable } from './extHostTypes';
1818
import { CancellationToken } from 'vs/base/common/cancellation';
1919
import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData';
@@ -247,7 +247,12 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
247247
get isDirty() { return false; }
248248

249249
accpetModelChanged(event: NotebookCellsChangedEvent) {
250-
this.$spliceNotebookCells(event.changes);
250+
if (event.kind === NotebookCellsChangeType.ModelChange) {
251+
this.$spliceNotebookCells(event.changes);
252+
} else if (event.kind === NotebookCellsChangeType.Move) {
253+
this.$moveCell(event.index, event.newIdx);
254+
}
255+
251256
this._versionId = event.versionId;
252257
}
253258

@@ -289,6 +294,11 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
289294
});
290295
}
291296

297+
private $moveCell(index: number, newIdx: number) {
298+
const cells = this.cells.splice(index, 1);
299+
this.cells.splice(newIdx, 0, ...cells);
300+
}
301+
292302
eventuallyUpdateCellOutputs(cell: ExtHostCell, diffs: ISplice<vscode.CellOutput>[]) {
293303
let renderers = new Set<number>();
294304
let outputDtos: NotebookCellOutputsSplice[] = diffs.map(diff => {
@@ -600,8 +610,8 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
600610
private readonly _editors = new Map<string, { editor: ExtHostNotebookEditor, onDidReceiveMessage: Emitter<any> }>();
601611
private readonly _notebookOutputRenderers = new Map<number, ExtHostNotebookOutputRenderer>();
602612

603-
private readonly _onDidChangeNotebookDocument = new Emitter<{ document: ExtHostNotebookDocument, changes: NotebookCellsSplice2[] }>();
604-
readonly onDidChangeNotebookDocument: Event<{ document: ExtHostNotebookDocument, changes: NotebookCellsSplice2[] }> = this._onDidChangeNotebookDocument.event;
613+
private readonly _onDidChangeNotebookDocument = new Emitter<{ document: ExtHostNotebookDocument, changes: NotebookCellsChangedEvent[] }>();
614+
readonly onDidChangeNotebookDocument: Event<{ document: ExtHostNotebookDocument, changes: NotebookCellsChangedEvent[] }> = this._onDidChangeNotebookDocument.event;
605615

606616
private _outputDisplayOrder: INotebookDisplayOrder | undefined;
607617

@@ -801,7 +811,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
801811
editor.editor.document.accpetModelChanged(event);
802812
this._onDidChangeNotebookDocument.fire({
803813
document: editor.editor.document,
804-
changes: event.changes
814+
changes: [event]
805815
});
806816
}
807817

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ export class NotebookEditorModel extends EditorModel {
6969
}
7070
}
7171

72+
moveCellToIdx(index: number, newIdx: number) {
73+
this.notebook.moveCellToIdx(index, newIdx);
74+
}
75+
7276
async save(): Promise<boolean> {
7377
if (this._notebook) {
7478
this._dirty = false;

src/vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -664,10 +664,8 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
664664
}
665665

666666
this.viewCells.splice(index, 1);
667-
this._model.deleteCell(index);
668-
669667
this.viewCells!.splice(newIdx, 0, viewCell);
670-
this._model.insertCell(viewCell.model, newIdx);
668+
this._model.moveCellToIdx(index, newIdx);
671669

672670
if (pushedToUndoStack) {
673671
this.undoService.pushElement(new MoveCellEdit(this.uri, index, newIdx, {

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

Lines changed: 21 additions & 2 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, IOutput, notebookDocumentMetadataDefaults, diff, ICellDeleteEdit } from 'vs/workbench/contrib/notebook/common/notebookCommon';
10+
import { INotebookTextModel, NotebookCellOutputsSplice, NotebookCellTextModelSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, CellEditType, CellUri, ICellInsertEdit, NotebookCellsChangedEvent, CellKind, IOutput, notebookDocumentMetadataDefaults, diff, ICellDeleteEdit, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
1111

1212
function compareRangesUsingEnds(a: [number, number], b: [number, number]): number {
1313
if (a[1] === b[1]) {
@@ -192,6 +192,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
192192
this._onDidChangeContent.fire();
193193

194194
this._onDidModelChangeProxy.fire({
195+
kind: NotebookCellsChangeType.ModelChange,
195196
versionId: this._versionId, changes: [
196197
[
197198
0,
@@ -228,6 +229,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
228229
this._onDidChangeContent.fire();
229230
this._increaseVersionId();
230231
this._onDidModelChangeProxy.fire({
232+
kind: NotebookCellsChangeType.ModelChange,
231233
versionId: this._versionId, changes: [
232234
[
233235
index,
@@ -258,7 +260,24 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
258260
this._onDidChangeContent.fire();
259261

260262
this._increaseVersionId();
261-
this._onDidModelChangeProxy.fire({ versionId: this._versionId, changes: [[index, 1, []]] });
263+
this._onDidModelChangeProxy.fire({ kind: NotebookCellsChangeType.ModelChange, versionId: this._versionId, changes: [[index, 1, []]] });
264+
}
265+
266+
moveCellToIdx(index: number, newIdx: number) {
267+
this.assertIndex(index);
268+
this.assertIndex(newIdx);
269+
270+
const cells = this.cells.splice(index, 1);
271+
this.cells.splice(newIdx, 0, ...cells);
272+
273+
this._increaseVersionId();
274+
this._onDidModelChangeProxy.fire({ kind: NotebookCellsChangeType.Move, versionId: this._versionId, index, newIdx });
275+
}
276+
277+
assertIndex(index: number) {
278+
if (index < 0 || index >= this.cells.length) {
279+
throw new Error(`model index out of range ${index}`);
280+
}
262281
}
263282

264283
// TODO@rebornix should this trigger content change event?

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,25 @@ export type NotebookCellsSplice2 = [
215215
IMainCellDto[]
216216
];
217217

218-
export interface NotebookCellsChangedEvent {
218+
export enum NotebookCellsChangeType {
219+
ModelChange = 1,
220+
Move = 2
221+
}
222+
223+
export interface NotebookCellsModelChangedEvent {
224+
readonly kind: NotebookCellsChangeType.ModelChange;
219225
readonly changes: NotebookCellsSplice2[];
220226
readonly versionId: number;
221227
}
222228

229+
export interface NotebookCellsModelMoveEvent {
230+
readonly kind: NotebookCellsChangeType.Move;
231+
readonly index: number;
232+
readonly newIdx: number;
233+
readonly versionId: number;
234+
}
235+
236+
export type NotebookCellsChangedEvent = NotebookCellsModelChangedEvent | NotebookCellsModelMoveEvent;
223237
export enum CellEditType {
224238
Insert = 1,
225239
Delete = 2

src/vs/workbench/test/browser/api/extHostNotebookConcatDocument.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { NullLogService } from 'vs/platform/log/common/log';
1111
import { ExtHostNotebookConcatDocument } from 'vs/workbench/api/common/extHostNotebookConcatDocument';
1212
import { ExtHostNotebookDocument, ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
1313
import { URI } from 'vs/base/common/uri';
14-
import { CellKind, CellUri } from 'vs/workbench/contrib/notebook/common/notebookCommon';
14+
import { CellKind, CellUri, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
1515
import { Position, Location, Range } from 'vs/workbench/api/common/extHostTypes';
1616
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
1717
import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
@@ -51,6 +51,7 @@ suite('NotebookConcatDocument', function () {
5151
});
5252
await extHostNotebooks.$resolveNotebook('test', notebookUri);
5353
extHostNotebooks.$acceptModelChanged(notebookUri, {
54+
kind: NotebookCellsChangeType.ModelChange,
5455
versionId: 0,
5556
changes: [[0, 0, [{
5657
handle: 0,
@@ -104,6 +105,7 @@ suite('NotebookConcatDocument', function () {
104105
test('location, position mapping', function () {
105106

106107
extHostNotebooks.$acceptModelChanged(notebookUri, {
108+
kind: NotebookCellsChangeType.ModelChange,
107109
versionId: notebook.versionId + 1,
108110
changes: [[0, 0, [{
109111
handle: 1,
@@ -142,6 +144,7 @@ suite('NotebookConcatDocument', function () {
142144

143145
// UPDATE 1
144146
extHostNotebooks.$acceptModelChanged(notebookUri, {
147+
kind: NotebookCellsChangeType.ModelChange,
145148
versionId: notebook.versionId + 1,
146149
changes: [[0, 0, [{
147150
handle: 1,
@@ -163,6 +166,7 @@ suite('NotebookConcatDocument', function () {
163166

164167
// UPDATE 2
165168
extHostNotebooks.$acceptModelChanged(notebookUri, {
169+
kind: NotebookCellsChangeType.ModelChange,
166170
versionId: notebook.versionId + 1,
167171
changes: [[1, 0, [{
168172
handle: 2,
@@ -185,6 +189,7 @@ suite('NotebookConcatDocument', function () {
185189

186190
// UPDATE 3 (remove cell #2 again)
187191
extHostNotebooks.$acceptModelChanged(notebookUri, {
192+
kind: NotebookCellsChangeType.ModelChange,
188193
versionId: notebook.versionId + 1,
189194
changes: [[1, 1, []]]
190195
});
@@ -202,6 +207,7 @@ suite('NotebookConcatDocument', function () {
202207

203208
// UPDATE 1
204209
extHostNotebooks.$acceptModelChanged(notebookUri, {
210+
kind: NotebookCellsChangeType.ModelChange,
205211
versionId: notebook.versionId + 1,
206212
changes: [[0, 0, [{
207213
handle: 1,
@@ -264,6 +270,7 @@ suite('NotebookConcatDocument', function () {
264270
test('selector', function () {
265271

266272
extHostNotebooks.$acceptModelChanged(notebookUri, {
273+
kind: NotebookCellsChangeType.ModelChange,
267274
versionId: notebook.versionId + 1,
268275
changes: [[0, 0, [{
269276
handle: 1,
@@ -291,6 +298,7 @@ suite('NotebookConcatDocument', function () {
291298
assertLines(barLangDoc, 'barLang-document');
292299

293300
extHostNotebooks.$acceptModelChanged(notebookUri, {
301+
kind: NotebookCellsChangeType.ModelChange,
294302
versionId: notebook.versionId + 1,
295303
changes: [[2, 0, [{
296304
handle: 3,
@@ -323,6 +331,7 @@ suite('NotebookConcatDocument', function () {
323331
test('offsetAt(position) <-> positionAt(offset)', function () {
324332

325333
extHostNotebooks.$acceptModelChanged(notebookUri, {
334+
kind: NotebookCellsChangeType.ModelChange,
326335
versionId: notebook.versionId + 1,
327336
changes: [[0, 0, [{
328337
handle: 1,
@@ -373,6 +382,7 @@ suite('NotebookConcatDocument', function () {
373382
test('locationAt(position) <-> positionAt(location)', function () {
374383

375384
extHostNotebooks.$acceptModelChanged(notebookUri, {
385+
kind: NotebookCellsChangeType.ModelChange,
376386
versionId: notebook.versionId + 1,
377387
changes: [[0, 0, [{
378388
handle: 1,
@@ -407,6 +417,7 @@ suite('NotebookConcatDocument', function () {
407417
test('getText(range)', function () {
408418

409419
extHostNotebooks.$acceptModelChanged(notebookUri, {
420+
kind: NotebookCellsChangeType.ModelChange,
410421
versionId: notebook.versionId + 1,
411422
changes: [[0, 0, [{
412423
handle: 1,

0 commit comments

Comments
 (0)