mirror of
https://github.com/atom/atom.git
synced 2026-01-22 13:28:01 -05:00
Update ::observe and add ::onDidChange
This commit is contained in:
@@ -231,6 +231,26 @@ describe "Config", ->
|
||||
atom.config.setDefaults("foo.bar.baz", a: 2)
|
||||
expect(updatedCallback.callCount).toBe 1
|
||||
|
||||
describe ".onDidChange(keyPath)", ->
|
||||
[observeHandler, observeSubscription] = []
|
||||
|
||||
beforeEach ->
|
||||
observeHandler = jasmine.createSpy("observeHandler")
|
||||
atom.config.set("foo.bar.baz", "value 1")
|
||||
observeSubscription = atom.config.onDidChange "foo.bar.baz", observeHandler
|
||||
|
||||
it "does not fire the given callback with the current value at the keypath", ->
|
||||
expect(observeHandler).not.toHaveBeenCalledWith("value 1")
|
||||
|
||||
it "fires the callback every time the observed value changes", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 2", {previous: 'value 1'})
|
||||
observeHandler.reset()
|
||||
|
||||
atom.config.set('foo.bar.baz', "value 1")
|
||||
expect(observeHandler).toHaveBeenCalledWith("value 1", {previous: 'value 2'})
|
||||
|
||||
describe ".observe(keyPath)", ->
|
||||
[observeHandler, observeSubscription] = []
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
{Emitter} = require 'emissary'
|
||||
EmitterMixin = require('emissary').Emitter
|
||||
{Emitter} = require 'event-kit'
|
||||
CSON = require 'season'
|
||||
path = require 'path'
|
||||
async = require 'async'
|
||||
pathWatcher = require 'pathwatcher'
|
||||
{deprecate} = require 'grim'
|
||||
|
||||
# Essential: Used to access all of Atom's configuration details.
|
||||
#
|
||||
@@ -24,16 +26,67 @@ pathWatcher = require 'pathwatcher'
|
||||
# ```
|
||||
module.exports =
|
||||
class Config
|
||||
Emitter.includeInto(this)
|
||||
EmitterMixin.includeInto(this)
|
||||
|
||||
# Created during initialization, available as `atom.config`
|
||||
constructor: ({@configDirPath, @resourcePath}={}) ->
|
||||
@emitter = new Emitter
|
||||
@defaultSettings = {}
|
||||
@settings = {}
|
||||
@configFileHasErrors = false
|
||||
@configFilePath = fs.resolve(@configDirPath, 'config', ['json', 'cson'])
|
||||
@configFilePath ?= path.join(@configDirPath, 'config.cson')
|
||||
|
||||
###
|
||||
Section: Config Subscription
|
||||
###
|
||||
|
||||
# Essential: Add a listener for changes to a given key path.
|
||||
#
|
||||
# * `keyPath` The {String} name of the key to observe
|
||||
# * `callback` The {Function} to call when the value of the key changes.
|
||||
# The first argument will be the new value of the key and the
|
||||
# second argument will be an {Object} with a `previous` property
|
||||
# that is the prior value of the key.
|
||||
#
|
||||
# Returns a {Disposable} with the following keys on which you can call
|
||||
# `.dispose()` to unsubscribe.
|
||||
onDidChange: (keyPath, callback) ->
|
||||
value = @get(keyPath)
|
||||
previousValue = _.clone(value)
|
||||
updateCallback = =>
|
||||
value = @get(keyPath)
|
||||
unless _.isEqual(value, previousValue)
|
||||
previous = previousValue
|
||||
previousValue = _.clone(value)
|
||||
callback(value, {previous})
|
||||
|
||||
@emitter.on 'did-change', updateCallback
|
||||
|
||||
# Essential: Add a listener for changes to a given key path. This is different
|
||||
# than {::onDidChange} in that it will immediately call your callback with the
|
||||
# current value of the config entry.
|
||||
#
|
||||
# * `keyPath` The {String} name of the key to observe
|
||||
# * `callback` The {Function} to call when the value of the key changes.
|
||||
# The first argument will be the new value of the key and the
|
||||
# second argument will be an {Object} with a `previous` property
|
||||
# that is the prior value of the key.
|
||||
#
|
||||
# Returns a {Disposable} with the following keys on which you can call
|
||||
# `.dispose()` to unsubscribe.
|
||||
observe: (keyPath, options={}, callback) ->
|
||||
if _.isFunction(options)
|
||||
callback = options
|
||||
options = {}
|
||||
else
|
||||
message = ''
|
||||
message = '`callNow` as been set to false. Use ::onDidChange instead.' if options.callNow == false
|
||||
deprecate 'Config::observe no longer supports options. #{message}'
|
||||
|
||||
callback(_.clone(@get(keyPath))) unless options.callNow == false
|
||||
@onDidChange(keyPath, callback)
|
||||
|
||||
###
|
||||
Section: get / set
|
||||
###
|
||||
@@ -75,36 +128,6 @@ class Config
|
||||
@update()
|
||||
value
|
||||
|
||||
# Essential: Add a listener for changes to a given key path.
|
||||
#
|
||||
# * `keyPath` The {String} name of the key to observe
|
||||
# * `options` An optional {Object} containing the `callNow` key.
|
||||
# * `callback` The {Function} to call when the value of the key changes.
|
||||
# The first argument will be the new value of the key and the
|
||||
# second argument will be an {Object} with a `previous` property
|
||||
# that is the prior value of the key.
|
||||
#
|
||||
# Returns an {Object} with the following keys:
|
||||
# * `off` A {Function} that unobserves the `keyPath` when called.
|
||||
observe: (keyPath, options={}, callback) ->
|
||||
if _.isFunction(options)
|
||||
callback = options
|
||||
options = {}
|
||||
|
||||
value = @get(keyPath)
|
||||
previousValue = _.clone(value)
|
||||
updateCallback = =>
|
||||
value = @get(keyPath)
|
||||
unless _.isEqual(value, previousValue)
|
||||
previous = previousValue
|
||||
previousValue = _.clone(value)
|
||||
callback(value, {previous})
|
||||
|
||||
eventName = "updated.#{keyPath.replace(/\./, '-')}"
|
||||
subscription = @on eventName, updateCallback
|
||||
callback(value) if options.callNow ? true
|
||||
subscription
|
||||
|
||||
# Extended: Get the {String} path to the config file being used.
|
||||
getUserConfigPath: ->
|
||||
@configFilePath
|
||||
@@ -113,7 +136,6 @@ class Config
|
||||
getSettings: ->
|
||||
_.deepExtend(@settings, @defaultSettings)
|
||||
|
||||
|
||||
# Extended: Restore the key path to its default value.
|
||||
#
|
||||
# * `keyPath` The {String} name of the key.
|
||||
@@ -252,6 +274,7 @@ class Config
|
||||
_.extend(@settings, userConfig)
|
||||
@configFileHasErrors = false
|
||||
@emit 'updated'
|
||||
@emitter.emit 'did-change'
|
||||
catch error
|
||||
@configFileHasErrors = true
|
||||
console.error "Failed to load user config '#{@configFilePath}'", error.message
|
||||
@@ -278,11 +301,13 @@ class Config
|
||||
|
||||
_.extend hash, defaults
|
||||
@emit 'updated'
|
||||
@emitter.emit 'did-change'
|
||||
|
||||
update: ->
|
||||
return if @configFileHasErrors
|
||||
@save()
|
||||
@emit 'updated'
|
||||
@emitter.emit 'did-change'
|
||||
|
||||
save: ->
|
||||
CSON.writeFileSync(@configFilePath, @settings)
|
||||
|
||||
Reference in New Issue
Block a user