create "real" TextDocument when opening a notebook or when adding cells, don't create them again when the renderer makes models

This commit is contained in:
Johannes Rieken
2020-07-17 11:02:08 +02:00
parent c4dae68b49
commit 00dea1c4ad
8 changed files with 188 additions and 165 deletions

View File

@@ -11,14 +11,12 @@ import { ISplice } from 'vs/base/common/sequence';
import { URI, UriComponents } from 'vs/base/common/uri';
import * as UUID from 'vs/base/common/uuid';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { CellKind, ExtHostNotebookShape, IMainContext, MainContext, MainThreadNotebookShape, NotebookCellOutputsSplice, MainThreadDocumentsShape, INotebookEditorPropertiesChangeData, INotebookDocumentsAndEditorsDelta } from 'vs/workbench/api/common/extHost.protocol';
import { CellKind, ExtHostNotebookShape, IMainContext, MainContext, MainThreadNotebookShape, NotebookCellOutputsSplice, INotebookEditorPropertiesChangeData, INotebookDocumentsAndEditorsDelta, IModelAddedData } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { CellEditType, diff, ICellEditOperation, ICellInsertEdit, INotebookDisplayOrder, INotebookEditData, NotebookCellsChangedEvent, NotebookCellsSplice2, ICellDeleteEdit, notebookDocumentMetadataDefaults, NotebookCellsChangeType, NotebookDataDto, IOutputRenderRequest, IOutputRenderResponse, IOutputRenderResponseOutputInfo, IOutputRenderResponseCellInfo, IRawOutput, CellOutputKind, IProcessedOutput, INotebookKernelInfoDto2, IMainCellDto } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData';
import { NotImplementedProxy } from 'vs/base/common/types';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
@@ -57,28 +55,19 @@ interface INotebookEventEmitter {
const addIdToOutput = (output: IRawOutput, id = UUID.generateUuid()): IProcessedOutput => output.outputKind === CellOutputKind.Rich
? ({ ...output, outputId: id }) : output;
class DettachedCellDocumentData extends ExtHostDocumentData {
private static readonly _fakeProxy = new class extends NotImplementedProxy<MainThreadDocumentsShape>('document') {
$trySaveDocument() {
return Promise.reject('Cell-document cannot be saved');
}
};
constructor(cell: IMainCellDto) {
super(DettachedCellDocumentData._fakeProxy,
URI.revive(cell.uri),
cell.source,
cell.eol,
cell.language,
0,
false
);
}
}
export class ExtHostCell extends Disposable implements vscode.NotebookCell {
public static asModelAddData(cell: IMainCellDto): IModelAddedData {
return {
EOL: cell.eol,
lines: cell.source,
modeId: cell.language,
uri: cell.uri,
isDirty: false,
versionId: 1
};
}
private _onDidChangeOutputs = new Emitter<ISplice<IProcessedOutput>[]>();
readonly onDidChangeOutputs: Event<ISplice<IProcessedOutput>[]> = this._onDidChangeOutputs.event;
@@ -92,13 +81,6 @@ export class ExtHostCell extends Disposable implements vscode.NotebookCell {
readonly uri: URI;
readonly cellKind: CellKind;
// todo@jrieken this is a little fish because we have
// vscode.TextDocument for which we never fired an onDidOpen
// event and which doesn't appear in the list of documents.
// this will change once the "real" document comes along. We
// should come up with a better approach here...
readonly defaultDocument: DettachedCellDocumentData;
constructor(
private _proxy: MainThreadNotebookShape,
readonly notebook: ExtHostNotebookDocument,
@@ -110,7 +92,6 @@ export class ExtHostCell extends Disposable implements vscode.NotebookCell {
this.handle = cell.handle;
this.uri = URI.revive(cell.uri);
this.cellKind = cell.cellKind;
this.defaultDocument = new DettachedCellDocumentData(cell);
this._outputs = cell.outputs;
for (const output of this._outputs) {
@@ -126,7 +107,7 @@ export class ExtHostCell extends Disposable implements vscode.NotebookCell {
}
get document(): vscode.TextDocument {
return this._extHostDocument.getDocument(this.uri)?.document ?? this.defaultDocument.document;
return this._extHostDocument.getDocument(this.uri)!.document;
}
get language(): string {
@@ -368,7 +349,8 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
return;
}
let contentChangeEvents: vscode.NotebookCellsChangeData[] = [];
const contentChangeEvents: vscode.NotebookCellsChangeData[] = [];
const addedCellDocuments: IModelAddedData[] = [];
splices.reverse().forEach(splice => {
let cellDtos = splice[2];
@@ -376,6 +358,10 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
const extCell = new ExtHostCell(this._proxy, this, this._documentsAndEditors, cell);
if (!initialization) {
addedCellDocuments.push(ExtHostCell.asModelAddData(cell));
}
if (!this._cellDisposableMapping.has(extCell.handle)) {
this._cellDisposableMapping.set(extCell.handle, new DisposableStore());
}
@@ -392,21 +378,22 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
for (let j = splice[0]; j < splice[0] + splice[1]; j++) {
this._cellDisposableMapping.get(this.cells[j].handle)?.dispose();
this._cellDisposableMapping.delete(this.cells[j].handle);
}
const deletedItems = this.cells.splice(splice[0], splice[1], ...newCells);
const event: vscode.NotebookCellsChangeData = {
contentChangeEvents.push({
start: splice[0],
deletedCount: splice[1],
deletedItems,
items: newCells
};
contentChangeEvents.push(event);
});
});
if (addedCellDocuments) {
this._documentsAndEditors.$acceptDocumentsAndEditorsDelta({ addedDocuments: addedCellDocuments });
}
if (!initialization) {
this._emitter.emitModelChange({
document: this,
@@ -456,7 +443,6 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
private $changeCellLanguage(index: number, language: string): void {
const cell = this.cells[index];
cell.defaultDocument._acceptLanguageId(language);
const event: vscode.NotebookCellLanguageChangeEvent = { document: this, cell, language };
this._emitter.emitCellLanguageChange(event);
}
@@ -1427,6 +1413,9 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
}
if (delta.addedDocuments) {
const addedCellDocuments: IModelAddedData[] = [];
delta.addedDocuments.forEach(modelData => {
const revivedUri = URI.revive(modelData.uri);
const revivedUriStr = revivedUri.toString();
@@ -1470,6 +1459,9 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
]]
});
// add cell document as vscode.TextDocument
addedCellDocuments.push(...modelData.cells.map(ExtHostCell.asModelAddData));
this._documents.get(revivedUriStr)?.dispose();
this._documents.set(revivedUriStr, document);
@@ -1480,6 +1472,10 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
}
}
this._documentsAndEditors.$acceptDocumentsAndEditorsDelta({
addedDocuments: addedCellDocuments
});
const document = this._documents.get(revivedUriStr)!;
this._onDidOpenNotebookDocument.fire(document);
});