Snippets parser can parse tab stops in the form of $1, $2, etc.

It associates each tab stop with its position relative to the beginning of the snippet body, and strips the '$number' marker from the inserted snippet body.
This commit is contained in:
Nathan Sobo
2012-06-21 16:33:21 -06:00
parent 2e0943f41a
commit f9ec6214e6
4 changed files with 56 additions and 10 deletions

View File

@@ -0,0 +1,21 @@
_ = require 'underscore'
module.exports =
class Snippet
constructor: ({@bodyPosition, @prefix, @description, body}) ->
@body = @extractTabStops(body)
extractTabStops: (body) ->
tabStopsByIndex = {}
bodyText = []
for element in body
if element.index
tabStopsByIndex[element.index] = element.position.subtract(@bodyPosition)
else
bodyText.push(element)
@tabStops = []
for index in _.keys(tabStopsByIndex).sort()
@tabStops.push tabStopsByIndex[index]
bodyText.join('')

View File

@@ -5,7 +5,7 @@ _ = require 'underscore'
module.exports =
name: 'Snippets'
snippetsByExtension: {}
snippetsParser: PEG.buildParser(fs.read(require.resolve 'extensions/snippets/snippets.pegjs'))
snippetsParser: PEG.buildParser(fs.read(require.resolve 'extensions/snippets/snippets.pegjs'), trackLineAndColumn: true)
activate: (@rootView) ->
@loadSnippets()

View File

@@ -1,3 +1,8 @@
{
var Snippet = require('extensions/snippets/snippet');
var Point = require('point');
}
snippets = snippets:snippet+ ws? {
var snippetsByPrefix = {};
snippets.forEach(function(snippet) {
@@ -6,17 +11,21 @@ snippets = snippets:snippet+ ws? {
return snippetsByPrefix;
}
snippet = ws? start ws prefix:prefix ws description:string separator body:body end {
return { prefix: prefix, description: description, body: body };
snippet = ws? start ws prefix:prefix ws description:string bodyPosition:beforeBody body:body end {
return new Snippet({ bodyPosition: bodyPosition, prefix: prefix, description: description, body: body });
}
separator = [ ]* '\n'
start = 'snippet'
prefix = prefix:[A-Za-z0-9_]+ { return prefix.join(''); }
body = body:bodyCharacter* { return body.join(''); }
bodyCharacter = !end char:. { return char; }
string = ['] body:[^']* ['] { return body.join(''); }
/ ["] body:[^"]* ["] { return body.join(''); }
beforeBody = [ ]* '\n' { return new Point(line, 0); } // return start position of body: body begins on next line, so don't subtract 1 from line
body = (tabStop / bodyText)*
bodyText = body:bodyCharacter+ { return body.join(''); }
bodyCharacter = !(end / tabStop) char:. { return char; }
tabStop = '$' index:[0-9]+ { return { index: index, position: new Point(line - 1, column - 1) }; }
end = '\nendsnippet'
string
= ['] body:[^']* ['] { return body.join(''); }
/ ["] body:[^"]* ["] { return body.join(''); }
ws = [ \n]+
ws = ([ \n] / comment)+
comment = '#' [^\n]*