Update output editor when output model is being updated.
This commit is contained in:
parent
8e18e33892
commit
c1f2f40bcd
|
@ -13,7 +13,7 @@ import { format } from 'vs/base/common/jsonFormatter';
|
|||
import { applyEdits } from 'vs/base/common/jsonEdit';
|
||||
import { ITextModel, ITextBufferFactory, DefaultEndOfLine, ITextBuffer } from 'vs/editor/common/model';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { ILanguageSelection, IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { ITextModelContentProvider, ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import * as nls from 'vs/nls';
|
||||
import { Extensions, IConfigurationPropertySchema, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
|
@ -100,6 +100,7 @@ import { NotebookExecutionService } from 'vs/workbench/contrib/notebook/browser/
|
|||
import { INotebookExecutionService } from 'vs/workbench/contrib/notebook/common/notebookExecutionService';
|
||||
import { INotebookKeymapService } from 'vs/workbench/contrib/notebook/common/notebookKeymapService';
|
||||
import { NotebookKeymapService } from 'vs/workbench/contrib/notebook/browser/notebookKeymapServiceImpl';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
|
||||
/*--------------------------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -372,25 +373,55 @@ class CellInfoContentProvider {
|
|||
return result;
|
||||
}
|
||||
|
||||
private parseStreamOutput(resource: URI, op?: ICellOutput) {
|
||||
private parseStreamOutput(op?: ICellOutput): { content: string, mode: ILanguageSelection } | undefined {
|
||||
if (!op) {
|
||||
return;
|
||||
}
|
||||
|
||||
const streamOutputData = getStreamOutputData(op.outputs);
|
||||
if (streamOutputData) {
|
||||
const result = this._modelService.createModel(
|
||||
streamOutputData,
|
||||
this._modeService.create('plaintext'),
|
||||
resource
|
||||
);
|
||||
|
||||
return result;
|
||||
return {
|
||||
content: streamOutputData,
|
||||
mode: this._modeService.create('plaintext')
|
||||
};
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private _getResult(data: {
|
||||
notebook: URI;
|
||||
handle: number;
|
||||
outputId?: string | undefined;
|
||||
}, cell: NotebookCellTextModel) {
|
||||
let result: { content: string, mode: ILanguageSelection } | undefined = undefined;
|
||||
|
||||
const mode = this._modeService.create('json');
|
||||
const op = cell.outputs.find(op => op.outputId === data.outputId);
|
||||
const streamOutputData = this.parseStreamOutput(op);
|
||||
if (streamOutputData) {
|
||||
result = streamOutputData;
|
||||
return result;
|
||||
}
|
||||
|
||||
const content = JSON.stringify(cell.outputs.map(output => ({
|
||||
metadata: output.metadata,
|
||||
outputItems: output.outputs.map(opit => ({
|
||||
mimeType: opit.mime,
|
||||
data: opit.data.toString()
|
||||
}))
|
||||
})));
|
||||
|
||||
const edits = format(content, undefined, {});
|
||||
const outputSource = applyEdits(content, edits);
|
||||
result = {
|
||||
content: outputSource,
|
||||
mode
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async provideOutputTextContent(resource: URI): Promise<ITextModel | null> {
|
||||
const existing = this._modelService.getModel(resource);
|
||||
if (existing) {
|
||||
|
@ -403,48 +434,37 @@ class CellInfoContentProvider {
|
|||
}
|
||||
|
||||
const ref = await this._notebookModelResolverService.resolve(data.notebook);
|
||||
let result: ITextModel | null = null;
|
||||
const cell = ref.object.notebook.cells.find(cell => cell.handle === data.handle);
|
||||
|
||||
const mode = this._modeService.create('json');
|
||||
|
||||
for (const cell of ref.object.notebook.cells) {
|
||||
if (cell.handle !== data.handle) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const op = cell.outputs.find(op => op.outputId === data.outputId);
|
||||
const streamOutputData = this.parseStreamOutput(resource, op);
|
||||
if (streamOutputData) {
|
||||
result = streamOutputData;
|
||||
break;
|
||||
}
|
||||
|
||||
const content = JSON.stringify(cell.outputs.map(output => ({
|
||||
metadata: output.metadata,
|
||||
outputItems: output.outputs.map(opit => ({
|
||||
mimeType: opit.mime,
|
||||
data: opit.data.toString()
|
||||
}))
|
||||
})));
|
||||
|
||||
const edits = format(content, undefined, {});
|
||||
const outputSource = applyEdits(content, edits);
|
||||
result = this._modelService.createModel(
|
||||
outputSource,
|
||||
mode,
|
||||
resource
|
||||
);
|
||||
break;
|
||||
if (!cell) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const result = this._getResult(data, cell);
|
||||
|
||||
if (result) {
|
||||
const once = result.onWillDispose(() => {
|
||||
const model = this._modelService.createModel(result.content, result.mode, resource);
|
||||
const cellModelListener = Event.any(cell.onDidChangeOutputs, cell.onDidChangeOutputItems)(() => {
|
||||
const newResult = this._getResult(data, cell);
|
||||
|
||||
if (!newResult) {
|
||||
return;
|
||||
}
|
||||
|
||||
model.setValue(newResult.content);
|
||||
model.setMode(newResult.mode.languageId);
|
||||
});
|
||||
|
||||
const once = model.onWillDispose(() => {
|
||||
once.dispose();
|
||||
cellModelListener.dispose();
|
||||
ref.dispose();
|
||||
});
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,15 @@ import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeText
|
|||
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { NotebookCellOutputTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel';
|
||||
import { CellInternalMetadataChangedEvent, CellKind, ICell, ICellOutput, IOutputDto, NotebookCellInternalMetadata, NotebookCellMetadata, NotebookCellOutputsSplice, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellInternalMetadataChangedEvent, CellKind, ICell, ICellOutput, IOutputDto, IOutputItemDto, NotebookCellInternalMetadata, NotebookCellMetadata, NotebookCellOutputsSplice, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
||||
export class NotebookCellTextModel extends Disposable implements ICell {
|
||||
private readonly _onDidChangeOutputs = this._register(new Emitter<NotebookCellOutputsSplice>());
|
||||
onDidChangeOutputs: Event<NotebookCellOutputsSplice> = this._onDidChangeOutputs.event;
|
||||
|
||||
private readonly _onDidChangeOutputItems = this._register(new Emitter<void>());
|
||||
onDidChangeOutputItems: Event<void> = this._onDidChangeOutputItems.event;
|
||||
|
||||
private readonly _onDidChangeContent = this._register(new Emitter<'content' | 'language' | 'mime'>());
|
||||
onDidChangeContent: Event<'content' | 'language' | 'mime'> = this._onDidChangeContent.event;
|
||||
|
||||
|
@ -264,6 +267,24 @@ export class NotebookCellTextModel extends Disposable implements ICell {
|
|||
this._onDidChangeOutputs.fire(splice);
|
||||
}
|
||||
|
||||
changeOutputItems(outputId: string, append: boolean, items: IOutputItemDto[]): boolean {
|
||||
const outputIndex = this.outputs.findIndex(output => output.outputId === outputId);
|
||||
|
||||
if (outputIndex < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const output = this.outputs[outputIndex];
|
||||
if (append) {
|
||||
output.appendData(items);
|
||||
} else {
|
||||
output.replaceData(items);
|
||||
}
|
||||
|
||||
this._onDidChangeOutputItems.fire();
|
||||
return true;
|
||||
}
|
||||
|
||||
private _outputNotEqualFastCheck(left: ICellOutput[], right: ICellOutput[]) {
|
||||
if (left.length !== right.length) {
|
||||
return false;
|
||||
|
|
|
@ -955,53 +955,41 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
}
|
||||
|
||||
private _appendNotebookCellOutputItems(cell: NotebookCellTextModel, outputId: string, items: IOutputItemDto[]) {
|
||||
const outputIndex = cell.outputs.findIndex(output => output.outputId === outputId);
|
||||
if (cell.changeOutputItems(outputId, true, items)) {
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{
|
||||
kind: NotebookCellsChangeType.OutputItem,
|
||||
index: this._cells.indexOf(cell),
|
||||
outputId: outputId,
|
||||
outputItems: items,
|
||||
append: true,
|
||||
transient: this.transientOptions.transientOutputs
|
||||
|
||||
if (outputIndex < 0) {
|
||||
return;
|
||||
}],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
|
||||
const output = cell.outputs[outputIndex];
|
||||
output.appendData(items);
|
||||
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[]) {
|
||||
const outputIndex = cell.outputs.findIndex(output => output.outputId === outputId);
|
||||
if (cell.changeOutputItems(outputId, false, items)) {
|
||||
this._pauseableEmitter.fire({
|
||||
rawEvents: [{
|
||||
kind: NotebookCellsChangeType.OutputItem,
|
||||
index: this._cells.indexOf(cell),
|
||||
outputId: outputId,
|
||||
outputItems: items,
|
||||
append: false,
|
||||
transient: this.transientOptions.transientOutputs
|
||||
|
||||
if (outputIndex < 0) {
|
||||
return;
|
||||
}],
|
||||
versionId: this.versionId,
|
||||
synchronous: true,
|
||||
endSelectionState: undefined
|
||||
});
|
||||
}
|
||||
|
||||
const output = cell.outputs[outputIndex];
|
||||
output.replaceData(items);
|
||||
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 {
|
||||
|
|
Loading…
Reference in a new issue