From 89d3b684a288ef65b8d4eaf47a92262fdbe8e72b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 12 Mar 2020 22:15:21 -0700 Subject: [PATCH] Use unique resource for custom editor working copy For #92037 Ensures that we can open multiple types of custom editors are opened for the same resource, and that our dirty tracking works as expected in that case (by only marking editors of a given type dirty) --- .../api/browser/mainThreadWebview.ts | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index 3f5ee9c4f52..332017e9ee0 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -536,6 +536,8 @@ namespace HotExitState { export type State = typeof Allowed | typeof NotAllowed | Pending; } +const customDocumentFileScheme = 'custom'; + class MainThreadCustomEditorModel extends Disposable implements ICustomEditorModel, IWorkingCopy { private _hotExitState: HotExitState.State = HotExitState.Allowed; @@ -556,7 +558,7 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod constructor( private readonly _proxy: extHostProtocol.ExtHostWebviewsShape, private readonly _viewType: string, - private readonly _resource: URI, + private readonly _realResource: URI, private readonly _editable: boolean, @IWorkingCopyService workingCopyService: IWorkingCopyService, @ILabelService private readonly _labelService: ILabelService, @@ -564,6 +566,7 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod @IUndoRedoService private readonly _undoService: IUndoRedoService, ) { super(); + if (_editable) { this._register(workingCopyService.registerWorkingCopy(this)); } @@ -571,18 +574,26 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod dispose() { if (this._editable) { - this._undoService.removeElements(this.resource); + this._undoService.removeElements(this._realResource); } - this._proxy.$disposeWebviewCustomEditorDocument(this.resource, this._viewType); + this._proxy.$disposeWebviewCustomEditorDocument(this._realResource, this._viewType); super.dispose(); } //#region IWorkingCopy - public get resource() { return this._resource; } // custom://viewType/path/file + public get resource() { + // Make sure each custom editor has a unique resource for backup and edits + return URI.from({ + scheme: customDocumentFileScheme, + authority: this._viewType, + path: this._realResource.path, + query: JSON.stringify(this._realResource.toJSON()) + }); + } public get name() { - return basename(this._labelService.getUriLabel(this._resource)); + return basename(this._labelService.getUriLabel(this._realResource)); } public get capabilities(): WorkingCopyCapabilities { @@ -617,7 +628,7 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod this._undoService.pushElement({ type: UndoRedoElementType.Resource, - resource: this.resource, + resource: this._realResource, label: label ?? localize('defaultEditLabel', "Edit"), undo: () => this.undo(), redo: () => this.redo(), @@ -635,7 +646,7 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod } const undoneEdit = this._edits[this._currentEditIndex]; - await this._proxy.$undo(this.resource, this.viewType, undoneEdit); + await this._proxy.$undo(this._realResource, this.viewType, undoneEdit); this.change(() => { --this._currentEditIndex; @@ -653,7 +664,7 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod } const redoneEdit = this._edits[this._currentEditIndex + 1]; - await this._proxy.$redo(this.resource, this.viewType, redoneEdit); + await this._proxy.$redo(this._realResource, this.viewType, redoneEdit); this.change(() => { ++this._currentEditIndex; }); @@ -668,7 +679,7 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod : this._edits.splice(start, toRemove); if (removedEdits.length) { - this._proxy.$disposeEdits(this.resource, this._viewType, removedEdits); + this._proxy.$disposeEdits(this._realResource, this._viewType, removedEdits); } } @@ -700,7 +711,7 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod editsToRedo = this._edits.slice(this._currentEditIndex, this._savePoint); } - this._proxy.$revert(this.resource, this.viewType, { undoneEdits: editsToUndo, redoneEdits: editsToRedo }); + this._proxy.$revert(this._realResource, this.viewType, { undoneEdits: editsToUndo, redoneEdits: editsToRedo }); this.change(() => { this._currentEditIndex = this._savePoint; this.spliceEdits(); @@ -711,7 +722,7 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod if (!this._editable) { return false; } - await createCancelablePromise(token => this._proxy.$onSave(this.resource, this.viewType, token)); + await createCancelablePromise(token => this._proxy.$onSave(this._realResource, this.viewType, token)); this.change(() => { this._savePoint = this._currentEditIndex; }); @@ -720,7 +731,7 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod public async saveAs(resource: URI, targetResource: URI, _options?: ISaveOptions): Promise { if (this._editable) { - await this._proxy.$onSaveAs(this.resource, this.viewType, targetResource); + await this._proxy.$onSaveAs(this._realResource, this.viewType, targetResource); this.change(() => { this._savePoint = this._currentEditIndex; }); @@ -749,7 +760,7 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod const pendingState = new HotExitState.Pending( createCancelablePromise(token => - this._proxy.$backup(this.resource.toJSON(), this.viewType, token))); + this._proxy.$backup(this._realResource.toJSON(), this.viewType, token))); this._hotExitState = pendingState; try { -- GitLab