提交 ff9fd2fa 编写于 作者: M Matt Bierner

Custom Editors: pass original edit objects back to extensions

For #88719

With this change, instead of passing custom editor edit json back and forth with the extension host, we keep the original edit objects on the extension host. This means that we can pass extensions back the exact same edit object they first hand to us. It also means that edits no longer need to be json serializable.
上级 74cc2f35
...@@ -1181,7 +1181,7 @@ declare module 'vscode' { ...@@ -1181,7 +1181,7 @@ declare module 'vscode' {
* Defines the editing functionality of a webview editor. This allows the webview editor to hook into standard * Defines the editing functionality of a webview editor. This allows the webview editor to hook into standard
* editor events such as `undo` or `save`. * editor events such as `undo` or `save`.
* *
* @param EditType Type of edits. Edit objects must be json serializable. * @param EditType Type of edits.
*/ */
interface WebviewCustomEditorEditingDelegate<EditType> { interface WebviewCustomEditorEditingDelegate<EditType> {
/** /**
......
...@@ -306,6 +306,8 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma ...@@ -306,6 +306,8 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
provider.dispose(); provider.dispose();
this._editorProviders.delete(viewType); this._editorProviders.delete(viewType);
this._customEditorService.models.disposeAllModelsForView(viewType);
} }
private async retainCustomEditorModel(webviewInput: WebviewInput, resource: URI, viewType: string, capabilities: readonly extHostProtocol.WebviewEditorCapabilities[]) { private async retainCustomEditorModel(webviewInput: WebviewInput, resource: URI, viewType: string, capabilities: readonly extHostProtocol.WebviewEditorCapabilities[]) {
...@@ -323,14 +325,17 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma ...@@ -323,14 +325,17 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
const capabilitiesSet = new Set(capabilities); const capabilitiesSet = new Set(capabilities);
const isEditable = capabilitiesSet.has(extHostProtocol.WebviewEditorCapabilities.Editable); const isEditable = capabilitiesSet.has(extHostProtocol.WebviewEditorCapabilities.Editable);
if (isEditable) { if (isEditable) {
model.onUndo(edits => { model.onUndo(e => {
this._proxy.$undoEdits(resource, viewType, edits.map(x => x.data)); this._proxy.$undoEdits(resource, viewType, e.edits);
});
model.onDisposeEdits(e => {
this._proxy.$disposeEdits(e.edits);
}); });
model.onApplyEdit(edits => { model.onApplyEdit(e => {
const editsToApply = edits.filter(x => x.source !== model).map(x => x.data); if (e.trigger !== model) {
if (editsToApply.length) { this._proxy.$applyEdits(resource, viewType, e.edits);
this._proxy.$applyEdits(resource, viewType, editsToApply);
} }
}); });
...@@ -369,13 +374,13 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma ...@@ -369,13 +374,13 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
} }
} }
public $onEdit(resource: UriComponents, viewType: string, editData: any): void { public $onEdit(resource: UriComponents, viewType: string, editId: number): void {
const model = this._customEditorService.models.get(URI.revive(resource), viewType); const model = this._customEditorService.models.get(URI.revive(resource), viewType);
if (!model) { if (!model) {
throw new Error('Could not find model for webview editor'); throw new Error('Could not find model for webview editor');
} }
model.pushEdit({ source: model, data: editData }); model.pushEdit(editId, model);
} }
private hookupWebviewEventDelegate(handle: extHostProtocol.WebviewPanelHandle, input: WebviewInput) { private hookupWebviewEventDelegate(handle: extHostProtocol.WebviewPanelHandle, input: WebviewInput) {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class Cache<T> {
private static readonly enableDebugLogging = false;
private readonly _data = new Map<number, readonly T[]>();
private _idPool = 1;
constructor(
private readonly id: string
) { }
add(item: readonly T[]): number {
const id = this._idPool++;
this._data.set(id, item);
this.logDebugInfo();
return id;
}
get(pid: number, id: number): T | undefined {
return this._data.has(pid) ? this._data.get(pid)![id] : undefined;
}
delete(id: number) {
this._data.delete(id);
this.logDebugInfo();
}
private logDebugInfo() {
if (!Cache.enableDebugLogging) {
return;
}
console.log(`${this.id} cache size — ${this._data.size}`);
}
}
...@@ -584,7 +584,7 @@ export interface MainThreadWebviewsShape extends IDisposable { ...@@ -584,7 +584,7 @@ export interface MainThreadWebviewsShape extends IDisposable {
$registerEditorProvider(extension: WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions, capabilities: readonly WebviewEditorCapabilities[]): void; $registerEditorProvider(extension: WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions, capabilities: readonly WebviewEditorCapabilities[]): void;
$unregisterEditorProvider(viewType: string): void; $unregisterEditorProvider(viewType: string): void;
$onEdit(resource: UriComponents, viewType: string, editJson: any): void; $onEdit(resource: UriComponents, viewType: string, editId: number): void;
} }
export interface WebviewPanelViewStateData { export interface WebviewPanelViewStateData {
...@@ -604,8 +604,9 @@ export interface ExtHostWebviewsShape { ...@@ -604,8 +604,9 @@ export interface ExtHostWebviewsShape {
$deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>; $deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
$resolveWebviewEditor(resource: UriComponents, newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>; $resolveWebviewEditor(resource: UriComponents, newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
$undoEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void; $undoEdits(resource: UriComponents, viewType: string, editIds: readonly number[]): void;
$applyEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void; $applyEdits(resource: UriComponents, viewType: string, editIds: readonly number[]): void;
$disposeEdits(editIds: readonly number[]): void;
$onSave(resource: UriComponents, viewType: string): Promise<void>; $onSave(resource: UriComponents, viewType: string): Promise<void>;
$onSaveAs(resource: UriComponents, viewType: string, targetResource: UriComponents): Promise<void>; $onSaveAs(resource: UriComponents, viewType: string, targetResource: UriComponents): Promise<void>;
......
...@@ -30,6 +30,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; ...@@ -30,6 +30,7 @@ import { VSBuffer } from 'vs/base/common/buffer';
import { encodeSemanticTokensDto } from 'vs/workbench/api/common/shared/semanticTokens'; import { encodeSemanticTokensDto } from 'vs/workbench/api/common/shared/semanticTokens';
import { IdGenerator } from 'vs/base/common/idGenerator'; import { IdGenerator } from 'vs/base/common/idGenerator';
import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService'; import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
import { Cache } from './cache';
// --- adapter // --- adapter
...@@ -1064,40 +1065,6 @@ class SignatureHelpAdapter { ...@@ -1064,40 +1065,6 @@ class SignatureHelpAdapter {
} }
} }
class Cache<T> {
private static readonly enableDebugLogging = false;
private readonly _data = new Map<number, readonly T[]>();
private _idPool = 1;
constructor(
private readonly id: string
) { }
add(item: readonly T[]): number {
const id = this._idPool++;
this._data.set(id, item);
this.logDebugInfo();
return id;
}
get(pid: number, id: number): T | undefined {
return this._data.has(pid) ? this._data.get(pid)![id] : undefined;
}
delete(id: number) {
this._data.delete(id);
this.logDebugInfo();
}
private logDebugInfo() {
if (!Cache.enableDebugLogging) {
return;
}
console.log(`${this.id} cache size — ${this._data.size}`);
}
}
class LinkProviderAdapter { class LinkProviderAdapter {
private _cache = new Cache<vscode.DocumentLink>('DocumentLink'); private _cache = new Cache<vscode.DocumentLink>('DocumentLink');
......
...@@ -15,6 +15,7 @@ import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; ...@@ -15,6 +15,7 @@ import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor'; import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview'; import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import type * as vscode from 'vscode'; import type * as vscode from 'vscode';
import { Cache } from './cache';
import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewEditorCapabilities, WebviewPanelHandle, WebviewPanelViewStateData } from './extHost.protocol'; import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewEditorCapabilities, WebviewPanelHandle, WebviewPanelViewStateData } from './extHost.protocol';
import { Disposable as VSCodeDisposable } from './extHostTypes'; import { Disposable as VSCodeDisposable } from './extHostTypes';
...@@ -251,8 +252,18 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { ...@@ -251,8 +252,18 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
private readonly _proxy: MainThreadWebviewsShape; private readonly _proxy: MainThreadWebviewsShape;
private readonly _webviewPanels = new Map<WebviewPanelHandle, ExtHostWebviewEditor>(); private readonly _webviewPanels = new Map<WebviewPanelHandle, ExtHostWebviewEditor>();
private readonly _serializers = new Map<string, { readonly serializer: vscode.WebviewPanelSerializer, readonly extension: IExtensionDescription }>();
private readonly _editorProviders = new Map<string, { readonly provider: vscode.WebviewCustomEditorProvider, readonly extension: IExtensionDescription }>(); private readonly _serializers = new Map<string, {
readonly serializer: vscode.WebviewPanelSerializer;
readonly extension: IExtensionDescription;
}>();
private readonly _editorProviders = new Map<string, {
readonly provider: vscode.WebviewCustomEditorProvider;
readonly extension: IExtensionDescription;
}>();
private readonly _edits = new Cache<unknown>('edits');
constructor( constructor(
mainContext: IMainContext, mainContext: IMainContext,
...@@ -312,11 +323,14 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { ...@@ -312,11 +323,14 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
if (this._editorProviders.has(viewType)) { if (this._editorProviders.has(viewType)) {
throw new Error(`Editor provider for '${viewType}' already registered`); throw new Error(`Editor provider for '${viewType}' already registered`);
} }
this._editorProviders.set(viewType, { extension, provider, }); this._editorProviders.set(viewType, { extension, provider, });
this._proxy.$registerEditorProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType, options || {}, this.getCapabilites(provider)); this._proxy.$registerEditorProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType, options || {}, this.getCapabilites(provider));
// Hook up events
provider?.editingDelegate?.onEdit(({ edit, resource }) => { provider?.editingDelegate?.onEdit(({ edit, resource }) => {
this._proxy.$onEdit(resource, viewType, edit); const id = this._edits.add([edit]);
this._proxy.$onEdit(resource, viewType, id);
}); });
return new VSCodeDisposable(() => { return new VSCodeDisposable(() => {
...@@ -426,14 +440,32 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { ...@@ -426,14 +440,32 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
await provider.resolveWebviewEditor(revivedResource, revivedPanel); await provider.resolveWebviewEditor(revivedResource, revivedPanel);
} }
$undoEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void { $undoEdits(resourceComponents: UriComponents, viewType: string, editIds: readonly number[]): void {
const provider = this.getEditorProvider(viewType); const provider = this.getEditorProvider(viewType);
provider?.editingDelegate?.undoEdits(URI.revive(resource), edits); if (!provider?.editingDelegate) {
return;
}
const resource = URI.revive(resourceComponents);
const edits = editIds.map(id => this._edits.get(id, 0));
provider.editingDelegate.undoEdits(resource, edits);
} }
$applyEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void { $applyEdits(resourceComponents: UriComponents, viewType: string, editIds: readonly number[]): void {
const provider = this.getEditorProvider(viewType); const provider = this.getEditorProvider(viewType);
provider?.editingDelegate?.applyEdits(URI.revive(resource), edits); if (!provider?.editingDelegate) {
return;
}
const resource = URI.revive(resourceComponents);
const edits = editIds.map(id => this._edits.get(id, 0));
provider.editingDelegate.applyEdits(resource, edits);
}
$disposeEdits(editIds: readonly number[]): void {
for (const edit of editIds) {
this._edits.delete(edit);
}
} }
async $onSave(resource: UriComponents, viewType: string): Promise<void> { async $onSave(resource: UriComponents, viewType: string): Promise<void> {
......
...@@ -42,7 +42,7 @@ export interface ICustomEditorService { ...@@ -42,7 +42,7 @@ export interface ICustomEditorService {
promptOpenWith(resource: URI, options?: ITextEditorOptions, group?: IEditorGroup): Promise<IEditor | undefined>; promptOpenWith(resource: URI, options?: ITextEditorOptions, group?: IEditorGroup): Promise<IEditor | undefined>;
} }
export type CustomEditorEdit = { source?: any, data: any }; export type CustomEditorEdit = number;
export interface ICustomEditorModelManager { export interface ICustomEditorModelManager {
get(resource: URI, viewType: string): ICustomEditorModel | undefined; get(resource: URI, viewType: string): ICustomEditorModel | undefined;
...@@ -50,6 +50,8 @@ export interface ICustomEditorModelManager { ...@@ -50,6 +50,8 @@ export interface ICustomEditorModelManager {
resolve(resource: URI, viewType: string): Promise<ICustomEditorModel>; resolve(resource: URI, viewType: string): Promise<ICustomEditorModel>;
disposeModel(model: ICustomEditorModel): void; disposeModel(model: ICustomEditorModel): void;
disposeAllModelsForView(viewType: string): void;
} }
export interface CustomEditorSaveEvent { export interface CustomEditorSaveEvent {
...@@ -64,13 +66,15 @@ export interface CustomEditorSaveAsEvent { ...@@ -64,13 +66,15 @@ export interface CustomEditorSaveAsEvent {
} }
export interface ICustomEditorModel extends IWorkingCopy { export interface ICustomEditorModel extends IWorkingCopy {
readonly onUndo: Event<readonly CustomEditorEdit[]>; readonly viewType: string;
readonly onApplyEdit: Event<readonly CustomEditorEdit[]>;
readonly onUndo: Event<{ edits: readonly CustomEditorEdit[], trigger: any | undefined }>;
readonly onApplyEdit: Event<{ edits: readonly CustomEditorEdit[], trigger: any | undefined }>;
readonly onDisposeEdits: Event<{ edits: readonly CustomEditorEdit[] }>;
readonly onWillSave: Event<CustomEditorSaveEvent>; readonly onWillSave: Event<CustomEditorSaveEvent>;
readonly onWillSaveAs: Event<CustomEditorSaveAsEvent>; readonly onWillSaveAs: Event<CustomEditorSaveAsEvent>;
readonly currentEdits: readonly CustomEditorEdit[];
undo(): void; undo(): void;
redo(): void; redo(): void;
revert(options?: IRevertOptions): Promise<boolean>; revert(options?: IRevertOptions): Promise<boolean>;
...@@ -78,7 +82,7 @@ export interface ICustomEditorModel extends IWorkingCopy { ...@@ -78,7 +82,7 @@ export interface ICustomEditorModel extends IWorkingCopy {
save(options?: ISaveOptions): Promise<boolean>; save(options?: ISaveOptions): Promise<boolean>;
saveAs(resource: URI, targetResource: URI, currentOptions?: ISaveOptions): Promise<boolean>; saveAs(resource: URI, targetResource: URI, currentOptions?: ISaveOptions): Promise<boolean>;
pushEdit(edit: CustomEditorEdit): void; pushEdit(edit: CustomEditorEdit, trigger: any): void;
} }
export const enum CustomEditorPriority { export const enum CustomEditorPriority {
......
...@@ -14,14 +14,20 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel ...@@ -14,14 +14,20 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel
private _currentEditIndex: number = -1; private _currentEditIndex: number = -1;
private _savePoint: number = -1; private _savePoint: number = -1;
private _edits: Array<any> = []; private readonly _edits: Array<CustomEditorEdit> = [];
constructor( constructor(
public readonly viewType: string,
private readonly _resource: URI, private readonly _resource: URI,
) { ) {
super(); super();
} }
dispose() {
this._onDisposeEdits.fire({ edits: this._edits });
super.dispose();
}
//#region IWorkingCopy //#region IWorkingCopy
public get resource() { public get resource() {
...@@ -44,30 +50,43 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel ...@@ -44,30 +50,43 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel
//#endregion //#endregion
protected readonly _onUndo = this._register(new Emitter<readonly CustomEditorEdit[]>()); protected readonly _onUndo = this._register(new Emitter<{ edits: readonly CustomEditorEdit[], trigger: any | undefined }>());
readonly onUndo = this._onUndo.event; readonly onUndo = this._onUndo.event;
protected readonly _onApplyEdit = this._register(new Emitter<readonly CustomEditorEdit[]>()); protected readonly _onApplyEdit = this._register(new Emitter<{ edits: readonly CustomEditorEdit[], trigger: any | undefined }>());
readonly onApplyEdit = this._onApplyEdit.event; readonly onApplyEdit = this._onApplyEdit.event;
protected readonly _onDisposeEdits = this._register(new Emitter<{ edits: readonly CustomEditorEdit[] }>());
readonly onDisposeEdits = this._onDisposeEdits.event;
protected readonly _onWillSave = this._register(new Emitter<CustomEditorSaveEvent>()); protected readonly _onWillSave = this._register(new Emitter<CustomEditorSaveEvent>());
readonly onWillSave = this._onWillSave.event; readonly onWillSave = this._onWillSave.event;
protected readonly _onWillSaveAs = this._register(new Emitter<CustomEditorSaveAsEvent>()); protected readonly _onWillSaveAs = this._register(new Emitter<CustomEditorSaveAsEvent>());
readonly onWillSaveAs = this._onWillSaveAs.event; readonly onWillSaveAs = this._onWillSaveAs.event;
get currentEdits(): readonly CustomEditorEdit[] { public pushEdit(edit: CustomEditorEdit, trigger: any): void {
return this._edits.slice(0, Math.max(0, this._currentEditIndex + 1)); this.spliceEdits(edit);
}
public pushEdit(edit: CustomEditorEdit): void {
this._edits.splice(this._currentEditIndex + 1, this._edits.length - this._currentEditIndex, edit.data);
this._currentEditIndex = this._edits.length - 1; this._currentEditIndex = this._edits.length - 1;
this.updateDirty(); this.updateDirty();
this._onApplyEdit.fire([edit]); this._onApplyEdit.fire({ edits: [edit], trigger });
this.updateContentChanged(); this.updateContentChanged();
} }
private spliceEdits(editToInsert?: CustomEditorEdit) {
const start = this._currentEditIndex + 1;
const toRemove = this._edits.length - this._currentEditIndex;
const removedEdits = editToInsert
? this._edits.splice(start, toRemove, editToInsert)
: this._edits.splice(start, toRemove);
if (removedEdits.length) {
this._onDisposeEdits.fire({ edits: removedEdits });
}
}
private updateDirty() { private updateDirty() {
// TODO@matt this should to be more fine grained and avoid // TODO@matt this should to be more fine grained and avoid
// emitting events if there was no change actually // emitting events if there was no change actually
...@@ -128,14 +147,15 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel ...@@ -128,14 +147,15 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel
if (this._currentEditIndex >= this._savePoint) { if (this._currentEditIndex >= this._savePoint) {
const editsToUndo = this._edits.slice(this._savePoint, this._currentEditIndex); const editsToUndo = this._edits.slice(this._savePoint, this._currentEditIndex);
this._onUndo.fire(editsToUndo.reverse()); this._onUndo.fire({ edits: editsToUndo.reverse(), trigger: undefined });
} else if (this._currentEditIndex < this._savePoint) { } else if (this._currentEditIndex < this._savePoint) {
const editsToRedo = this._edits.slice(this._currentEditIndex, this._savePoint); const editsToRedo = this._edits.slice(this._currentEditIndex, this._savePoint);
this._onApplyEdit.fire(editsToRedo); this._onApplyEdit.fire({ edits: editsToRedo, trigger: undefined });
} }
this._currentEditIndex = this._savePoint; this._currentEditIndex = this._savePoint;
this._edits.splice(this._currentEditIndex + 1, this._edits.length - this._currentEditIndex); this.spliceEdits();
this.updateDirty(); this.updateDirty();
this.updateContentChanged(); this.updateContentChanged();
return true; return true;
...@@ -149,7 +169,7 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel ...@@ -149,7 +169,7 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel
const undoneEdit = this._edits[this._currentEditIndex]; const undoneEdit = this._edits[this._currentEditIndex];
--this._currentEditIndex; --this._currentEditIndex;
this._onUndo.fire([{ data: undoneEdit }]); this._onUndo.fire({ edits: [undoneEdit], trigger: undefined });
this.updateDirty(); this.updateDirty();
this.updateContentChanged(); this.updateContentChanged();
...@@ -164,7 +184,7 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel ...@@ -164,7 +184,7 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel
++this._currentEditIndex; ++this._currentEditIndex;
const redoneEdit = this._edits[this._currentEditIndex]; const redoneEdit = this._edits[this._currentEditIndex];
this._onApplyEdit.fire([{ data: redoneEdit }]); this._onApplyEdit.fire({ edits: [redoneEdit], trigger: undefined });
this.updateDirty(); this.updateDirty();
this.updateContentChanged(); this.updateContentChanged();
......
...@@ -27,7 +27,7 @@ export class CustomEditorModelManager implements ICustomEditorModelManager { ...@@ -27,7 +27,7 @@ export class CustomEditorModelManager implements ICustomEditorModelManager {
return existing; return existing;
} }
const model = new CustomEditorModel(resource); const model = new CustomEditorModel(viewType, resource);
const disposables = new DisposableStore(); const disposables = new DisposableStore();
disposables.add(this._workingCopyService.registerWorkingCopy(model)); disposables.add(this._workingCopyService.registerWorkingCopy(model));
this._models.set(this.key(resource, viewType), { model, disposables }); this._models.set(this.key(resource, viewType), { model, disposables });
...@@ -39,6 +39,7 @@ export class CustomEditorModelManager implements ICustomEditorModelManager { ...@@ -39,6 +39,7 @@ export class CustomEditorModelManager implements ICustomEditorModelManager {
this._models.forEach((value, key) => { this._models.forEach((value, key) => {
if (model === value.model) { if (model === value.model) {
value.disposables.dispose(); value.disposables.dispose();
value.model.dispose();
foundKey = key; foundKey = key;
} }
}); });
...@@ -48,6 +49,14 @@ export class CustomEditorModelManager implements ICustomEditorModelManager { ...@@ -48,6 +49,14 @@ export class CustomEditorModelManager implements ICustomEditorModelManager {
return; return;
} }
public disposeAllModelsForView(viewType: string): void {
this._models.forEach((value) => {
if (value.model.viewType === viewType) {
this.disposeModel(value.model);
}
});
}
private key(resource: URI, viewType: string): string { private key(resource: URI, viewType: string): string {
return `${resource.toString()}@@@${viewType}`; return `${resource.toString()}@@@${viewType}`;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册