mirror of
https://github.com/atom/atom.git
synced 2026-02-04 03:35:20 -05:00
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:
@@ -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 """
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user