fix #121100. PausableEmitter
This commit is contained in:
parent
424e5f8de8
commit
369afa6562
|
@ -623,56 +623,6 @@ suite('Notebook API tests', function () {
|
|||
});
|
||||
});
|
||||
|
||||
test('notebook workspace edit and undo redo', async function () {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
const editor = await vscode.window.showNotebookDocument(notebook);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor === editor, true, 'notebook first');
|
||||
assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'test');
|
||||
assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript');
|
||||
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
|
||||
assert.strictEqual(getFocusedCell(editor)?.document.getText(), '');
|
||||
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellAbove');
|
||||
const activeCell = getFocusedCell(editor);
|
||||
assert.notStrictEqual(getFocusedCell(editor), undefined);
|
||||
assert.strictEqual(activeCell!.document.getText(), '');
|
||||
assert.strictEqual(editor.document.cellCount, 4);
|
||||
assert.strictEqual(editor.document.getCells().indexOf(activeCell!), 1);
|
||||
|
||||
{
|
||||
// modify the second cell, delete it
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
edit.insert(getFocusedCell(editor)!.document.uri, new vscode.Position(0, 0), 'var abc = 0;');
|
||||
await vscode.workspace.applyEdit(edit);
|
||||
}
|
||||
|
||||
{
|
||||
const focusedCell = getFocusedCell(editor);
|
||||
assert.strictEqual(focusedCell !== undefined, true);
|
||||
// delete focused cell
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
edit.replaceNotebookCells(focusedCell!.notebook.uri, new vscode.NotebookRange(focusedCell!.index, focusedCell!.index + 1), []);
|
||||
await vscode.workspace.applyEdit(edit);
|
||||
}
|
||||
|
||||
assert.strictEqual(editor.document.cellCount, 3);
|
||||
assert.strictEqual(editor.document.getCells().indexOf(getFocusedCell(editor)!), 1);
|
||||
|
||||
|
||||
// undo should bring back the deleted cell, and revert to previous content and selection
|
||||
await vscode.commands.executeCommand('undo');
|
||||
assert.strictEqual(editor.document.cellCount, 4);
|
||||
assert.strictEqual(editor.document.getCells().indexOf(getFocusedCell(editor)!), 1);
|
||||
assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'var abc = 0;');
|
||||
|
||||
// redo
|
||||
// await vscode.commands.executeCommand('notebook.redo');
|
||||
// assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellCount, 2);
|
||||
// assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(getFocusedCell(vscode.window.activeNotebookEditor)!), 1);
|
||||
// assert.strictEqual(vscode.window.activeNotebookEditor?.selection?.document.getText(), 'test');
|
||||
});
|
||||
|
||||
test('multiple tabs: dirty + clean', async function () {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
|
|
|
@ -308,14 +308,15 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
for (let i = 0; i < e.rawEvents.length; i++) {
|
||||
const change = e.rawEvents[i];
|
||||
let changes: NotebookCellTextModelSplice<ICell>[] = [];
|
||||
const synchronous = e.synchronous ?? true;
|
||||
|
||||
if (change.kind === NotebookCellsChangeType.ModelChange || change.kind === NotebookCellsChangeType.Initialize) {
|
||||
changes = change.changes;
|
||||
compute(changes, e.synchronous);
|
||||
compute(changes, synchronous);
|
||||
continue;
|
||||
} else if (change.kind === NotebookCellsChangeType.Move) {
|
||||
compute([[change.index, change.length, []]], e.synchronous);
|
||||
compute([[change.newIdx, 0, change.cells]], e.synchronous);
|
||||
compute([[change.index, change.length, []]], synchronous);
|
||||
compute([[change.newIdx, 0, change.cells]], synchronous);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { flatten } from 'vs/base/common/arrays';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Emitter, Event, PauseableEmitter } from 'vs/base/common/event';
|
||||
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
import { INotebookTextModel, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, CellEditType, CellUri, diff, NotebookCellsChangeType, ICellDto2, TransientOptions, NotebookTextModelChangedEvent, NotebookRawContentEvent, IOutputDto, ICellOutput, IOutputItemDto, ISelectionState, NullablePartialNotebookCellMetadata, NotebookCellInternalMetadata, NullablePartialNotebookCellInternalMetadata, NotebookTextModelWillAddRemoveEvent, NotebookCellTextModelSplice, ICell } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookTextModel, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, CellEditType, CellUri, diff, NotebookCellsChangeType, ICellDto2, TransientOptions, NotebookTextModelChangedEvent, IOutputDto, ICellOutput, IOutputItemDto, ISelectionState, NullablePartialNotebookCellMetadata, NotebookCellInternalMetadata, NullablePartialNotebookCellInternalMetadata, NotebookTextModelWillAddRemoveEvent, NotebookCellTextModelSplice, ICell } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { IUndoRedoService, UndoRedoElementType, IUndoRedoElement, IResourceUndoRedoElement, UndoRedoGroup, IWorkspaceUndoRedoElement } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { MoveCellEdit, SpliceCellsEdit, CellMetadataEdit } from 'vs/workbench/contrib/notebook/common/model/cellEdit';
|
||||
import { ISequence, LcsDiff } from 'vs/base/common/diff/diff';
|
||||
|
@ -32,10 +32,10 @@ class StackOperation implements IWorkspaceUndoRedoElement {
|
|||
private _resultAlternativeVersionId: string;
|
||||
|
||||
constructor(
|
||||
readonly resource: URI,
|
||||
readonly textModel: NotebookTextModel,
|
||||
readonly label: string,
|
||||
readonly undoRedoGroup: UndoRedoGroup | undefined,
|
||||
private _delayedEmitter: DelayedEmitter,
|
||||
private _pauseableEmitter: PauseableEmitter<NotebookTextModelChangedEvent>,
|
||||
private _postUndoRedo: (alternativeVersionId: string) => void,
|
||||
selectionState: ISelectionState | undefined,
|
||||
beginAlternativeVersionId: string
|
||||
|
@ -46,7 +46,7 @@ class StackOperation implements IWorkspaceUndoRedoElement {
|
|||
this._resultAlternativeVersionId = beginAlternativeVersionId;
|
||||
}
|
||||
get resources(): readonly URI[] {
|
||||
return [this.resource];
|
||||
return [this.textModel.uri];
|
||||
}
|
||||
|
||||
get isEmpty(): boolean {
|
||||
|
@ -67,30 +67,43 @@ class StackOperation implements IWorkspaceUndoRedoElement {
|
|||
}
|
||||
|
||||
async undo(): Promise<void> {
|
||||
this._delayedEmitter.beginDeferredEmit();
|
||||
this._pauseableEmitter.pause();
|
||||
for (let i = this._operations.length - 1; i >= 0; i--) {
|
||||
await this._operations[i].undo();
|
||||
}
|
||||
this._postUndoRedo(this._beginAlternativeVersionId);
|
||||
this._delayedEmitter.endDeferredEmit(this._beginSelectionState);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [],
|
||||
synchronous: undefined,
|
||||
versionId: this.textModel.versionId,
|
||||
endSelectionState: this._beginSelectionState
|
||||
});
|
||||
this._pauseableEmitter.resume();
|
||||
}
|
||||
|
||||
async redo(): Promise<void> {
|
||||
this._delayedEmitter.beginDeferredEmit();
|
||||
this._pauseableEmitter.pause();
|
||||
for (let i = 0; i < this._operations.length; i++) {
|
||||
await this._operations[i].redo();
|
||||
}
|
||||
this._postUndoRedo(this._resultAlternativeVersionId);
|
||||
this._delayedEmitter.endDeferredEmit(this._resultSelectionState);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [],
|
||||
synchronous: undefined,
|
||||
versionId: this.textModel.versionId,
|
||||
endSelectionState: this._resultSelectionState
|
||||
});
|
||||
this._pauseableEmitter.resume();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export class NotebookOperationManager {
|
||||
private _pendingStackOperation: StackOperation | null = null;
|
||||
constructor(
|
||||
private readonly _textModel: NotebookTextModel,
|
||||
private _undoService: IUndoRedoService,
|
||||
private _resource: URI,
|
||||
private _delayedEmitter: DelayedEmitter,
|
||||
private _pauseableEmitter: PauseableEmitter<NotebookTextModelChangedEvent>,
|
||||
private _postUndoRedo: (alternativeVersionId: string) => void
|
||||
) {
|
||||
}
|
||||
|
@ -109,7 +122,7 @@ export class NotebookOperationManager {
|
|||
return;
|
||||
}
|
||||
|
||||
this._pendingStackOperation = new StackOperation(this._resource, label, undoRedoGroup, this._delayedEmitter, this._postUndoRedo, selectionState, alternativeVersionId);
|
||||
this._pendingStackOperation = new StackOperation(this._textModel, label, undoRedoGroup, this._pauseableEmitter, this._postUndoRedo, selectionState, alternativeVersionId);
|
||||
}
|
||||
|
||||
pushEditOperation(element: IUndoRedoElement, beginSelectionState: ISelectionState | undefined, resultSelectionState: ISelectionState | undefined) {
|
||||
|
@ -122,71 +135,6 @@ export class NotebookOperationManager {
|
|||
}
|
||||
}
|
||||
|
||||
class DelayedEmitter {
|
||||
private _deferredCnt: number = 0;
|
||||
private _notebookTextModelChangedEvent: NotebookTextModelChangedEvent | null = null;
|
||||
constructor(
|
||||
private readonly _onDidChangeContent: Emitter<NotebookTextModelChangedEvent>,
|
||||
private readonly _textModel: NotebookTextModel
|
||||
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
beginDeferredEmit(): void {
|
||||
this._deferredCnt++;
|
||||
}
|
||||
|
||||
endDeferredEmit(endSelections: ISelectionState | undefined): void {
|
||||
this._deferredCnt--;
|
||||
if (this._deferredCnt === 0) {
|
||||
if (this._notebookTextModelChangedEvent) {
|
||||
this._onDidChangeContent.fire(
|
||||
{
|
||||
rawEvents: this._notebookTextModelChangedEvent.rawEvents,
|
||||
versionId: this._textModel.versionId,
|
||||
endSelectionState: endSelections,
|
||||
synchronous: this._notebookTextModelChangedEvent.synchronous
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
this._notebookTextModelChangedEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
emit(data: NotebookRawContentEvent, synchronous: boolean, endSelections?: ISelectionState) {
|
||||
if (this._deferredCnt === 0) {
|
||||
this._onDidChangeContent.fire(
|
||||
{
|
||||
rawEvents: [data],
|
||||
versionId: this._textModel.versionId,
|
||||
synchronous,
|
||||
endSelectionState: endSelections
|
||||
}
|
||||
);
|
||||
} else {
|
||||
if (!this._notebookTextModelChangedEvent) {
|
||||
this._notebookTextModelChangedEvent = {
|
||||
rawEvents: [data],
|
||||
versionId: this._textModel.versionId,
|
||||
endSelectionState: endSelections,
|
||||
synchronous: synchronous
|
||||
};
|
||||
} else {
|
||||
// merge
|
||||
this._notebookTextModelChangedEvent = {
|
||||
rawEvents: [...this._notebookTextModelChangedEvent.rawEvents, data],
|
||||
versionId: this._textModel.versionId,
|
||||
endSelectionState: endSelections !== undefined ? endSelections : this._notebookTextModelChangedEvent.endSelectionState,
|
||||
synchronous: synchronous
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type TransformedEdit = {
|
||||
edit: ICellEditOperation;
|
||||
cellIndex: number;
|
||||
|
@ -220,7 +168,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
*/
|
||||
private _alternativeVersionId: string = '1';
|
||||
private _operationManager: NotebookOperationManager;
|
||||
private _eventEmitter: DelayedEmitter;
|
||||
private _pauseableEmitter: PauseableEmitter<NotebookTextModelChangedEvent>;
|
||||
|
||||
get length() {
|
||||
return this._cells.length;
|
||||
|
@ -269,15 +217,36 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
};
|
||||
this._register(_modelService.onModelAdded(e => maybeUpdateCellTextModel(e)));
|
||||
|
||||
this._eventEmitter = new DelayedEmitter(
|
||||
this._onDidChangeContent,
|
||||
this
|
||||
);
|
||||
this._pauseableEmitter = new PauseableEmitter<NotebookTextModelChangedEvent>({
|
||||
merge: (events: NotebookTextModelChangedEvent[]) => {
|
||||
let first = events[0];
|
||||
|
||||
let rawEvents = first.rawEvents;
|
||||
let versionId = first.versionId;
|
||||
let endSelectionState = first.endSelectionState;
|
||||
let synchronous = first.synchronous;
|
||||
|
||||
for (let i = 1; i < events.length; i++) {
|
||||
rawEvents.push(...events[i].rawEvents);
|
||||
versionId = events[i].versionId;
|
||||
endSelectionState = events[i].endSelectionState !== undefined ? events[i].endSelectionState : endSelectionState;
|
||||
synchronous = events[i].synchronous !== undefined ? events[i].synchronous : synchronous;
|
||||
}
|
||||
|
||||
return { rawEvents, versionId, endSelectionState, synchronous };
|
||||
}
|
||||
});
|
||||
|
||||
this._register(this._pauseableEmitter.event(e => {
|
||||
if (e.rawEvents.length) {
|
||||
this._onDidChangeContent.fire(e);
|
||||
}
|
||||
}));
|
||||
|
||||
this._operationManager = new NotebookOperationManager(
|
||||
this,
|
||||
this._undoService,
|
||||
uri,
|
||||
this._eventEmitter,
|
||||
this._pauseableEmitter,
|
||||
(alternativeVersionId: string) => {
|
||||
this._increaseVersionId(true);
|
||||
this._overwriteAlternativeVersionId(alternativeVersionId);
|
||||
|
@ -308,7 +277,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
this._alternativeVersionId = this._generateAlternativeId();
|
||||
|
||||
if (triggerDirty) {
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.Unknown, transient: false }, true);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.Unknown, transient: false }],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,15 +290,30 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
this._increaseVersionId(e === 'content');
|
||||
switch (e) {
|
||||
case 'content':
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeCellContent, transient: false }, true);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ChangeCellContent, transient: false }],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
break;
|
||||
|
||||
case 'language':
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeLanguage, index: this._getCellIndexByHandle(cell.handle), language: cell.language, transient: false }, true);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ChangeLanguage, index: this._getCellIndexByHandle(cell.handle), language: cell.language, transient: false }],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
break;
|
||||
|
||||
case 'mime':
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeCellMime, index: this._getCellIndexByHandle(cell.handle), mime: cell.mime, transient: false }, true);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ChangeCellMime, index: this._getCellIndexByHandle(cell.handle), mime: cell.mime, transient: false }],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -367,8 +356,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
}
|
||||
|
||||
applyEdits(rawEdits: ICellEditOperation[], synchronous: boolean, beginSelectionState: ISelectionState | undefined, endSelectionsComputer: () => ISelectionState | undefined, undoRedoGroup: UndoRedoGroup | undefined, computeUndoRedo: boolean = true): boolean {
|
||||
|
||||
this._eventEmitter.beginDeferredEmit();
|
||||
this._pauseableEmitter.pause();
|
||||
this.pushStackElement('edit', beginSelectionState, undoRedoGroup);
|
||||
|
||||
try {
|
||||
|
@ -383,7 +371,8 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
this.pushStackElement('edit', endSelections, undefined);
|
||||
|
||||
// Broadcast changes
|
||||
this._eventEmitter.endDeferredEmit(endSelections);
|
||||
this._pauseableEmitter.fire({ rawEvents: [], versionId: this.versionId, synchronous: synchronous, endSelectionState: endSelections });
|
||||
this._pauseableEmitter.resume();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,11 +593,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
}
|
||||
|
||||
// should be deferred
|
||||
this._eventEmitter.emit({
|
||||
kind: NotebookCellsChangeType.ModelChange,
|
||||
changes: diffs,
|
||||
transient: false
|
||||
}, synchronous);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ModelChange, changes: diffs, transient: false }],
|
||||
versionId: this.versionId,
|
||||
synchronous: synchronous,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
|
||||
private _increaseVersionId(undoStackEmpty: boolean): void {
|
||||
|
@ -659,7 +649,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
}
|
||||
|
||||
this.metadata = metadata;
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeDocumentMetadata, metadata: this.metadata, transient: this._isDocumentMetadataChangeTransient(oldMetadata, metadata) }, true);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ChangeDocumentMetadata, metadata: this.metadata, transient: this._isDocumentMetadataChangeTransient(oldMetadata, metadata) }],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
|
||||
private _insertNewCell(index: number, cells: NotebookCellTextModel[], synchronous: boolean, endSelections: ISelectionState | undefined): void {
|
||||
|
@ -674,11 +669,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
const changes: NotebookCellTextModelSplice<ICell>[] = [[index, 0, cells]];
|
||||
this._onWillAddRemoveCells.fire({ rawEvent: { kind: NotebookCellsChangeType.ModelChange, changes } });
|
||||
this._cells.splice(index, 0, ...cells);
|
||||
this._eventEmitter.emit({
|
||||
kind: NotebookCellsChangeType.ModelChange,
|
||||
changes,
|
||||
transient: false
|
||||
}, synchronous, endSelections);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ModelChange, changes, transient: false }],
|
||||
versionId: this.versionId,
|
||||
synchronous: synchronous,
|
||||
endSelectionState: endSelections
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -692,7 +688,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
const changes: NotebookCellTextModelSplice<ICell>[] = [[index, count, []]];
|
||||
this._onWillAddRemoveCells.fire({ rawEvent: { kind: NotebookCellsChangeType.ModelChange, changes } });
|
||||
this._cells.splice(index, count);
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ModelChange, changes, transient: false }, synchronous, endSelections);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ModelChange, changes, transient: false }],
|
||||
versionId: this.versionId,
|
||||
synchronous: synchronous,
|
||||
endSelectionState: endSelections
|
||||
});
|
||||
}
|
||||
|
||||
private _replaceNewCells(index: number, count: number, cells: NotebookCellTextModel[], synchronous: boolean, endSelections: ISelectionState | undefined) {
|
||||
|
@ -713,8 +714,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
const changes: NotebookCellTextModelSplice<ICell>[] = [[index, count, cells]];
|
||||
this._onWillAddRemoveCells.fire({ rawEvent: { kind: NotebookCellsChangeType.ModelChange, changes } });
|
||||
this._cells.splice(index, count, ...cells);
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ModelChange, changes, transient: false }, synchronous, endSelections);
|
||||
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ModelChange, changes, transient: false }],
|
||||
versionId: this.versionId,
|
||||
synchronous: synchronous,
|
||||
endSelectionState: endSelections
|
||||
});
|
||||
}
|
||||
|
||||
private _isDocumentMetadataChanged(a: NotebookDocumentMetadata, b: NotebookDocumentMetadata) {
|
||||
|
@ -814,8 +819,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
|
||||
// should be deferred
|
||||
cell.metadata = metadata;
|
||||
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeCellMetadata, index: this._cells.indexOf(cell), metadata: cell.metadata, transient: !triggerDirtyChange }, true);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ChangeCellMetadata, index: this._cells.indexOf(cell), metadata: cell.metadata, transient: !triggerDirtyChange }],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
|
||||
private _changeCellInternalMetadataPartial(cell: NotebookCellTextModel, internalMetadata: NullablePartialNotebookCellInternalMetadata) {
|
||||
|
@ -829,7 +838,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
}
|
||||
|
||||
cell.internalMetadata = newInternalMetadata;
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeCellInternalMetadata, index: this._cells.indexOf(cell), internalMetadata: cell.internalMetadata, transient: true }, true);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ChangeCellInternalMetadata, index: this._cells.indexOf(cell), internalMetadata: cell.internalMetadata, transient: true }],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
|
||||
private _changeCellLanguage(cell: NotebookCellTextModel, languageId: string, computeUndoRedo: boolean) {
|
||||
|
@ -857,7 +871,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
}(), undefined, undefined);
|
||||
}
|
||||
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeLanguage, index: this._cells.indexOf(cell), language: languageId, transient: false }, true, undefined);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.ChangeLanguage, index: this._cells.indexOf(cell), language: languageId, transient: false }],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
|
||||
private _spliceNotebookCellOutputs2(cell: NotebookCellTextModel, outputs: ICellOutput[], computeUndoRedo: boolean): void {
|
||||
|
@ -880,14 +899,18 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
|
||||
private _spliceNotebookCellOutputs(cell: NotebookCellTextModel, splice: NotebookCellOutputsSplice, append: boolean, computeUndoRedo: boolean): void {
|
||||
cell.spliceNotebookCellOutputs(splice);
|
||||
|
||||
this._eventEmitter.emit({
|
||||
kind: NotebookCellsChangeType.Output,
|
||||
index: this._cells.indexOf(cell),
|
||||
outputs: cell.outputs ?? [],
|
||||
append,
|
||||
transient: this.transientOptions.transientOutputs,
|
||||
}, true);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{
|
||||
kind: NotebookCellsChangeType.Output,
|
||||
index: this._cells.indexOf(cell),
|
||||
outputs: cell.outputs ?? [],
|
||||
append,
|
||||
transient: this.transientOptions.transientOutputs,
|
||||
}],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
|
||||
private _appendNotebookCellOutputItems(cell: NotebookCellTextModel, outputId: string, items: IOutputItemDto[]) {
|
||||
|
@ -899,14 +922,20 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
|
||||
const output = cell.outputs[outputIndex];
|
||||
output.appendData(items);
|
||||
this._eventEmitter.emit({
|
||||
kind: NotebookCellsChangeType.OutputItem,
|
||||
index: this._cells.indexOf(cell),
|
||||
outputId: output.outputId,
|
||||
outputItems: items,
|
||||
append: true,
|
||||
transient: this.transientOptions.transientOutputs
|
||||
}, true);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{
|
||||
kind: NotebookCellsChangeType.OutputItem,
|
||||
index: this._cells.indexOf(cell),
|
||||
outputId: output.outputId,
|
||||
outputItems: items,
|
||||
append: true,
|
||||
transient: this.transientOptions.transientOutputs
|
||||
|
||||
}],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
|
||||
private _replaceNotebookCellOutputItems(cell: NotebookCellTextModel, outputId: string, items: IOutputItemDto[]) {
|
||||
|
@ -918,14 +947,20 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
|
||||
const output = cell.outputs[outputIndex];
|
||||
output.replaceData(items);
|
||||
this._eventEmitter.emit({
|
||||
kind: NotebookCellsChangeType.OutputItem,
|
||||
index: this._cells.indexOf(cell),
|
||||
outputId: output.outputId,
|
||||
outputItems: items,
|
||||
append: false,
|
||||
transient: this.transientOptions.transientOutputs
|
||||
}, true, undefined);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{
|
||||
kind: NotebookCellsChangeType.OutputItem,
|
||||
index: this._cells.indexOf(cell),
|
||||
outputId: output.outputId,
|
||||
outputItems: items,
|
||||
append: false,
|
||||
transient: this.transientOptions.transientOutputs
|
||||
|
||||
}],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
|
||||
private _moveCellToIdx(index: number, length: number, newIdx: number, synchronous: boolean, pushedToUndoStack: boolean, beforeSelections: ISelectionState | undefined, endSelections: ISelectionState | undefined): boolean {
|
||||
|
@ -942,7 +977,12 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
|
||||
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);
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{ kind: NotebookCellsChangeType.Move, index, length, newIdx, cells, transient: false }],
|
||||
versionId: this.versionId,
|
||||
synchronous: synchronous,
|
||||
endSelectionState: endSelections
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -344,7 +344,7 @@ export type ISelectionState = ISelectionHandleState | ISelectionIndexState;
|
|||
export type NotebookTextModelChangedEvent = {
|
||||
readonly rawEvents: NotebookRawContentEvent[];
|
||||
readonly versionId: number;
|
||||
readonly synchronous: boolean;
|
||||
readonly synchronous: boolean | undefined;
|
||||
readonly endSelectionState: ISelectionState | undefined;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue