chore - extract ExtHostNotebookEditor into its own file

This commit is contained in:
Johannes Rieken
2020-09-09 11:56:54 +02:00
parent 6e35aa3ceb
commit 82ac7bacf3
2 changed files with 262 additions and 243 deletions

View File

@@ -4,13 +4,12 @@
*--------------------------------------------------------------------------------------------*/
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { readonly } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
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, ICommandDto, IMainContext, IModelAddedData, INotebookDocumentPropertiesChangeData, INotebookDocumentsAndEditorsDelta, INotebookEditorPropertiesChangeData, MainContext, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostNotebookShape, ICommandDto, IMainContext, IModelAddedData, INotebookDocumentPropertiesChangeData, INotebookDocumentsAndEditorsDelta, INotebookEditorPropertiesChangeData, MainContext, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
import { ILogService } from 'vs/platform/log/common/log';
import { CommandsConverter, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
@@ -18,104 +17,11 @@ import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePa
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import { addIdToOutput, CellEditType, CellStatusbarAlignment, CellUri, ICellEditOperation, ICellReplaceEdit, INotebookCellStatusBarEntry, INotebookDisplayOrder, INotebookEditData, INotebookKernelInfoDto2, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookDataDto, NotebookDocumentMetadata, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { addIdToOutput, CellStatusbarAlignment, CellUri, INotebookCellStatusBarEntry, INotebookDisplayOrder, INotebookKernelInfoDto2, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookDataDto, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import * as vscode from 'vscode';
import { ResourceMap } from 'vs/base/common/map';
import { ExtHostCell, ExtHostNotebookDocument } from './extHostNotebookDocument';
export class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit {
private readonly _documentVersionId: number;
private _finalized: boolean = false;
private _collectedEdits: ICellEditOperation[] = [];
private _newNotebookDocumentMetadata?: NotebookDocumentMetadata;
constructor(documentVersionId: number) {
this._documentVersionId = documentVersionId;
}
finalize(): INotebookEditData {
this._finalized = true;
return {
documentVersionId: this._documentVersionId,
cellEdits: this._collectedEdits,
newMetadata: this._newNotebookDocumentMetadata
};
}
private _throwIfFinalized() {
if (this._finalized) {
throw new Error('Edit is only valid while callback runs');
}
}
replaceNotebookMetadata(value: vscode.NotebookDocumentMetadata): void {
this._throwIfFinalized();
this._newNotebookDocumentMetadata = { ...notebookDocumentMetadataDefaults, ...value };
}
replaceCellMetadata(index: number, metadata: vscode.NotebookCellMetadata): void {
this._throwIfFinalized();
this._collectedEdits.push({
editType: CellEditType.Metadata,
index,
metadata
});
}
replaceMetadata(index: number, metadata: vscode.NotebookCellMetadata): void {
console.warn('DEPRECATED use "replaceCellMetadata" instead');
this.replaceCellMetadata(index, metadata);
}
replaceCellOutput(index: number, outputs: vscode.CellOutput[]): void {
this._throwIfFinalized();
this._collectedEdits.push({
editType: CellEditType.Output,
index,
outputs: outputs.map(output => addIdToOutput(output))
});
}
replaceOutput(index: number, outputs: vscode.CellOutput[]): void {
console.warn('DEPRECATED use "replaceCellOutput" instead');
this.replaceCellOutput(index, outputs);
}
replaceCells(from: number, to: number, cells: vscode.NotebookCellData[]): void {
this._throwIfFinalized();
this._collectedEdits.push({
editType: CellEditType.Replace,
index: from,
count: to - from,
cells: cells.map(data => {
return {
...data,
outputs: data.outputs.map(output => addIdToOutput(output)),
};
})
});
}
insert(index: number, content: string | string[], language: string, type: CellKind, outputs: vscode.CellOutput[], metadata: vscode.NotebookCellMetadata | undefined): void {
this._throwIfFinalized();
this.replaceCells(index, index, [{
language,
outputs,
metadata,
cellKind: type,
source: Array.isArray(content) ? content.join('\n') : content,
}]);
}
delete(index: number): void {
this._throwIfFinalized();
this.replaceCells(index, 1, []);
}
}
import { ExtHostNotebookEditor } from './extHostNotebookEditor';
class ExtHostWebviewCommWrapper extends Disposable {
private readonly _onDidReceiveDocumentMessage = new Emitter<any>();
@@ -162,152 +68,7 @@ class ExtHostWebviewCommWrapper extends Disposable {
}
}
export class ExtHostNotebookEditor extends Disposable implements vscode.NotebookEditor {
private _viewColumn: vscode.ViewColumn | undefined;
selection?: vscode.NotebookCell;
private _visibleRanges: vscode.NotebookCellRange[] = [];
get visibleRanges() {
return this._visibleRanges;
}
set visibleRanges(_range: vscode.NotebookCellRange[]) {
throw readonly('visibleRanges');
}
_acceptVisibleRanges(value: vscode.NotebookCellRange[]): void {
this._visibleRanges = value;
}
private _active: boolean = false;
get active(): boolean {
return this._active;
}
set active(_state: boolean) {
throw readonly('active');
}
private _visible: boolean = false;
get visible(): boolean {
return this._visible;
}
set visible(_state: boolean) {
throw readonly('visible');
}
_acceptVisibility(value: boolean) {
this._visible = value;
}
_acceptActive(value: boolean) {
this._active = value;
}
private _kernel?: vscode.NotebookKernel;
get kernel() {
return this._kernel;
}
set kernel(_kernel: vscode.NotebookKernel | undefined) {
throw readonly('kernel');
}
private _onDidDispose = new Emitter<void>();
readonly onDidDispose: Event<void> = this._onDidDispose.event;
private _onDidReceiveMessage = new Emitter<any>();
onDidReceiveMessage: vscode.Event<any> = this._onDidReceiveMessage.event;
constructor(
private readonly viewType: string,
readonly id: string,
public uri: URI,
private _proxy: MainThreadNotebookShape,
private _webComm: vscode.NotebookCommunication,
public readonly notebookData: ExtHostNotebookDocument,
) {
super();
this._register(this._webComm.onDidReceiveMessage(e => {
this._onDidReceiveMessage.fire(e);
}));
}
get document(): vscode.NotebookDocument {
return this.notebookData.notebookDocument;
}
edit(callback: (editBuilder: NotebookEditorCellEditBuilder) => void): Thenable<boolean> {
const edit = new NotebookEditorCellEditBuilder(this.document.version);
callback(edit);
return this._applyEdit(edit.finalize());
}
private _applyEdit(editData: INotebookEditData): Promise<boolean> {
// return when there is nothing to do
if (editData.cellEdits.length === 0) {
return Promise.resolve(true);
}
const compressedEdits: ICellEditOperation[] = [];
let compressedEditsIndex = -1;
for (let i = 0; i < editData.cellEdits.length; i++) {
if (compressedEditsIndex < 0) {
compressedEdits.push(editData.cellEdits[i]);
compressedEditsIndex++;
continue;
}
const prevIndex = compressedEditsIndex;
const prev = compressedEdits[prevIndex];
if (prev.editType === CellEditType.Replace && editData.cellEdits[i].editType === CellEditType.Replace) {
if (prev.index === editData.cellEdits[i].index) {
prev.cells.push(...(editData.cellEdits[i] as ICellReplaceEdit).cells);
prev.count += (editData.cellEdits[i] as ICellReplaceEdit).count;
continue;
}
}
compressedEdits.push(editData.cellEdits[i]);
compressedEditsIndex++;
}
return this._proxy.$tryApplyEdits(this.viewType, this.uri, editData.documentVersionId, compressedEdits, editData.newMetadata);
}
revealRange(range: vscode.NotebookCellRange, revealType?: extHostTypes.NotebookEditorRevealType) {
this._proxy.$tryRevealRange(this.id, range, revealType || extHostTypes.NotebookEditorRevealType.Default);
}
get viewColumn(): vscode.ViewColumn | undefined {
return this._viewColumn;
}
set viewColumn(value) {
throw readonly('viewColumn');
}
updateActiveKernel(kernel?: vscode.NotebookKernel) {
this._kernel = kernel;
}
async postMessage(message: any): Promise<boolean> {
return this._webComm.postMessage(message);
}
asWebviewUri(localResource: vscode.Uri): vscode.Uri {
return this._webComm.asWebviewUri(localResource);
}
dispose() {
this._onDidDispose.fire();
super.dispose();
}
}
export interface ExtHostNotebookOutputRenderingHandler {
outputDisplayOrder: INotebookDisplayOrder | undefined;
@@ -755,7 +516,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
const kernel = event.kernelId ? adapter.getKernel(event.kernelId) : undefined;
this._editors.forEach(editor => {
if (editor.editor.notebookData === document) {
editor.editor.updateActiveKernel(kernel);
editor.editor._acceptKernel(kernel);
}
});
this._onDidChangeActiveNotebookKernel.fire({ document: document.notebookDocument, kernel });