Skip to content

Commit 44f6625

Browse files
author
Benjamin Pasero
committed
Change -> Undo no longer marks document non-dirty (fix microsoft#90973)
1 parent 7779310 commit 44f6625

3 files changed

Lines changed: 68 additions & 54 deletions

File tree

src/vs/workbench/services/textfile/common/textFileEditorModel.ts

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,13 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
249249
//#region Load
250250

251251
async load(options?: ITextFileLoadOptions): Promise<TextFileEditorModel> {
252-
this.logService.trace('[text file model] load() - enter', this.resource.toString());
252+
this.logService.trace('[text file model] load() - enter', this.resource.toString(true));
253253

254254
// It is very important to not reload the model when the model is dirty.
255255
// We also only want to reload the model from the disk if no save is pending
256256
// to avoid data loss.
257257
if (this.dirty || this.saveSequentializer.hasPending()) {
258-
this.logService.trace('[text file model] load() - exit - without loading because model is dirty or being saved', this.resource.toString());
258+
this.logService.trace('[text file model] load() - exit - without loading because model is dirty or being saved', this.resource.toString(true));
259259

260260
return this;
261261
}
@@ -359,7 +359,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
359359
}
360360

361361
private loadFromContent(content: ITextFileStreamContent, options?: ITextFileLoadOptions, fromBackup?: boolean): TextFileEditorModel {
362-
this.logService.trace('[text file model] load() - resolved content', this.resource.toString());
362+
this.logService.trace('[text file model] load() - resolved content', this.resource.toString(true));
363363

364364
// Update our resolved disk stat model
365365
this.updateLastResolvedFileStat({
@@ -395,14 +395,17 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
395395
this.doCreateTextModel(content.resource, content.value, !!fromBackup);
396396
}
397397

398+
// Ensure we track the latest saved version ID
399+
this.updateSavedVersionId();
400+
398401
// Emit as event
399402
this._onDidLoad.fire(options?.reason ?? TextFileLoadReason.OTHER);
400403

401404
return this;
402405
}
403406

404407
private doCreateTextModel(resource: URI, value: ITextBufferFactory, fromBackup: boolean): void {
405-
this.logService.trace('[text file model] load() - created text editor model', this.resource.toString());
408+
this.logService.trace('[text file model] load() - created text editor model', this.resource.toString(true));
406409

407410
// Create model
408411
const textModel = this.createTextEditorModel(value, resource, this.preferredMode);
@@ -417,7 +420,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
417420
}
418421

419422
private doUpdateTextModel(value: ITextBufferFactory): void {
420-
this.logService.trace('[text file model] load() - updated text editor model', this.resource.toString());
423+
this.logService.trace('[text file model] load() - updated text editor model', this.resource.toString(true));
421424

422425
// Update model value in a block that ignores content change events for dirty tracking
423426
this.ignoreDirtyOnModelContentChange = true;
@@ -426,9 +429,6 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
426429
} finally {
427430
this.ignoreDirtyOnModelContentChange = false;
428431
}
429-
430-
// Ensure we track the latest saved version ID given that the contents changed
431-
this.updateSavedVersionId();
432432
}
433433

434434
private installModelListeners(model: ITextModel): void {
@@ -442,11 +442,11 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
442442
}
443443

444444
private onModelContentChanged(model: ITextModel): void {
445-
this.logService.trace(`[text file model] onModelContentChanged() - enter`, this.resource.toString());
445+
this.logService.trace(`[text file model] onModelContentChanged() - enter`, this.resource.toString(true));
446446

447447
// In any case increment the version id because it tracks the textual content state of the model at all times
448448
this.versionId++;
449-
this.logService.trace(`[text file model] onModelContentChanged() - new versionId ${this.versionId}`, this.resource.toString());
449+
this.logService.trace(`[text file model] onModelContentChanged() - new versionId ${this.versionId}`, this.resource.toString(true));
450450

451451
// We mark check for a dirty-state change upon model content change, unless:
452452
// - explicitly instructed to ignore it (e.g. from model.load())
@@ -456,7 +456,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
456456
// The contents changed as a matter of Undo and the version reached matches the saved one
457457
// In this case we clear the dirty flag and emit a SAVED event to indicate this state.
458458
if (model.getAlternativeVersionId() === this.bufferSavedVersionId) {
459-
this.logService.trace('[text file model] onModelContentChanged() - model content changed back to last saved version', this.resource.toString());
459+
this.logService.trace('[text file model] onModelContentChanged() - model content changed back to last saved version', this.resource.toString(true));
460460

461461
// Clear flags
462462
const wasDirty = this.dirty;
@@ -470,7 +470,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
470470

471471
// Otherwise the content has changed and we signal this as becoming dirty
472472
else {
473-
this.logService.trace('[text file model] onModelContentChanged() - model content changed and marked as dirty', this.resource.toString());
473+
this.logService.trace('[text file model] onModelContentChanged() - model content changed and marked as dirty', this.resource.toString(true));
474474

475475
// Mark as dirty
476476
this.setDirty(true);
@@ -538,7 +538,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
538538
}
539539

540540
if (this.isReadonly()) {
541-
this.logService.trace('[text file model] save() - ignoring request for readonly resource', this.resource.toString());
541+
this.logService.trace('[text file model] save() - ignoring request for readonly resource', this.resource.toString(true));
542542

543543
return false; // if model is readonly we do not attempt to save at all
544544
}
@@ -547,15 +547,15 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
547547
(this.hasState(TextFileEditorModelState.CONFLICT) || this.hasState(TextFileEditorModelState.ERROR)) &&
548548
(options.reason === SaveReason.AUTO || options.reason === SaveReason.FOCUS_CHANGE || options.reason === SaveReason.WINDOW_CHANGE)
549549
) {
550-
this.logService.trace('[text file model] save() - ignoring auto save request for model that is in conflict or error', this.resource.toString());
550+
this.logService.trace('[text file model] save() - ignoring auto save request for model that is in conflict or error', this.resource.toString(true));
551551

552552
return false; // if model is in save conflict or error, do not save unless save reason is explicit
553553
}
554554

555555
// Actually do save and log
556-
this.logService.trace('[text file model] save() - enter', this.resource.toString());
556+
this.logService.trace('[text file model] save() - enter', this.resource.toString(true));
557557
await this.doSave(options);
558-
this.logService.trace('[text file model] save() - exit', this.resource.toString());
558+
this.logService.trace('[text file model] save() - exit', this.resource.toString(true));
559559

560560
return true;
561561
}
@@ -566,15 +566,15 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
566566
}
567567

568568
let versionId = this.versionId;
569-
this.logService.trace(`[text file model] doSave(${versionId}) - enter with versionId ${versionId}`, this.resource.toString());
569+
this.logService.trace(`[text file model] doSave(${versionId}) - enter with versionId ${versionId}`, this.resource.toString(true));
570570

571571
// Lookup any running pending save for this versionId and return it if found
572572
//
573573
// Scenario: user invoked the save action multiple times quickly for the same contents
574574
// while the save was not yet finished to disk
575575
//
576576
if (this.saveSequentializer.hasPending(versionId)) {
577-
this.logService.trace(`[text file model] doSave(${versionId}) - exit - found a pending save for versionId ${versionId}`, this.resource.toString());
577+
this.logService.trace(`[text file model] doSave(${versionId}) - exit - found a pending save for versionId ${versionId}`, this.resource.toString(true));
578578

579579
return this.saveSequentializer.pending;
580580
}
@@ -583,7 +583,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
583583
//
584584
// Scenario: user invoked save action even though the model is not dirty
585585
if (!options.force && !this.dirty) {
586-
this.logService.trace(`[text file model] doSave(${versionId}) - exit - because not dirty and/or versionId is different (this.isDirty: ${this.dirty}, this.versionId: ${this.versionId})`, this.resource.toString());
586+
this.logService.trace(`[text file model] doSave(${versionId}) - exit - because not dirty and/or versionId is different (this.isDirty: ${this.dirty}, this.versionId: ${this.versionId})`, this.resource.toString(true));
587587

588588
return;
589589
}
@@ -597,7 +597,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
597597
// while the first save has not returned yet.
598598
//
599599
if (this.saveSequentializer.hasPending()) {
600-
this.logService.trace(`[text file model] doSave(${versionId}) - exit - because busy saving`, this.resource.toString());
600+
this.logService.trace(`[text file model] doSave(${versionId}) - exit - because busy saving`, this.resource.toString(true));
601601

602602
// Indicate to the save sequentializer that we want to
603603
// cancel the pending operation so that ours can run
@@ -629,7 +629,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
629629
try {
630630
await this.textFileService.files.runSaveParticipants(this, { reason: options.reason ?? SaveReason.EXPLICIT }, saveCancellation.token);
631631
} catch (error) {
632-
this.logService.error(`[text file model] runSaveParticipants(${versionId}) - resulted in an error: ${error.toString()}`, this.resource.toString());
632+
this.logService.error(`[text file model] runSaveParticipants(${versionId}) - resulted in an error: ${error.toString()}`, this.resource.toString(true));
633633
}
634634
}
635635

@@ -680,7 +680,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
680680
// Save to Disk. We mark the save operation as currently pending with
681681
// the latest versionId because it might have changed from a save
682682
// participant triggering
683-
this.logService.trace(`[text file model] doSave(${versionId}) - before write()`, this.resource.toString());
683+
this.logService.trace(`[text file model] doSave(${versionId}) - before write()`, this.resource.toString(true));
684684
const lastResolvedFileStat = assertIsDefined(this.lastResolvedFileStat);
685685
const textFileEdiorModel = this;
686686
return this.saveSequentializer.setPending(versionId, (async () => {
@@ -703,25 +703,25 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
703703
}
704704

705705
private handleSaveSuccess(stat: IFileStatWithMetadata, versionId: number, options: ITextFileSaveOptions): void {
706-
this.logService.trace(`[text file model] doSave(${versionId}) - after write()`, this.resource.toString());
706+
this.logService.trace(`[text file model] doSave(${versionId}) - after write()`, this.resource.toString(true));
707707

708708
// Updated resolved stat with updated stat
709709
this.updateLastResolvedFileStat(stat);
710710

711711
// Update dirty state unless model has changed meanwhile
712712
if (versionId === this.versionId) {
713-
this.logService.trace(`[text file model] handleSaveSuccess(${versionId}) - setting dirty to false because versionId did not change`, this.resource.toString());
713+
this.logService.trace(`[text file model] handleSaveSuccess(${versionId}) - setting dirty to false because versionId did not change`, this.resource.toString(true));
714714
this.setDirty(false);
715715
} else {
716-
this.logService.trace(`[text file model] handleSaveSuccess(${versionId}) - not setting dirty to false because versionId did change meanwhile`, this.resource.toString());
716+
this.logService.trace(`[text file model] handleSaveSuccess(${versionId}) - not setting dirty to false because versionId did change meanwhile`, this.resource.toString(true));
717717
}
718718

719719
// Emit Save Event
720720
this._onDidSave.fire(options.reason ?? SaveReason.EXPLICIT);
721721
}
722722

723723
private handleSaveError(error: Error, versionId: number, options: ITextFileSaveOptions): void {
724-
this.logService.error(`[text file model] handleSaveError(${versionId}) - exit - resulted in a save error: ${error.toString()}`, this.resource.toString());
724+
this.logService.error(`[text file model] handleSaveError(${versionId}) - exit - resulted in a save error: ${error.toString()}`, this.resource.toString(true));
725725

726726
// Return early if the save() call was made asking to
727727
// handle the save error itself.

0 commit comments

Comments
 (0)