Load snippets from TextMate bundles

There's still a bunch of holes in this. TextMate snippets have features
that we don't support yet. But the basic ones should now work.
This commit is contained in:
Nathan Sobo
2013-01-09 11:43:04 -07:00
parent cab5b25e76
commit e33f93b40c
5 changed files with 49 additions and 5 deletions

View File

@@ -5,11 +5,15 @@ Buffer = require 'buffer'
Editor = require 'editor'
_ = require 'underscore'
fs = require 'fs'
AtomPackage = require 'atom-package'
TextMatePackage = require 'text-mate-package'
describe "Snippets extension", ->
[buffer, editor] = []
beforeEach ->
rootView = new RootView(require.resolve('fixtures/sample.js'))
spyOn(AtomPackage.prototype, 'loadSnippets')
spyOn(TextMatePackage.prototype, 'loadSnippets')
atom.loadPackage("snippets")
editor = rootView.getActiveEditor()
buffer = editor.getBuffer()
@@ -31,8 +35,8 @@ describe "Snippets extension", ->
"tab stops":
prefix: "t2"
body: """
go here next:($2) and finally go here:($3)
go here first:($1)
go here next:($1) and finally go here:($2)
go here first:($0)
"""
@@ -204,8 +208,25 @@ describe "Snippets extension", ->
describe "snippet loading", ->
it "loads snippets from all atom packages with a snippets directory", ->
jasmine.unspy(AtomPackage.prototype, 'loadSnippets')
snippets.loadAll()
expect(syntax.getProperty(['.test'], 'snippets.test')?.constructor).toBe Snippet
it "loads snippets from all TextMate packages with snippets", ->
jasmine.unspy(TextMatePackage.prototype, 'loadSnippets')
snippets.loadAll()
snippet = syntax.getProperty(['.source.js'], 'snippets.fun')
expect(snippet.constructor).toBe Snippet
expect(snippet.prefix).toBe 'fun'
expect(snippet.name).toBe 'Function'
expect(snippet.body).toBe """
function function_name (argument) {
\t// body...
}
"""
describe "Snippets parser", ->
it "breaks a snippet body into lines, with each line containing tab stops at the appropriate position", ->
bodyTree = Snippets.parser.parse """

View File

@@ -9,3 +9,19 @@ AtomPackage.prototype.loadSnippets = ->
snippets.load(snippetsPath)
TextMatePackage.prototype.loadSnippets = ->
snippetsDirPath = fs.join(@path, 'Snippets')
if fs.exists(snippetsDirPath)
tmSnippets = fs.list(snippetsDirPath).map (snippetPath) -> fs.readPlist(snippetPath)
snippets.add(@translateSnippets(tmSnippets))
TextMatePackage.prototype.translateSnippets = (tmSnippets) ->
atomSnippets = {}
for { scope, name, content, tabTrigger } in tmSnippets
if scope
scope = TextMatePackage.cssSelectorFromScopeSelector(scope)
else
scope = '*'
snippetsForScope = (atomSnippets[scope] ?= {})
snippetsForScope[name] = { prefix: tabTrigger, body: content }
atomSnippets

View File

@@ -20,12 +20,12 @@ class Snippet
# recursive helper function; mutates vars above
extractTabStops = (bodyTree) ->
for segment in bodyTree
if segment.index
if segment.index?
{ index, content } = segment
start = [row, column]
extractTabStops(content)
tabStopsByIndex[index] = new Range(start, [row, column])
else
else if _.isString(segment)
bodyText.push(segment)
segmentLines = segment.split('\n')
column += segmentLines.shift().length

View File

@@ -35,7 +35,6 @@ module.exports =
snippetsByPrefix[snippet.prefix] = snippet
syntax.addProperties(selector, snippets: snippetsByPrefix)
enableSnippetsInEditor: (editor) ->
editor.command 'snippets:expand', (e) =>
editSession = editor.activeEditSession

View File

@@ -184,3 +184,11 @@ module.exports =
CoffeeScript.eval(contents, bare: true)
else
JSON.parse(contents)
readPlist: (path) ->
plist = require 'plist'
object = null
plist.parseString @read(path), (e, data) ->
throw new Error(e) if e
object = data[0]
object