mirror of
https://github.com/atom/atom.git
synced 2026-04-06 03:02:13 -04:00
Start on syntax global. Use it to replace scoped config settings.
We'll store all syntax-related global state in the `syntax` global. For now, this means that all scoped properties will be stored here, as well as all grammars.
This commit is contained in:
@@ -34,33 +34,11 @@ class Config
|
||||
userConfig = JSON.parse(fs.read(configJsonPath))
|
||||
_.extend(@settings, userConfig)
|
||||
|
||||
get: (args...) ->
|
||||
scopeStack = args.shift() if args.length > 1
|
||||
keyPath = args.shift()
|
||||
keys = @keysForKeyPath(keyPath)
|
||||
|
||||
settingsToSearch = []
|
||||
settingsToSearch.push(@settingsForScopeChain(scopeStack)...) if scopeStack
|
||||
settingsToSearch.push(@settings)
|
||||
|
||||
for settings in settingsToSearch
|
||||
value = settings
|
||||
for key in keys
|
||||
value = value[key]
|
||||
break unless value?
|
||||
return value if value?
|
||||
undefined
|
||||
|
||||
set: (args...) ->
|
||||
scope = args.shift() if args.length > 2
|
||||
keyPath = args.shift()
|
||||
value = args.shift()
|
||||
|
||||
keys = @keysForKeyPath(keyPath)
|
||||
if scope
|
||||
keys.unshift(scope)
|
||||
keys.unshift('scopes')
|
||||
get: (keyPath) ->
|
||||
_.valueForKeyPath(@settings, keyPath)
|
||||
|
||||
set: (keyPath, value) ->
|
||||
keys = keyPath.split('.')
|
||||
hash = @settings
|
||||
while keys.length > 1
|
||||
key = keys.shift()
|
||||
@@ -72,7 +50,7 @@ class Config
|
||||
value
|
||||
|
||||
setDefaults: (keyPath, defaults) ->
|
||||
keys = @keysForKeyPath(keyPath)
|
||||
keys = keyPath.split('.')
|
||||
hash = @settings
|
||||
for key in keys
|
||||
hash[key] ?= {}
|
||||
@@ -102,46 +80,6 @@ class Config
|
||||
save: ->
|
||||
fs.write(configJsonPath, JSON.stringify(@settings, undefined, 2) + "\n")
|
||||
|
||||
keysForKeyPath: (keyPath) ->
|
||||
if typeof keyPath is 'string'
|
||||
keyPath.split(".")
|
||||
else
|
||||
new Array(keyPath...)
|
||||
|
||||
settingsForScopeChain: (scopeStack) ->
|
||||
return [] unless @settings.scopes?
|
||||
|
||||
matchingScopeSelectors = []
|
||||
node = @buildDomNodeFromScopeChain(scopeStack)
|
||||
while node
|
||||
scopeSelectorsForNode = []
|
||||
for scopeSelector of @settings.scopes
|
||||
if jQuery.find.matchesSelector(node, scopeSelector)
|
||||
scopeSelectorsForNode.push(scopeSelector)
|
||||
scopeSelectorsForNode.sort (a, b) -> Specificity(b) - Specificity(a)
|
||||
matchingScopeSelectors.push(scopeSelectorsForNode...)
|
||||
node = node.parentNode
|
||||
|
||||
matchingScopeSelectors.map (scopeSelector) => @settings.scopes[scopeSelector]
|
||||
|
||||
buildDomNodeFromScopeChain: (scopeStack) ->
|
||||
scopeStack = new Array(scopeStack...)
|
||||
element = $$ ->
|
||||
elementsForRemainingScopes = =>
|
||||
classString = scopeStack.shift()
|
||||
classes = classString.replace(/^\./, '').replace(/\./g, ' ')
|
||||
if scopeStack.length
|
||||
@div class: classes, elementsForRemainingScopes
|
||||
else
|
||||
@div class: classes
|
||||
elementsForRemainingScopes()
|
||||
|
||||
deepestChild = element.find(":not(:has(*))")
|
||||
if deepestChild.length
|
||||
deepestChild[0]
|
||||
else
|
||||
element[0]
|
||||
|
||||
requireUserInitScript: ->
|
||||
try
|
||||
require userInitScriptPath if fs.exists(userInitScriptPath)
|
||||
|
||||
59
src/app/syntax.coffee
Normal file
59
src/app/syntax.coffee
Normal file
@@ -0,0 +1,59 @@
|
||||
_ = require 'underscore'
|
||||
jQuery = require 'jquery'
|
||||
Specificity = require 'specificity'
|
||||
{$$} = require 'space-pen'
|
||||
|
||||
module.exports =
|
||||
class Syntax
|
||||
constructor: ->
|
||||
@globalProperties = {}
|
||||
@propertiesBySelector = {}
|
||||
|
||||
addProperties: (args...) ->
|
||||
scopeSelector = args.shift() if args.length > 1
|
||||
properties = args.shift()
|
||||
|
||||
if scopeSelector
|
||||
@propertiesBySelector[scopeSelector] ?= {}
|
||||
_.extend(@propertiesBySelector[scopeSelector], properties)
|
||||
else
|
||||
_.extend(@globalProperties, properties)
|
||||
|
||||
getProperty: (scope, keyPath) ->
|
||||
for object in @propertiesForScope(scope)
|
||||
value = _.valueForKeyPath(object, keyPath)
|
||||
return value if value?
|
||||
undefined
|
||||
|
||||
propertiesForScope: (scope) ->
|
||||
matchingSelectors = []
|
||||
element = @buildScopeElement(scope)
|
||||
while element
|
||||
matchingSelectors.push(@matchingSelectorsForElement(element)...)
|
||||
element = element.parentNode
|
||||
properties = matchingSelectors.map (selector) => @propertiesBySelector[selector]
|
||||
properties.concat([@globalProperties])
|
||||
|
||||
matchingSelectorsForElement: (element) ->
|
||||
matchingSelectors = []
|
||||
for selector of @propertiesBySelector
|
||||
matchingSelectors.push(selector) if jQuery.find.matchesSelector(element, selector)
|
||||
matchingSelectors.sort (a, b) -> Specificity(b) - Specificity(a)
|
||||
|
||||
buildScopeElement: (scope) ->
|
||||
scope = new Array(scope...)
|
||||
element = $$ ->
|
||||
elementsForRemainingScopes = =>
|
||||
classString = scope.shift()
|
||||
classes = classString.replace(/^\./, '').replace(/\./g, ' ')
|
||||
if scope.length
|
||||
@div class: classes, elementsForRemainingScopes
|
||||
else
|
||||
@div class: classes
|
||||
elementsForRemainingScopes()
|
||||
|
||||
deepestChild = element.find(":not(:has(*))")
|
||||
if deepestChild.length
|
||||
deepestChild[0]
|
||||
else
|
||||
element[0]
|
||||
@@ -9,6 +9,7 @@ _ = require 'underscore'
|
||||
$ = require 'jquery'
|
||||
{CoffeeScript} = require 'coffee-script'
|
||||
Config = require 'config'
|
||||
Syntax = require 'syntax'
|
||||
RootView = require 'root-view'
|
||||
Pasteboard = require 'pasteboard'
|
||||
require 'jquery-extensions'
|
||||
@@ -25,6 +26,7 @@ windowAdditions =
|
||||
# in all environments: spec, benchmark, and application
|
||||
startup: ->
|
||||
@config = new Config
|
||||
@syntax = new Syntax
|
||||
TextMateTheme.loadAll()
|
||||
@setUpKeymap()
|
||||
@pasteboard = new Pasteboard
|
||||
|
||||
@@ -85,3 +85,10 @@ _.mixin
|
||||
|
||||
endsWith: (string, suffix) ->
|
||||
string.indexOf(suffix, string.length - suffix.length) isnt -1
|
||||
|
||||
valueForKeyPath: (object, keyPath) ->
|
||||
keys = keyPath.split('.')
|
||||
for key in keys
|
||||
object = object[key]
|
||||
return unless object?
|
||||
object
|
||||
|
||||
Reference in New Issue
Block a user