add notebookEditorModelResolverService.isDirty and use that when forwarding events

This commit is contained in:
Johannes Rieken
2021-03-31 12:06:03 +02:00
parent 6b5f2532d9
commit dd360b25da
3 changed files with 27 additions and 14 deletions
@@ -260,7 +260,7 @@ export class MainThreadNotebooks implements MainThreadNotebookShape {
return;
}
const disposableStore = new DisposableStore();
disposableStore.add(textModel!.onDidChangeContent(event => {
disposableStore.add(textModel.onDidChangeContent(event => {
const dto = event.rawEvents.map(e => {
const data =
e.kind === NotebookCellsChangeType.ModelChange || e.kind === NotebookCellsChangeType.Initialize
@@ -285,18 +285,14 @@ export class MainThreadNotebooks implements MainThreadNotebookShape {
return data;
});
/**
* TODO@rebornix, @jrieken
* When a document is modified, it will trigger onDidChangeContent events.
* The first event listener is this one, which doesn't know if the text model is dirty or not. It can ask `workingCopyService` but get the wrong result
* The second event listener is `NotebookEditorModel`, which will then set `isDirty` to `true`.
* Since `e.transient` decides if the model should be dirty or not, we will use the same logic here.
*/
const hasNonTransientEvent = event.rawEvents.find(e => !e.transient);
this._proxy.$acceptModelChanged(textModel.uri, {
rawEvents: dto,
versionId: event.versionId
}, !!hasNonTransientEvent);
// using the model resolver service to know if the model is dirty or not.
// assuming this is the first listener it can mean that at first the model
// is marked as dirty and that another event is fired
this._proxy.$acceptModelChanged(
textModel.uri,
{ rawEvents: dto, versionId: event.versionId },
this._notebookEditorModelResolverService.isDirty(textModel.uri)
);
const hasDocumentMetadataChangeEvent = event.rawEvents.find(e => e.kind === NotebookCellsChangeType.ChangeDocumentMetadata);
if (!!hasDocumentMetadataChangeEvent) {
@@ -17,5 +17,7 @@ export interface INotebookEditorModelResolverService {
readonly onDidSaveNotebook: Event<URI>;
readonly onDidChangeDirty: Event<{ resource: URI, isDirty: boolean }>;
isDirty(resource: URI): boolean;
resolve(resource: URI, viewType?: string): Promise<IReference<IResolvedNotebookEditorModel>>;
}
@@ -15,6 +15,7 @@ import { FileWorkingCopyManager, IFileWorkingCopyManager } from 'vs/workbench/se
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
import { ResourceMap } from 'vs/base/common/map';
class NotebookModelReferenceCollection extends ReferenceCollection<Promise<IResolvedNotebookEditorModel>> {
@@ -28,6 +29,8 @@ class NotebookModelReferenceCollection extends ReferenceCollection<Promise<IReso
private readonly _onDidChangeDirty = new Emitter<{ resource: URI, isDirty: boolean }>();
readonly onDidChangeDirty: Event<{ resource: URI, isDirty: boolean }> = this._onDidChangeDirty.event;
private readonly _dirtyStates = new ResourceMap<boolean>();
constructor(
@IInstantiationService readonly _instantiationService: IInstantiationService,
@INotebookService private readonly _notebookService: INotebookService,
@@ -48,6 +51,10 @@ class NotebookModelReferenceCollection extends ReferenceCollection<Promise<IReso
this._workingCopyManager.dispose();
}
isDirty(resource: URI): boolean {
return this._dirtyStates.get(resource) ?? false;
}
protected async createReferencedObject(key: string, viewType: string): Promise<IResolvedNotebookEditorModel> {
const uri = URI.parse(key);
const info = await this._notebookService.withNotebookDataProvider(uri, viewType);
@@ -68,7 +75,11 @@ class NotebookModelReferenceCollection extends ReferenceCollection<Promise<IReso
this._modelListener.set(result, combinedDisposable(
result.onDidSave(() => this._onDidSaveNotebook.fire(result.resource)),
result.onDidChangeDirty(() => this._onDidChangeDirty.fire({ resource: result.resource, isDirty: result.isDirty() })),
result.onDidChangeDirty(() => {
const isDirty = result.isDirty();
this._dirtyStates.set(result.resource, isDirty);
this._onDidChangeDirty.fire({ resource: result.resource, isDirty });
}),
));
return result;
}
@@ -108,6 +119,10 @@ export class NotebookModelResolverServiceImpl implements INotebookEditorModelRes
this._data.dispose();
}
isDirty(resource: URI): boolean {
return this._data.isDirty(resource);
}
async resolve(resource: URI, viewType?: string): Promise<IReference<IResolvedNotebookEditorModel>> {
if (resource.scheme === CellUri.scheme) {