Files
atom/src/app/text-mate-package.coffee
2013-02-25 08:58:47 -08:00

117 lines
3.7 KiB
CoffeeScript

Package = require 'package'
fs = require 'fs'
plist = require 'plist'
_ = require 'underscore'
TextMateGrammar = require 'text-mate-grammar'
module.exports =
class TextMatePackage extends Package
@testName: (packageName) ->
/(\.|_|-)tmbundle$/.test(packageName)
@cssSelectorFromScopeSelector: (scopeSelector) ->
scopeSelector.split(', ').map((commaFragment) ->
commaFragment.split(' ').map((spaceFragment) ->
spaceFragment.split('.').map((dotFragment) ->
'.' + dotFragment.replace(/\+/g, '\\+')
).join('')
).join(' ')
).join(', ')
constructor: ->
super
@preferencesPath = fs.join(@path, "Preferences")
@syntaxesPath = fs.join(@path, "Syntaxes")
@grammars = []
load: ->
try
@loadGrammars()
catch e
console.warn "Failed to load package at '#{@path}'", e.stack
this
getGrammars: -> @grammars
readGrammars: ->
grammars = []
for grammarPath in fs.list(@syntaxesPath)
try
grammars.push(TextMateGrammar.readFromPath(grammarPath))
catch e
console.warn "Failed to load grammar at path '#{grammarPath}'", e.stack
grammars
addGrammar: (rawGrammar) ->
grammar = new TextMateGrammar(rawGrammar)
@grammars.push(grammar)
syntax.addGrammar(grammar)
loadGrammars: (rawGrammars) ->
rawGrammars = @readGrammars() unless rawGrammars?
@grammars = []
@addGrammar(rawGrammar) for rawGrammar in rawGrammars
@loadScopedProperties()
loadScopedProperties: ->
for { selector, properties } in @getScopedProperties()
syntax.addProperties(selector, properties)
getScopedProperties: ->
scopedProperties = []
for grammar in @getGrammars()
if properties = @propertiesFromTextMateSettings(grammar)
selector = @cssSelectorFromScopeSelector(grammar.scopeName)
scopedProperties.push({selector, properties})
for {scope, settings} in @getTextMatePreferenceObjects()
if properties = @propertiesFromTextMateSettings(settings)
selector = @cssSelectorFromScopeSelector(scope) if scope?
scopedProperties.push({selector, properties})
scopedProperties
readObjectFromPath: (path, callback) ->
object = null
error = null
if fs.isObjectPath(path)
object = fs.readObject(path)
else
plist.parseString fs.read(path), (e, data) ->
error = e
object = data[0]
error = throw new Error("Failed to load object at path `#{path}`") unless object
callback(error, object)
getTextMatePreferenceObjects: ->
preferenceObjects = []
if fs.exists(@preferencesPath)
for preferencePath in fs.list(@preferencesPath)
@readObjectFromPath preferencePath, (e, object) =>
if e
console.warn "Failed to parse preference at path '#{preferencePath}'", e.stack
else
preferenceObjects.push(object)
preferenceObjects
propertiesFromTextMateSettings: (textMateSettings) ->
if textMateSettings.shellVariables
shellVariables = {}
for {name, value} in textMateSettings.shellVariables
shellVariables[name] = value
textMateSettings.shellVariables = shellVariables
editorProperties = _.compactObject(
commentStart: _.valueForKeyPath(textMateSettings, 'shellVariables.TM_COMMENT_START')
commentEnd: _.valueForKeyPath(textMateSettings, 'shellVariables.TM_COMMENT_END')
increaseIndentPattern: textMateSettings.increaseIndentPattern
decreaseIndentPattern: textMateSettings.decreaseIndentPattern
foldEndPattern: textMateSettings.foldingStopMarker
)
{ editor: editorProperties } if _.size(editorProperties) > 0
cssSelectorFromScopeSelector: (scopeSelector) ->
@constructor.cssSelectorFromScopeSelector(scopeSelector)