diff --git a/src/vs/workbench/api/browser/mainThreadNotebook.ts b/src/vs/workbench/api/browser/mainThreadNotebook.ts index f88f0d1ec0d..9b87422a5fe 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebook.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebook.ts @@ -282,6 +282,13 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo return; } + async $onNotebookChange(viewType: string, uri: UriComponents): Promise { + let controller = this._notebookProviders.get(viewType); + if (controller) { + controller.handleNotebookChange(uri); + } + } + async $unregisterNotebookProvider(viewType: string): Promise { this._notebookProviders.delete(viewType); this._notebookService.unregisterNotebookProvider(viewType); @@ -503,6 +510,11 @@ export class MainThreadNotebookController implements IMainNotebookController { // Methods for ExtHost + handleNotebookChange(resource: UriComponents) { + let document = this._mapping.get(URI.from(resource).toString()); + document?.textModel.handleUnknownChange(); + } + updateLanguages(resource: UriComponents, languages: string[]) { let document = this._mapping.get(URI.from(resource).toString()); document?.textModel.updateLanguages(languages); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 2b950183241..ce8e267e10c 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -698,6 +698,7 @@ export type NotebookCellOutputsSplice = [ export interface MainThreadNotebookShape extends IDisposable { $registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string, kernelInfoDto: INotebookKernelInfoDto | undefined): Promise; + $onNotebookChange(viewType: string, resource: UriComponents): Promise; $unregisterNotebookProvider(viewType: string): Promise; $registerNotebookRenderer(extension: NotebookExtensionDescription, type: string, selectors: INotebookMimeTypeSelector, preloads: UriComponents[]): Promise; $unregisterNotebookRenderer(id: string): Promise; diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index 0505b2de4c8..61b31818789 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -815,8 +815,14 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN // } this._notebookContentProviders.set(viewType, { extension, provider }); + + const listener = provider.onDidChangeNotebook(e => { + this._proxy.$onNotebookChange(viewType, e.document.uri); + }); + this._proxy.$registerNotebookProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType, provider.kernel ? { id: viewType, label: provider.kernel.label, extensionLocation: extension.extensionLocation, preloads: provider.kernel.preloads } : undefined); return new extHostTypes.Disposable(() => { + listener.dispose(); this._notebookContentProviders.delete(viewType); this._proxy.$unregisterNotebookProvider(viewType); }); diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts index 9232209ce59..305d80a87bd 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookTextModel.ts @@ -78,6 +78,8 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel onDidChangeContent: Event = this._onDidChangeContent.event; private _onDidChangeMetadata = new Emitter(); onDidChangeMetadata: Event = this._onDidChangeMetadata.event; + private readonly _onDidChangeUnknown = new Emitter(); + readonly onDidChangeUnknown: Event = this._onDidChangeUnknown.event; private _mapping: Map = new Map(); private _cellListeners: Map = new Map(); cells: NotebookCellTextModel[]; @@ -222,6 +224,10 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel this._versionId = this._versionId + 1; } + handleUnknownChange() { + this._onDidChangeUnknown.fire(); + } + updateLanguages(languages: string[]) { this.languages = languages; diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 9b53e3870ce..7dce654a3f2 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -258,6 +258,7 @@ export interface INotebookTextModel { renderers: Set; onDidChangeCells?: Event; onDidChangeContent: Event; + onDidChangeUnknown: Event; onWillDispose(listener: () => void): IDisposable; } @@ -560,4 +561,3 @@ export interface IEditor extends editorCommon.ICompositeCodeEditor { hasFocus(): boolean; hasModel(): boolean; } - diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts index a6784c58295..c9f0781e22f 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts @@ -138,6 +138,9 @@ export class NotebookEditorModel extends EditorModel implements IWorkingCopy, IN this.setDirty(true); this._onDidChangeContent.fire(); })); + this._register(this._notebook.onDidChangeUnknown(() => { + this.setDirty(true); + })); await this.backupFileService.discardBackup(this._workingCopyResource); this.setDirty(true); @@ -155,6 +158,9 @@ export class NotebookEditorModel extends EditorModel implements IWorkingCopy, IN this.setDirty(true); this._onDidChangeContent.fire(); })); + this._register(this._notebook.onDidChangeUnknown(() => { + this.setDirty(true); + })); return this; }