notebook editor worker service.

This commit is contained in:
rebornix 2020-08-20 10:53:42 -07:00
parent 065fde64cc
commit 509bc25f02
7 changed files with 508 additions and 80 deletions

View file

@ -653,6 +653,20 @@
"**/vs/workbench/services/**/{common,browser}/**"
]
},
{
"target": "**/vs/workbench/contrib/notebook/common/**",
"restrictions": [
"vs/nls",
"vs/css!./**/*",
"**/vs/base/**/{common,worker}/**",
"**/vs/platform/**/common/**",
"**/vs/editor/**",
"**/vs/workbench/common/**",
"**/vs/workbench/api/common/**",
"**/vs/workbench/services/**/common/**",
"**/vs/workbench/contrib/**/common/**"
]
},
{
"target": "**/vs/workbench/contrib/**/common/**",
"restrictions": [

View file

@ -42,8 +42,10 @@ import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { INotebookEditorModelResolverService, NotebookModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { NotebookDiffEditorInput } from './notebookDiffEditorInput';
import { NotebookDiffEditor } from './notebookDiffEditor';
import { NotebookDiffEditorInput } from 'vs/workbench/contrib/notebook/browser/notebookDiffEditorInput';
import { NotebookDiffEditor } from 'vs/workbench/contrib/notebook/browser/notebookDiffEditor';
import { INotebookEditorWorkerService } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerService';
import { NotebookEditorWorkerServiceImpl } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerServiceImpl';
// Editor Contribution
@ -438,6 +440,7 @@ workbenchContributionsRegistry.registerWorkbenchContribution(NotebookContributio
workbenchContributionsRegistry.registerWorkbenchContribution(CellContentProvider, LifecyclePhase.Starting);
registerSingleton(INotebookService, NotebookService);
registerSingleton(INotebookEditorWorkerService, NotebookEditorWorkerServiceImpl);
registerSingleton(INotebookEditorModelResolverService, NotebookModelResolverService, true);
const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);

View file

@ -16,15 +16,13 @@ import { NotebookEditorWidget } from 'vs/workbench/contrib/notebook/browser/note
import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { NotebookDiffEditorInput } from './notebookDiffEditorInput';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IDiffResult, LcsDiff } from 'vs/base/common/diff/diff';
import { CellSequence, INotebookDiffEditorModel } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookDiffEditorModel, INotebookDiffResult } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookDeltaDecoration } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
import { FileService } from 'vs/platform/files/common/fileService';
import { IFileService } from 'vs/platform/files/common/files';
import { DiffComputer } from 'vs/editor/common/diff/diffComputer';
import { createDecoration, DECORATIONS, isChangeOrDelete, isChangeOrInsert } from 'vs/editor/browser/widget/diffEditorWidget';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { Color } from 'vs/base/common/color';
@ -32,6 +30,7 @@ import { IModelDeltaDecoration, IReadonlyTextBuffer } from 'vs/editor/common/mod
import { Range } from 'vs/editor/common/core/range';
import { Constants } from 'vs/base/common/uint';
import { defaultInsertColor, defaultRemoveColor, diffInserted, diffRemoved } from 'vs/platform/theme/common/colorRegistry';
import { INotebookEditorWorkerService } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerService';
export class NotebookDiffEditor extends BaseEditor {
static readonly ID: string = 'workbench.editor.notebookDiffEditor';
@ -52,6 +51,7 @@ export class NotebookDiffEditor extends BaseEditor {
@ITelemetryService telemetryService: ITelemetryService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IStorageService storageService: IStorageService,
@INotebookEditorWorkerService private readonly notebookEditorWorkerService: INotebookEditorWorkerService
) {
super(NotebookDiffEditor.ID, telemetryService, themeService, storageService);
@ -149,10 +149,9 @@ export class NotebookDiffEditor extends BaseEditor {
}
private _update(model: INotebookDiffEditorModel) {
const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook));
const diffResult = diff.ComputeDiff(false);
this._adjustHeight(diffResult);
this.notebookEditorWorkerService.computeDiff(model.original.notebook.uri, model.modified.notebook.uri).then(diffResult => {
this._adjustHeight(diffResult);
});
}
private _setStrategy(newStrategy: DiffEditorWidgetSideBySide): void {
@ -162,13 +161,12 @@ export class NotebookDiffEditor extends BaseEditor {
this._strategy = newStrategy;
newStrategy.applyColors(this.themeService.getColorTheme());
// if (this._diffComputationResult) {
// this._updateDecorations();
// }
}
private _adjustHeight(diffResult: IDiffResult) {
private _adjustHeight(notebookDiffResult: INotebookDiffResult) {
const diffResult = notebookDiffResult.cellsDiff;
const linesDiffResult = notebookDiffResult.linesDiff;
if (!this._widget || !this._originalWidget) {
return;
}
@ -211,67 +209,37 @@ export class NotebookDiffEditor extends BaseEditor {
};
viewLayoutUpdateDisposables.push(...[
...originalCells.map(cell => (cell instanceof CodeCellViewModel) ? cell.onDidChangeLayout(e => update()) : (cell as MarkdownCellViewModel).onDidChangeLayout(e => update())),
...modifiedCells.map(cell => (cell instanceof CodeCellViewModel) ? cell.onDidChangeLayout(e => update()) : (cell as MarkdownCellViewModel).onDidChangeLayout(e => update())),
...originalCells.map(cell => (cell instanceof CodeCellViewModel) ? cell.onDidChangeLayout(() => update()) : (cell as MarkdownCellViewModel).onDidChangeLayout(() => update())),
...modifiedCells.map(cell => (cell instanceof CodeCellViewModel) ? cell.onDidChangeLayout(() => update()) : (cell as MarkdownCellViewModel).onDidChangeLayout(() => update())),
]);
update();
});
// console.log(diffResult);
diffResult.changes.forEach(change => {
if (change.modifiedLength === 0) {
// deletion ...
linesDiffResult.forEach(diff => {
const originalCell = this._originalWidget!.viewModel!.viewCells.find(cell => cell.handle === diff.originalCellhandle);
const modifiedCell = this._widget!.viewModel!.viewCells.find(cell => cell.handle === diff.modifiedCellhandle);
if (!originalCell || !modifiedCell) {
return;
}
if (change.originalLength === 0) {
// insertion
return;
}
const lineDecorations = this._strategy.getEditorsDiffDecorations(diff.lineChanges, false, false, originalCell.textBuffer, modifiedCell.textBuffer);
for (let i = 0, len = Math.min(change.modifiedLength, change.originalLength); i < len; i++) {
let originalIndex = change.originalStart + i;
let modifiedIndex = change.modifiedStart + i;
this._originalWidget?.changeModelDecorations(accessor => {
accessor.deltaDecorations([], [{
ownerId: diff.originalCellhandle,
decorations: lineDecorations.original.decorations
}]);
});
const originalCell = this._originalWidget!.viewModel!.viewCells[originalIndex];
const modifiedCell = this._widget!.viewModel!.viewCells[modifiedIndex];
if (originalCell.getText() !== modifiedCell.getText()) {
// console.log(`original cell ${originalIndex} content change`);
const originalLines = originalCell.textBuffer.getLinesContent();
const modifiedLines = modifiedCell.textBuffer.getLinesContent();
const diffComputer = new DiffComputer(originalLines, modifiedLines, {
shouldComputeCharChanges: true,
shouldPostProcessCharChanges: true,
shouldIgnoreTrimWhitespace: false,
shouldMakePrettyDiff: true,
maxComputationTime: 5000
});
const lineChanges = diffComputer.computeDiff().changes;
const lineDecorations = this._strategy.getEditorsDiffDecorations(lineChanges, false, false, originalCell.textBuffer, modifiedCell.textBuffer);
this._originalWidget?.changeModelDecorations(accessor => {
accessor.deltaDecorations([], [{
ownerId: originalCell.handle,
decorations: lineDecorations.original.decorations
}]);
});
this._widget?.changeModelDecorations(accessor => {
accessor.deltaDecorations([], [{
ownerId: modifiedCell.handle,
decorations: lineDecorations.modified.decorations
}]);
});
// console.log(lineDecorations);
} else {
// console.log(`original cell ${originalIndex} metadata change`);
}
}
this._widget?.changeModelDecorations(accessor => {
accessor.deltaDecorations([], [{
ownerId: diff.modifiedCellhandle,
decorations: lineDecorations.modified.decorations
}]);
});
});
this._originalCellDecorations = this._originalWidget.deltaCellDecorations(this._originalCellDecorations, originalDecorations);
@ -362,15 +330,6 @@ export class DiffEditorWidgetSideBySide extends Disposable {
}
public getEditorsDiffDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalModel: IReadonlyTextBuffer, modifiedModel: IReadonlyTextBuffer): IEditorsDiffDecorationsWithZones {
// Get view zones
// modifiedWhitespaces = modifiedWhitespaces.sort((a, b) => {
// return a.afterLineNumber - b.afterLineNumber;
// });
// originalWhitespaces = originalWhitespaces.sort((a, b) => {
// return a.afterLineNumber - b.afterLineNumber;
// });
// let zones = this._getViewZones(lineChanges, originalWhitespaces, modifiedWhitespaces, originalEditor, modifiedEditor, renderIndicators);
// Get decorations & overview ruler zones
let originalDecorations = this._getOriginalEditorDecorations(lineChanges, ignoreTrimWhitespace, renderIndicators, originalModel);
let modifiedDecorations = this._getModifiedEditorDecorations(lineChanges, ignoreTrimWhitespace, renderIndicators, modifiedModel);
@ -378,13 +337,9 @@ export class DiffEditorWidgetSideBySide extends Disposable {
return {
original: {
decorations: originalDecorations.decorations,
// overviewZones: originalDecorations.overviewZones,
// zones: zones.original
},
modified: {
decorations: modifiedDecorations.decorations,
// overviewZones: modifiedDecorations.overviewZones,
// zones: zones.modified
}
};
}

View file

@ -18,7 +18,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { Schemas } from 'vs/base/common/network';
import { IRevertOptions } from 'vs/workbench/common/editor';
import { basename } from 'vs/base/common/path';
import { ISequence } from 'vs/base/common/diff/diff';
import { IDiffResult, ISequence } from 'vs/base/common/diff/diff';
export enum CellKind {
Markdown = 1,
@ -715,3 +715,8 @@ export class CellSequence implements ISequence {
return hashValue;
}
}
export interface INotebookDiffResult {
cellsDiff: IDiffResult,
linesDiff: { originalCellhandle: number, modifiedCellhandle: number, lineChanges: editorCommon.ILineChange[] }[];
}

View file

@ -0,0 +1,207 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ISequence, LcsDiff } from 'vs/base/common/diff/diff';
import { hash } from 'vs/base/common/hash';
import { IDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { IRequestHandler } from 'vs/base/common/worker/simpleWorker';
import * as model from 'vs/editor/common/model';
import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder';
import { CellKind, ICellDto2, IMainCellDto, INotebookDiffResult, IProcessedOutput, NotebookCellMetadata, NotebookDataDto, NotebookDocumentMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { Range } from 'vs/editor/common/core/range';
import { DiffComputer } from 'vs/editor/common/diff/diffComputer';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { EditorWorkerHost } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerServiceImpl';
class MirrorCell {
private _textBuffer!: model.IReadonlyTextBuffer;
get textBuffer() {
if (this._textBuffer) {
return this._textBuffer;
}
const builder = new PieceTreeTextBufferBuilder();
builder.acceptChunk(Array.isArray(this._source) ? this._source.join('\n') : this._source);
const bufferFactory = builder.finish(true);
this._textBuffer = bufferFactory.create(model.DefaultEndOfLine.LF);
return this._textBuffer;
}
private _hash: number | null = null;
constructor(
readonly handle: number,
private _source: string | string[],
readonly language: string,
readonly cellKind: CellKind,
readonly outputs: IProcessedOutput[],
readonly metadata?: NotebookCellMetadata
) { }
getFullModelRange() {
const lineCount = this.textBuffer.getLineCount();
return new Range(1, 1, lineCount, this.textBuffer.getLineLength(lineCount) + 1);
}
getValue(): string {
const fullRange = this.getFullModelRange();
const eol = this.textBuffer.getEOL();
if (eol === '\n') {
return this.textBuffer.getValueInRange(fullRange, model.EndOfLinePreference.LF);
} else {
return this.textBuffer.getValueInRange(fullRange, model.EndOfLinePreference.CRLF);
}
}
getHashValue(): number {
if (this._hash !== null) {
return this._hash;
}
this._hash = hash([hash(this.getValue()), this.metadata]);
// this._hash = hash(this.getValue());
return this._hash;
}
}
class MirrorNotebookDocument {
constructor(
readonly uri: URI,
readonly cells: MirrorCell[],
readonly languages: string[],
readonly metadata: NotebookDocumentMetadata,
) {
}
}
export class CellSequence implements ISequence {
constructor(readonly textModel: MirrorNotebookDocument) {
}
getElements(): string[] | number[] | Int32Array {
const hashValue = new Int32Array(this.textModel.cells.length);
for (let i = 0; i < this.textModel.cells.length; i++) {
hashValue[i] = this.textModel.cells[i].getHashValue();
}
return hashValue;
}
getCellHash(cell: ICellDto2) {
const source = Array.isArray(cell.source) ? cell.source.join('\n') : cell.source;
const hashVal = hash([hash(source), cell.metadata]);
return hashVal;
}
}
export class NotebookEditorSimpleWorker implements IRequestHandler, IDisposable {
_requestHandlerBrand: any;
private _models: { [uri: string]: MirrorNotebookDocument; };
constructor() {
this._models = Object.create(null);
}
dispose(): void {
}
public acceptNewModel(uri: string, data: NotebookDataDto): void {
this._models[uri] = new MirrorNotebookDocument(URI.parse(uri), data.cells.map(dto => new MirrorCell(
(dto as IMainCellDto).handle,
dto.source,
dto.language,
dto.cellKind,
dto.outputs,
dto.metadata
)), data.languages, data.metadata);
}
public acceptRemovedModel(strURL: string): void {
if (!this._models[strURL]) {
return;
}
delete this._models[strURL];
}
computeDiff(originalUrl: string, modifiedUrl: string): INotebookDiffResult {
const original = this._getModel(originalUrl);
const modified = this._getModel(modifiedUrl);
const diff = new LcsDiff(new CellSequence(original), new CellSequence(modified));
const diffResult = diff.ComputeDiff(false);
let cellLineChanges: { originalCellhandle: number, modifiedCellhandle: number, lineChanges: editorCommon.ILineChange[] }[] = [];
diffResult.changes.forEach(change => {
if (change.modifiedLength === 0) {
// deletion ...
return;
}
if (change.originalLength === 0) {
// insertion
return;
}
for (let i = 0, len = Math.min(change.modifiedLength, change.originalLength); i < len; i++) {
let originalIndex = change.originalStart + i;
let modifiedIndex = change.modifiedStart + i;
const originalCell = original.cells[originalIndex];
const modifiedCell = modified.cells[modifiedIndex];
if (originalCell.getValue() !== modifiedCell.getValue()) {
// console.log(`original cell ${originalIndex} content change`);
const originalLines = originalCell.textBuffer.getLinesContent();
const modifiedLines = modifiedCell.textBuffer.getLinesContent();
const diffComputer = new DiffComputer(originalLines, modifiedLines, {
shouldComputeCharChanges: true,
shouldPostProcessCharChanges: true,
shouldIgnoreTrimWhitespace: false,
shouldMakePrettyDiff: true,
maxComputationTime: 5000
});
const lineChanges = diffComputer.computeDiff().changes;
cellLineChanges.push({
originalCellhandle: originalCell.handle,
modifiedCellhandle: modifiedCell.handle,
lineChanges
});
// console.log(lineDecorations);
} else {
// console.log(`original cell ${originalIndex} metadata change`);
}
}
});
return {
cellsDiff: diffResult,
linesDiff: cellLineChanges
};
}
protected _getModel(uri: string): MirrorNotebookDocument {
return this._models[uri];
}
}
/**
* Called on the worker side
* @internal
*/
export function create(host: EditorWorkerHost): IRequestHandler {
return new NotebookEditorSimpleWorker();
}

View file

@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { ILineChange } from 'vs/editor/common/editorCommon';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { INotebookDiffResult } from 'vs/workbench/contrib/notebook/common/notebookCommon';
export const ID_NOTEBOOK_EDITOR_WORKER_SERVICE = 'notebookEditorWorkerService';
export const INotebookEditorWorkerService = createDecorator<INotebookEditorWorkerService>(ID_NOTEBOOK_EDITOR_WORKER_SERVICE);
export interface IDiffComputationResult {
quitEarly: boolean;
identical: boolean;
changes: ILineChange[];
}
export interface INotebookEditorWorkerService {
readonly _serviceBrand: undefined;
canComputeDiff(original: URI, modified: URI): boolean;
computeDiff(original: URI, modified: URI): Promise<INotebookDiffResult>;
}

View file

@ -0,0 +1,219 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable, DisposableStore, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { SimpleWorkerClient } from 'vs/base/common/worker/simpleWorker';
import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory';
import { INotebookDiffResult } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { NotebookEditorSimpleWorker } from 'vs/workbench/contrib/notebook/common/services/notebookSimpleWorker';
import { INotebookEditorWorkerService } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerService';
export class NotebookEditorWorkerServiceImpl extends Disposable implements INotebookEditorWorkerService {
declare readonly _serviceBrand: undefined;
private readonly _workerManager: WorkerManager;
constructor(
@INotebookService notebookService: INotebookService
) {
super();
this._workerManager = this._register(new WorkerManager(notebookService));
}
canComputeDiff(original: URI, modified: URI): boolean {
throw new Error('Method not implemented.');
}
computeDiff(original: URI, modified: URI): Promise<INotebookDiffResult> {
return this._workerManager.withWorker().then(client => {
return client.computeDiff(original, modified);
});
}
}
export class WorkerManager extends Disposable {
private _editorWorkerClient: NotebookWorkerClient | null;
// private _lastWorkerUsedTime: number;
constructor(
private readonly _notebookService: INotebookService
) {
super();
this._editorWorkerClient = null;
// this._lastWorkerUsedTime = (new Date()).getTime();
}
withWorker(): Promise<NotebookWorkerClient> {
// this._lastWorkerUsedTime = (new Date()).getTime();
if (!this._editorWorkerClient) {
this._editorWorkerClient = new NotebookWorkerClient(this._notebookService, 'notebookEditorWorkerService');
}
return Promise.resolve(this._editorWorkerClient);
}
}
export interface IWorkerClient<W> {
getProxyObject(): Promise<W>;
dispose(): void;
}
export class NotebookEditorModelManager extends Disposable {
private _syncedModels: { [modelUrl: string]: IDisposable; } = Object.create(null);
private _syncedModelsLastUsedTime: { [modelUrl: string]: number; } = Object.create(null);
constructor(
private readonly _proxy: NotebookEditorSimpleWorker,
private readonly _notebookService: INotebookService
) {
super();
}
public ensureSyncedResources(resources: URI[]): void {
for (const resource of resources) {
let resourceStr = resource.toString();
if (!this._syncedModels[resourceStr]) {
this._beginModelSync(resource);
}
if (this._syncedModels[resourceStr]) {
this._syncedModelsLastUsedTime[resourceStr] = (new Date()).getTime();
}
}
}
private _beginModelSync(resource: URI): void {
let model = this._notebookService.listNotebookDocuments().find(document => document.uri.toString() === resource.toString());
if (!model) {
return;
}
let modelUrl = resource.toString();
this._proxy.acceptNewModel(
model.uri.toString(),
{
cells: model.cells.map(cell => ({
handle: cell.handle,
uri: cell.uri,
source: cell.textBuffer.getLinesContent(),
eol: cell.textBuffer.getEOL(),
language: cell.language,
cellKind: cell.cellKind,
outputs: cell.outputs,
metadata: cell.metadata
})),
languages: model.languages,
metadata: model.metadata
}
);
const toDispose = new DisposableStore();
// TODO, accept Model change
// toDispose.add(model.onDidChangeContent((e) => {
// this._proxy.acceptModelChanged(modelUrl.toString(), e);
// }));
toDispose.add(model.onWillDispose(() => {
this._stopModelSync(modelUrl);
}));
toDispose.add(toDisposable(() => {
this._proxy.acceptRemovedModel(modelUrl);
}));
this._syncedModels[modelUrl] = toDispose;
}
private _stopModelSync(modelUrl: string): void {
let toDispose = this._syncedModels[modelUrl];
delete this._syncedModels[modelUrl];
delete this._syncedModelsLastUsedTime[modelUrl];
dispose(toDispose);
}
}
export class EditorWorkerHost {
private readonly _workerClient: NotebookWorkerClient;
constructor(workerClient: NotebookWorkerClient) {
this._workerClient = workerClient;
}
// foreign host request
public fhr(method: string, args: any[]): Promise<any> {
return this._workerClient.fhr(method, args);
}
}
export class NotebookWorkerClient extends Disposable {
private _worker: IWorkerClient<NotebookEditorSimpleWorker> | null;
private readonly _workerFactory: DefaultWorkerFactory;
private _modelManager: NotebookEditorModelManager | null;
constructor(private readonly _notebookService: INotebookService, label: string) {
super();
this._workerFactory = new DefaultWorkerFactory(label);
this._worker = null;
this._modelManager = null;
}
// foreign host request
public fhr(method: string, args: any[]): Promise<any> {
throw new Error(`Not implemented!`);
}
computeDiff(original: URI, modified: URI) {
return this._withSyncedResources([original, modified]).then(proxy => {
return proxy.computeDiff(original.toString(), modified.toString());
});
}
private _getOrCreateModelManager(proxy: NotebookEditorSimpleWorker): NotebookEditorModelManager {
if (!this._modelManager) {
this._modelManager = this._register(new NotebookEditorModelManager(proxy, this._notebookService));
}
return this._modelManager;
}
protected _withSyncedResources(resources: URI[]): Promise<NotebookEditorSimpleWorker> {
return this._getProxy().then((proxy) => {
this._getOrCreateModelManager(proxy).ensureSyncedResources(resources);
return proxy;
});
}
private _getOrCreateWorker(): IWorkerClient<NotebookEditorSimpleWorker> {
if (!this._worker) {
try {
this._worker = this._register(new SimpleWorkerClient<NotebookEditorSimpleWorker, EditorWorkerHost>(
this._workerFactory,
'vs/workbench/contrib/notebook/common/services/notebookSimpleWorker',
new EditorWorkerHost(this)
));
} catch (err) {
// logOnceWebWorkerWarning(err);
// this._worker = new SynchronousWorkerClient(new EditorSimpleWorker(new EditorWorkerHost(this), null));
throw (err);
}
}
return this._worker;
}
protected _getProxy(): Promise<NotebookEditorSimpleWorker> {
return this._getOrCreateWorker().getProxyObject().then(undefined, (err) => {
// logOnceWebWorkerWarning(err);
// this._worker = new SynchronousWorkerClient(new EditorSimpleWorker(new EditorWorkerHost(this), null));
// return this._getOrCreateWorker().getProxyObject();
throw (err);
});
}
}