diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index 01609c631f67..e62c07154f43 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -412,12 +412,18 @@ export enum FileOperationResult { FILE_TOO_LARGE } +export const AutoSaveModes = { + OFF: 'off', + AFTER_DELAY: 'afterDelay', + ON_FOCUS_CHANGE: 'onFocusChange' +} + export interface IFilesConfiguration { files: { exclude: glob.IExpression; encoding: string; trimTrailingWhitespace: boolean; + autoSave: string; autoSaveDelay: number; - autoSaveFocusChange: boolean; }; } \ No newline at end of file diff --git a/src/vs/workbench/electron-browser/integration.ts b/src/vs/workbench/electron-browser/integration.ts index 3a1fad0d7e23..ddc948a3f9ba 100644 --- a/src/vs/workbench/electron-browser/integration.ts +++ b/src/vs/workbench/electron-browser/integration.ts @@ -128,7 +128,7 @@ export class ElectronIntegration { ipc.on('vscode:showAutoSaveInfo', () => { this.messageService.show( Severity.Info, { - message: nls.localize('autoSaveInfo', "The **File | Auto Save** option moved into settings and **files.autoSaveDelay: 1** will be added to preserve it."), + message: nls.localize('autoSaveInfo', "The **File | Auto Save** option moved into settings and **files.autoSave: \"afterDelay\"** will be added to preserve it."), actions: [ CloseAction, this.instantiationService.createInstance(OpenGlobalSettingsAction, OpenGlobalSettingsAction.ID, OpenGlobalSettingsAction.LABEL) @@ -139,7 +139,7 @@ export class ElectronIntegration { ipc.on('vscode:showAutoSaveError', () => { this.messageService.show( Severity.Warning, { - message: nls.localize('autoSaveError', "Unable to write to settings. Please add **files.autoSaveDelay: 1** to settings.json."), + message: nls.localize('autoSaveError', "Unable to write to settings. Please add **files.autoSave: \"afterDelay\"** to settings.json."), actions: [ CloseAction, this.instantiationService.createInstance(OpenGlobalSettingsAction, OpenGlobalSettingsAction.ID, OpenGlobalSettingsAction.LABEL) diff --git a/src/vs/workbench/electron-main/windows.ts b/src/vs/workbench/electron-main/windows.ts index 626e61a999b7..e8f5c8523d29 100644 --- a/src/vs/workbench/electron-main/windows.ts +++ b/src/vs/workbench/electron-main/windows.ts @@ -344,7 +344,7 @@ export class WindowsManager { // Initial settings file if (!fs.existsSync(env.appSettingsPath)) { - fs.writeFileSync(env.appSettingsPath, JSON.stringify({ 'files.autoSaveDelay': 1 }, null, ' ')); + fs.writeFileSync(env.appSettingsPath, JSON.stringify({ 'files.autoSave': 'afterDelay' }, null, ' ')); } // Update existing settings file @@ -356,7 +356,7 @@ export class WindowsManager { // We found a closing '}' and the JSON does not contain errors if (lastClosing > 0 && !errors.length) { - const migratedSettings = settingsRaw.substring(0, lastClosing) + '\n , // Migrated from previous File | Auto Save setting:\n "files.autoSaveDelay": 1\n}'; + const migratedSettings = settingsRaw.substring(0, lastClosing) + '\n , // Migrated from previous "File | Auto Save" setting:\n "files.autoSave": "afterDelay"\n}'; fs.writeFileSync(env.appSettingsPath, migratedSettings); } diff --git a/src/vs/workbench/parts/files/browser/files.contribution.ts b/src/vs/workbench/parts/files/browser/files.contribution.ts index a3c1b394b354..674c35d6ade0 100644 --- a/src/vs/workbench/parts/files/browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/browser/files.contribution.ts @@ -19,6 +19,7 @@ import {IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions} from import {IEditorRegistry, Extensions as EditorExtensions, IEditorInputFactory} from 'vs/workbench/browser/parts/editor/baseEditor'; import {EditorInput, IFileEditorInput} from 'vs/workbench/common/editor'; import {FileEditorDescriptor} from 'vs/workbench/parts/files/browser/files'; +import {AutoSaveModes} from 'vs/platform/files/common/files'; import {FILE_EDITOR_INPUT_ID, VIEWLET_ID} from 'vs/workbench/parts/files/common/files'; import {FileTracker} from 'vs/workbench/parts/files/browser/fileTracker'; import {SaveParticipant} from 'vs/workbench/parts/files/common/editors/saveParticipant'; @@ -79,9 +80,9 @@ let openViewletKb: IKeybindings = { [ 'text/*', - // In case the mime type is unknown, we prefer the text file editor over the binary editor to leave a chance - // of opening a potential text file properly. The resolution of the file in the text file editor will fail - // early on in case the file is actually binary, to prevent downloading a potential large binary file. + // In case the mime type is unknown, we prefer the text file editor over the binary editor to leave a chance + // of opening a potential text file properly. The resolution of the file in the text file editor will fail + // early on in case the file is actually binary, to prevent downloading a potential large binary file. 'application/unknown' ] ), @@ -124,7 +125,7 @@ interface ISerializedFileInput { // Register Editor Input Factory class FileEditorInputFactory implements IEditorInputFactory { - constructor(@INullService ns) {} + constructor(@INullService ns) { } public serialize(editorInput: EditorInput): string { let fileEditorInput = editorInput; @@ -200,15 +201,16 @@ configurationRegistry.registerConfiguration({ 'default': false, 'description': nls.localize('trimTrailingWhitespace', "When enabled, will trim trailing whitespace when you save a file.") }, + 'files.autoSave': { + 'type': 'string', + 'enum': [AutoSaveModes.OFF, AutoSaveModes.AFTER_DELAY, AutoSaveModes.ON_FOCUS_CHANGE], + 'default': AutoSaveModes.OFF, + 'description': nls.localize('autoSave', "Controls auto save of dirty files. Accepted values: \"{0}\", \"{1}\", \"{2}\". If set to \"{3}\" you can configure the delay in \"files.autoSaveDelay\".", AutoSaveModes.OFF, AutoSaveModes.AFTER_DELAY, AutoSaveModes.ON_FOCUS_CHANGE, AutoSaveModes.AFTER_DELAY) + }, 'files.autoSaveDelay': { 'type': 'number', - 'default': 0, - 'description': nls.localize('autoSaveDelay', "When set to a positive number, will automatically save dirty editors after configured seconds.") - }, - 'files.autoSaveFocusChange': { - 'type': 'boolean', - 'default': false, - 'description': nls.localize('autoSaveFocusChange', "When enabled, will automatically save dirty editors when they lose focus or are closed.") + 'default': 1000, + 'description': nls.localize('autoSaveDelay', "Controls the delay in ms after which a dirty file is saved automatically. Only applies when \"files.autoSave\" is set to \"{0}\"", AutoSaveModes.AFTER_DELAY) } } }); diff --git a/src/vs/workbench/parts/files/browser/textFileServices.ts b/src/vs/workbench/parts/files/browser/textFileServices.ts index 9fa08a0ed79a..ddf1da1ab373 100644 --- a/src/vs/workbench/parts/files/browser/textFileServices.ts +++ b/src/vs/workbench/parts/files/browser/textFileServices.ts @@ -15,7 +15,7 @@ import {IResult, ITextFileOperationResult, ConfirmResult, ITextFileService, IAut import {EventType} from 'vs/workbench/common/events'; import {WorkingFilesModel} from 'vs/workbench/parts/files/common/workingFilesModel'; import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService'; -import {IFilesConfiguration, IFileOperationResult, FileOperationResult} from 'vs/platform/files/common/files'; +import {IFilesConfiguration, IFileOperationResult, FileOperationResult, AutoSaveModes} from 'vs/platform/files/common/files'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle'; import {IEventService} from 'vs/platform/event/common/event'; @@ -100,8 +100,23 @@ export abstract class TextFileService implements ITextFileService { private onConfigurationChange(configuration: IFilesConfiguration): void { const wasAutoSaveEnabled = this.isAutoSaveEnabled(); - this.configuredAutoSaveDelay = configuration && configuration.files && configuration.files.autoSaveDelay; - this.configuredAutoSaveOnFocusChange = configuration && configuration.files && configuration.files.autoSaveFocusChange; + const autoSaveMode = (configuration && configuration.files && configuration.files.autoSave) || AutoSaveModes.OFF; + switch (autoSaveMode) { + case AutoSaveModes.AFTER_DELAY: + this.configuredAutoSaveDelay = configuration && configuration.files && configuration.files.autoSaveDelay; + this.configuredAutoSaveOnFocusChange = false; + break; + + case AutoSaveModes.ON_FOCUS_CHANGE: + this.configuredAutoSaveDelay = void 0; + this.configuredAutoSaveOnFocusChange = true; + break; + + default: + this.configuredAutoSaveDelay = void 0; + this.configuredAutoSaveOnFocusChange = false; + break; + } // Emit as event this._onAutoSaveConfigurationChange.fire(this.getAutoSaveConfiguration()); diff --git a/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts b/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts index cd213247b1e4..7b626c73114b 100644 --- a/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts +++ b/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts @@ -132,7 +132,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements IEncodin private updateAutoSaveConfiguration(config: IAutoSaveConfiguration): void { if (typeof config.autoSaveDelay === 'number' && config.autoSaveDelay > 0) { - this.autoSaveAfterMillies = config.autoSaveDelay * 1000; + this.autoSaveAfterMillies = config.autoSaveDelay; this.autoSaveAfterMilliesEnabled = true; } else { this.autoSaveAfterMillies = void 0;