From 49e08513a12f0b5c6d708de41a1f06ab49897c1e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 May 2020 07:58:09 +0200 Subject: [PATCH] files - do not open dirty models that are being auto saved (#96920) --- .../browser/editors/textFileEditorTracker.ts | 8 +++- .../browser/textFileEditorTracker.test.ts | 44 ++++++++++++++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts b/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts index 9d6d291ea17..415393da1ef 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts @@ -13,6 +13,7 @@ import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { RunOnceWorker } from 'vs/base/common/async'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; export class TextFileEditorTracker extends Disposable implements IWorkbenchContribution { @@ -21,7 +22,8 @@ export class TextFileEditorTracker extends Disposable implements IWorkbenchContr @ITextFileService private readonly textFileService: ITextFileService, @ILifecycleService private readonly lifecycleService: ILifecycleService, @IHostService private readonly hostService: IHostService, - @ICodeEditorService private readonly codeEditorService: ICodeEditorService + @ICodeEditorService private readonly codeEditorService: ICodeEditorService, + @IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService ) { super(); @@ -57,6 +59,10 @@ export class TextFileEditorTracker extends Disposable implements IWorkbenchContr return false; // resource must not be pending to save } + if (this.filesConfigurationService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { + return false; // resource must not be pending to be auto saved + } + if (this.editorService.isOpen({ resource })) { return false; // model must not be opened already as file } diff --git a/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts b/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts index f50a26af1a9..7f8da4afd56 100644 --- a/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/textFileEditorTracker.test.ts @@ -8,7 +8,7 @@ import { Event } from 'vs/base/common/event'; import { TextFileEditorTracker } from 'vs/workbench/contrib/files/browser/editors/textFileEditorTracker'; import { toResource } from 'vs/base/test/common/utils'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { workbenchInstantiationService, TestServiceAccessor } from 'vs/workbench/test/browser/workbenchTestServices'; +import { workbenchInstantiationService, TestServiceAccessor, TestFilesConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices'; import { IResolvedTextFileEditorModel, snapshotToString, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { FileChangesEvent, FileChangeType } from 'vs/platform/files/common/files'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -27,6 +27,11 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput'; import { isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; suite('Files - TextFileEditorTracker', () => { @@ -48,9 +53,21 @@ suite('Files - TextFileEditorTracker', () => { disposables = []; }); - async function createTracker(): Promise<[EditorPart, TestServiceAccessor, TextFileEditorTracker, IInstantiationService, IEditorService]> { + async function createTracker(autoSaveEnabled = false): Promise<[EditorPart, TestServiceAccessor, TextFileEditorTracker, IInstantiationService, IEditorService]> { const instantiationService = workbenchInstantiationService(); + if (autoSaveEnabled) { + const configurationService = new TestConfigurationService(); + configurationService.setUserConfiguration('files', { autoSave: 'afterDelay', autoSaveDelay: 1 }); + + instantiationService.stub(IConfigurationService, configurationService); + + instantiationService.stub(IFilesConfigurationService, new TestFilesConfigurationService( + instantiationService.createInstance(MockContextKeyService), + configurationService + )); + } + const part = instantiationService.createInstance(EditorPart); part.create(document.createElement('div')); part.layout(400, 300); @@ -93,23 +110,38 @@ suite('Files - TextFileEditorTracker', () => { }); test('dirty text file model opens as editor', async function () { - const [part, accessor, tracker] = await createTracker(); + const resource = toResource.call(this, '/path/index.txt'); + + await testDirtyTextFileModelOpensEditorDependingOnAutoSaveSetting(resource, false); + }); + test('dirty text file model does not open as editor if autosave is ON', async function () { const resource = toResource.call(this, '/path/index.txt'); + await testDirtyTextFileModelOpensEditorDependingOnAutoSaveSetting(resource, true); + }); + + async function testDirtyTextFileModelOpensEditorDependingOnAutoSaveSetting(resource: URI, autoSave: boolean): Promise { + const [part, accessor, tracker] = await createTracker(autoSave); + assert.ok(!accessor.editorService.isOpen(accessor.editorService.createEditorInput({ resource, forceFile: true }))); const model = await accessor.textFileService.files.resolve(resource) as IResolvedTextFileEditorModel; model.textEditorModel.setValue('Super Good'); - await awaitEditorOpening(accessor.editorService); - assert.ok(accessor.editorService.isOpen(accessor.editorService.createEditorInput({ resource, forceFile: true }))); + if (autoSave) { + await timeout(100); + assert.ok(!accessor.editorService.isOpen(accessor.editorService.createEditorInput({ resource, forceFile: true }))); + } else { + await awaitEditorOpening(accessor.editorService); + assert.ok(accessor.editorService.isOpen(accessor.editorService.createEditorInput({ resource, forceFile: true }))); + } part.dispose(); tracker.dispose(); (accessor.textFileService.files).dispose(); - }); + } test('dirty untitled text file model opens as editor', async function () { const [part, accessor, tracker, , editorService] = await createTracker(); -- GitLab