diff --git a/src/vs/workbench/services/configuration/node/configurationEditingService.ts b/src/vs/workbench/services/configuration/node/configurationEditingService.ts index 4352bd113b1fc..74dc243d50645 100644 --- a/src/vs/workbench/services/configuration/node/configurationEditingService.ts +++ b/src/vs/workbench/services/configuration/node/configurationEditingService.ts @@ -11,6 +11,7 @@ import URI from 'vs/base/common/uri'; import * as json from 'vs/base/common/json'; import * as encoding from 'vs/base/node/encoding'; import * as pfs from 'vs/base/node/pfs'; +import strings = require('vs/base/common/strings'); import {getConfigurationKeys} from 'vs/platform/configuration/common/model'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {setProperty} from 'vs/base/common/jsonEdit'; @@ -72,7 +73,7 @@ export class ConfigurationEditingService implements IConfigurationEditingService return ensureConfigurationFile.then(() => { // Apply all edits to the configuration file - const result = this.applyEdits(contents, [operation]); + const result = this.applyEdits(contents, operation); return pfs.writeFile(resource.fsPath, result, encoding.UTF8).then(() => { @@ -119,17 +120,20 @@ export class ConfigurationEditingService implements IConfigurationEditingService } } - private applyEdits(content: string, values: IConfigurationValue[]): string { + private applyEdits(content: string, edit: IConfigurationEditOperation): string { const {tabSize, insertSpaces} = this.configurationService.getConfiguration<{ tabSize: number; insertSpaces: boolean }>('editor'); const {eol} = this.configurationService.getConfiguration<{ eol: string }>('files'); - while (values.length > 0) { - const {key, value} = values.pop(); + const {key, value} = edit; - const edits = setProperty(content, [key], value, { tabSize, insertSpaces, eol }); - content = applyEdits(content, edits); + // Without key, the entire settings file is being replaced, so we just use JSON.stringify + if (!key) { + return JSON.stringify(value, null, insertSpaces ? strings.repeat(' ', tabSize) : '\t'); } + const edits = setProperty(content, [key], value, { tabSize, insertSpaces, eol }); + content = applyEdits(content, edits); + return content; } @@ -188,9 +192,15 @@ export class ConfigurationEditingService implements IConfigurationEditingService const standaloneConfigurationKeys = Object.keys(WORKSPACE_STANDALONE_CONFIGURATIONS); for (let i = 0; i < standaloneConfigurationKeys.length; i++) { const key = standaloneConfigurationKeys[i]; - const keyPrefix = `${key}.`; const target = this.contextService.toResource(WORKSPACE_STANDALONE_CONFIGURATIONS[key]); + // Check for prefix + if (config.key === key) { + return { key: '', value: config.value, target, isWorkspaceStandalone: true }; + } + + // Check for prefix. + const keyPrefix = `${key}.`; if (config.key.indexOf(keyPrefix) === 0) { return { key: config.key.substr(keyPrefix.length), value: config.value, target, isWorkspaceStandalone: true }; } diff --git a/src/vs/workbench/services/configuration/test/node/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/node/configurationEditingService.test.ts index 99f25de5b4e3a..fc2b05163a344 100644 --- a/src/vs/workbench/services/configuration/test/node/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/node/configurationEditingService.test.ts @@ -112,7 +112,7 @@ suite('WorkspaceConfigurationEditingService - Node', () => { createWorkspace((workspaceDir, globalSettingsFile, cleanUp) => { return createServices(workspaceDir, globalSettingsFile, false, true /* no workspace */).then(services => { return services.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'unknown.key', value: 'value' }).then(res => { - }, (error:IConfigurationEditingError) => { + }, (error: IConfigurationEditingError) => { assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_UNKNOWN_KEY); services.configurationService.dispose(); cleanUp(done); @@ -125,7 +125,7 @@ suite('WorkspaceConfigurationEditingService - Node', () => { createWorkspace((workspaceDir, globalSettingsFile, cleanUp) => { return createServices(workspaceDir, globalSettingsFile).then(services => { return services.configurationEditingService.writeConfiguration(ConfigurationTarget.USER, { key: 'tasks.something', value: 'value' }).then(res => { - }, (error:IConfigurationEditingError) => { + }, (error: IConfigurationEditingError) => { assert.equal(error.code, ConfigurationEditingErrorCode.ERROR_INVALID_TARGET); services.configurationService.dispose(); cleanUp(done); @@ -251,4 +251,44 @@ suite('WorkspaceConfigurationEditingService - Node', () => { }); }); }); + + test('write workspace standalone setting - empty file - full JSON', (done: () => void) => { + createWorkspace((workspaceDir, globalSettingsFile, cleanUp) => { + return createServices(workspaceDir, globalSettingsFile).then(services => { + return services.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } }).then(res => { + const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']); + const contents = fs.readFileSync(target).toString('utf8'); + const parsed = json.parse(contents); + + assert.equal(parsed['version'], '1.0.0'); + assert.equal(parsed['tasks'][0]['taskName'], 'myTask'); + + services.configurationService.dispose(); + cleanUp(done); + }); + }); + }); + }); + + test('write workspace standalone setting - existing file - full JSON', (done: () => void) => { + createWorkspace((workspaceDir, globalSettingsFile, cleanUp) => { + return createServices(workspaceDir, globalSettingsFile).then(services => { + const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['launch']); + + fs.writeFileSync(target, '{ "my.super.setting": "my.super.value" }'); + + return services.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, { key: 'tasks', value: { 'version': '1.0.0', tasks: [{ 'taskName': 'myTask' }] } }).then(res => { + const target = path.join(workspaceDir, WORKSPACE_STANDALONE_CONFIGURATIONS['tasks']); + const contents = fs.readFileSync(target).toString('utf8'); + const parsed = json.parse(contents); + + assert.equal(parsed['version'], '1.0.0'); + assert.equal(parsed['tasks'][0]['taskName'], 'myTask'); + + services.configurationService.dispose(); + cleanUp(done); + }); + }); + }); + }); }); \ No newline at end of file