diff --git a/docs/internals/configuration.md b/docs/internals/configuration.md index d1df1d358..ab9dbedf7 100644 --- a/docs/internals/configuration.md +++ b/docs/internals/configuration.md @@ -48,11 +48,6 @@ the following way: ```coffeescript # basic key update config.set("core.autosave", true) - -# if you mutate a config key, you'll need to call `config.update` to inform -# observers of the change -config.get("fuzzyFinder.ignoredPaths").push "vendor" -config.update() ``` You can also use `setDefaults`, which will assign default values for keys that diff --git a/spec/app/config-spec.coffee b/spec/app/config-spec.coffee index a1aa37884..41933f2db 100644 --- a/spec/app/config-spec.coffee +++ b/spec/app/config-spec.coffee @@ -8,6 +8,13 @@ describe "Config", -> expect(config.get("foo.bar.baz")).toBe 42 expect(config.get("bogus.key.path")).toBeUndefined() + it "returns a deep clone of the key path's value", -> + config.set('value', array: [1, b: 2, 3]) + retrievedValue = config.get('value') + retrievedValue.array[0] = 4 + retrievedValue.array[1].b = 2.1 + expect(config.get('value')).toEqual(array: [1, b: 2, 3]) + describe ".set(keyPath, value)", -> it "allows a key path's value to be written", -> expect(config.set("foo.bar.baz", 42)).toBe 42 @@ -93,21 +100,6 @@ describe "Config", -> expect(config.get("foo.quux.x")).toBe 0 expect(config.get("foo.quux.y")).toBe 1 - describe ".update()", -> - it "updates observers if a value is mutated without the use of .set", -> - config.set("foo.bar.baz", ["a"]) - observeHandler = jasmine.createSpy "observeHandler" - config.observe "foo.bar.baz", observeHandler - observeHandler.reset() - - config.get("foo.bar.baz").push("b") - config.update() - expect(observeHandler).toHaveBeenCalledWith config.get("foo.bar.baz") - observeHandler.reset() - - config.update() - expect(observeHandler).not.toHaveBeenCalled() - describe ".observe(keyPath)", -> observeHandler = null diff --git a/spec/app/project-spec.coffee b/spec/app/project-spec.coffee index 6367e20c4..6180ceb23 100644 --- a/spec/app/project-spec.coffee +++ b/spec/app/project-spec.coffee @@ -180,8 +180,9 @@ describe "Project", -> it "ignores ignored.txt file", -> paths = null - config.get("core.ignoredNames").push("ignored.txt") - config.update() + ignoredNames = config.get("core.ignoredNames") + ignoredNames.push("ignored.txt") + config.set("core.ignoredNames", ignoredNames) waitsForPromise -> project.getFilePaths().done (foundPaths) -> paths = foundPaths diff --git a/src/app/config.coffee b/src/app/config.coffee index 767959330..5fbb5e08e 100644 --- a/src/app/config.coffee +++ b/src/app/config.coffee @@ -106,8 +106,8 @@ class Config # Returns the value from Atom's default settings, the user's configuration file, # or `null` if the key doesn't exist in either. get: (keyPath) -> - _.valueForKeyPath(@settings, keyPath) ? - _.valueForKeyPath(@defaultSettings, keyPath) + value = _.valueForKeyPath(@settings, keyPath) ? _.valueForKeyPath(@defaultSettings, keyPath) + _.deepClone(value) # Retrieves the setting for the given key as an integer. # diff --git a/src/app/package-config-panel.coffee b/src/app/package-config-panel.coffee index 43a95faed..137ca6851 100644 --- a/src/app/package-config-panel.coffee +++ b/src/app/package-config-panel.coffee @@ -29,11 +29,12 @@ class PackageConfigPanel extends ConfigPanel @on 'change', '#packages input[type=checkbox]', (e) -> checkbox = $(e.target) name = checkbox.closest('tr').attr('name') + disabledPackages = config.get('core.disabledPackages') if checkbox.attr('checked') - _.remove(config.get('core.disabledPackages'), name) + _.remove(disabledPackages, name) else - config.get('core.disabledPackages').push(name) - config.update() + disabledPackages.push(name) + config.set('core.disabledPackages', disabledPackages) @observeConfig 'core.disabledPackages', (disabledPackages) => @packageTableBody.find("input[type='checkbox']").attr('checked', true) diff --git a/src/stdlib/underscore-extensions.coffee b/src/stdlib/underscore-extensions.coffee index 6f71705d5..8251cbcd1 100644 --- a/src/stdlib/underscore-extensions.coffee +++ b/src/stdlib/underscore-extensions.coffee @@ -126,6 +126,35 @@ _.mixin endsWith: (string, suffix) -> string.indexOf(suffix, string.length - suffix.length) isnt -1 + # Transform the given object into another object. + # + # `object` - The object to transform. + # `iterator` - + # A function that takes `(key, value)` arguments and returns a + # `[key, value]` tuple. + # + # Returns a new object based with the key/values returned by the iterator. + mapObject: (object, iterator) -> + newObject = {} + for key, value of object + [key, value] = iterator(key, value) + newObject[key] = value + + newObject + + # Deep clones the given JSON object. + # + # `object` - The JSON object to clone. + # + # Returns a deep clone of the JSON object. + deepClone: (object) -> + if _.isArray(object) + object.map (value) -> _.deepClone(value) + else if _.isObject(object) + @mapObject object, (key, value) => [key, @deepClone(value)] + else + object + valueForKeyPath: (object, keyPath) -> keys = keyPath.split('.') for key in keys