Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit 26c5d90

Browse files
committed
tweaks
1 parent e247bbd commit 26c5d90

File tree

5 files changed

+52
-9
lines changed

5 files changed

+52
-9
lines changed

lib/snippet-body.pegjs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,51 @@ regex ::= JS regex value
2525
2626
options ::= JS regex options // NOTE: Unrecognised options should be ignored for the best fault tolerance (can log a warning though)
2727
28+
modifier = '/' var
29+
2830
var ::= [a-zA-Z_][a-zA-Z_0-9]*
2931
3032
int ::= [0-9]+
3133
3234
*/
3335

36+
{
37+
function coalesce (parts) {
38+
const result = [];
39+
for (let i = 0; i < parts.length; i++) {
40+
const part = parts[i];
41+
const ri = result.length - 1;
42+
if (typeof part === 'string' && typeof result[ri] === 'string') {
43+
result[ri] = result[ri] + part;
44+
} else {
45+
result.push(part);
46+
}
47+
}
48+
return result;
49+
}
50+
}
51+
3452
// Grab anything that isn't \ or $, then try to build a special node out of it, and (at the top level) if that fails then just accept it as text
35-
topLevelContent = content:(text / escapedTopLevel / tabStop / choice / variable / any)* { return content; }
53+
topLevelContent = content:(text / escapedTopLevel / tabStop / choice / variable / any)* { return coalesce(content); }
3654

37-
tabStopContent = content:(text / escapedTabStop / tabStop / choice / variable)* { return content; }
55+
tabStopContent = content:(tabStopText / escapedTabStop / tabStop / choice / variable)* { return coalesce(content); }
3856

3957
tabStop = tabStopSimple / tabStopWithoutPlaceholder / tabStopWithPlaceholder / tabStopWithTransform
4058

41-
tabStopSimple = '$' n:integer { return { index: n }; }
59+
tabStopSimple = '$' n:integer { return { index: n, content: [] }; }
4260

43-
tabStopWithoutPlaceholder = '${' n:integer '}' { return { index: n }; }
61+
tabStopWithoutPlaceholder = '${' n:integer '}' { return { index: n, content: [] }; }
4462

4563
tabStopWithPlaceholder = '${' n:integer ':' content:tabStopContent '}' { return { index: n, content }; }
4664

4765
tabStopWithTransform = '${' n:integer t:transformation '}' { return { index: n, transformation: t }; }
4866

4967
transformation = '/' capture:regexString '/' replace:replace '/' flags:flags { return { capture, flags, replace }; }
5068

51-
regexString = r:[^/]* { return r.join(""); }
69+
// TODO: enforce this is a valid regex, or fail (can do at transform level where we make regex though)
70+
regexString = r:([^/\\] / '\\' c:. { return '\\' + c } )* { return r.join(""); }
5271

53-
replace = (format / replaceText)*
72+
replace = (format / replaceText / replaceModifier / escapedReplace)*
5473

5574
format = formatSimple / formatPlain / formatWithModifier / formatWithIf / formatWithIfElse / formatWithElse
5675

@@ -82,7 +101,9 @@ variableWithPlaceholder = '${' v:var ':' content:tabStopContent '}' { return { v
82101

83102
variableWithTransform = '${' v:var t:transformation '}' { return { variable: v, transformation: t }; }
84103

85-
text = t:[^$\\}]+ { return t.join("") }
104+
text = t:([^$\\}])+ { return t.join("") }
105+
106+
tabStopText = text
86107

87108
choiceText = t:[^,|]+ { return t.join(""); }
88109

@@ -95,6 +116,10 @@ escapedTabStop = escapedTopLevel
95116

96117
escapedChoice = '\\' c:[$\\,|] { return c; }
97118

119+
replaceModifier = '\\' m:[uUlL] { return { modifier: m }; }
120+
121+
escapedReplace = '\\' c:[$\\] { return c; }
122+
98123
// Match nonnegative integers like those used for tab stop ordering
99124
integer = digits:[0-9]+ { return parseInt(digits.join(""), 10); }
100125

lib/snippets.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ module.exports = {
4545
this.handleDisabledPackagesDidChange(newValue, oldValue)
4646
}))
4747

48+
this.subscriptions.add(atom.config.observe('snippets.snippetSyntax', ({newValue, oldValue}) => {
49+
this.handleSnippetSyntaxDidChange(newValue, oldValue)
50+
}))
51+
4852
const snippets = this
4953

5054
this.subscriptions.add(atom.commands.add('atom-text-editor', {
@@ -439,6 +443,10 @@ module.exports = {
439443
return this.bodyParser
440444
},
441445

446+
handleSnippetSyntaxDidChange(oldValue, newValue) {
447+
// TODO: Clear out all snippet parse trees && set the parser to the correct syntax
448+
},
449+
442450
// Get an {Object} with these keys:
443451
// * `snippetPrefix`: the possible snippet prefix text preceding the cursor
444452
// * `wordPrefix`: the word preceding the cursor

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
},
3333
"configSchema": {
3434
"snippetSyntax": {
35-
"type": "enum",
36-
"description": "Configures the syntax used for snippets. LSP is mostly a superset of original, with support for more features.",
35+
"type": "string",
36+
"description": "Configures the syntax used for snippets. LSP is mostly a superset of original, with support for more features (but not all features may be implemented yet).",
3737
"default": "LSP",
3838
"enum": [
3939
"LSP",

spec/body-parser-spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
const BodyParser = require('../lib/snippet-body-parser');
22

33
describe("Snippet Body Parser", () => {
4+
function t(snippetBody) {
5+
return BodyParser.parse(snippetBody);
6+
}
7+
48
it("breaks a snippet body into lines, with each line containing tab stops at the appropriate position", () => {
59
const bodyTree = BodyParser.parse(`\
610
the quick brown $1fox \${2:jumped \${3:over}

spec/parsing-todo.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
foo bar
2+
$1 ${1} ${1:/foo} ${1/foo/bar/baz}
3+
foo ${1 bar
4+
\\ \\\\ \\$ \\{ \\} \\, \\| \\: \\/ \\a \\n \\r
5+
${1:\\ \\\\ \\$ \\{ \\} \\, \\| \\: \\/ \\a \\n \\r}
6+
${1|\\ \\\\ \\$ \\{ \\} \\, \\| \\: \\/ \\a \\n \\r|}

0 commit comments

Comments
 (0)