Skip to content

Commit c7ed45e

Browse files
authored
Merge pull request #14 from SWAT-engineering/pico-vscode-extension
Pico VS Code extension
2 parents 1a3b465 + 7c7bec8 commit c7ed45e

File tree

9 files changed

+360
-75
lines changed

9 files changed

+360
-75
lines changed

rascal-textmate-core/src/main/rascal/Main.rsc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ module Main
77
import Grammar;
88
import lang::textmate::Conversion;
99
import lang::textmate::Grammar;
10+
import lang::textmate::NameGeneration;
1011

1112
int main(type[&T <: Tree] tree, str scopeName, loc f) {
1213
RscGrammar rsc = Grammar::grammar(tree);
1314
return main(rsc, scopeName, f);
1415
}
1516

1617
int main(RscGrammar rsc, str scopeName, loc l) {
17-
TmGrammar tm = toTmGrammar(rsc, scopeName);
18+
TmGrammar tm = toTmGrammar(rsc, scopeName, nameGeneration = short());
1819
toJSON(tm, indent = 2, l = l);
1920
return 0;
2021
}
Lines changed: 6 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,15 @@
11
@synopsis{
2-
Main function to generate a new TextMate grammar for use in the special VS
3-
Code extension
2+
Main function to generate new TextMate grammars for Rascal and Pico, to be
3+
used in the special VS Code extension
44
}
55

66
module VSCode
77

8-
import Grammar;
9-
import lang::rascal::\syntax::Rascal;
10-
import lang::textmate::Conversion;
11-
import lang::textmate::Grammar;
12-
import lang::textmate::NameGeneration;
8+
import VSCodePico;
9+
import VSCodeRascal;
1310

1411
int main() {
15-
str scopeName = "source.rascalmpl.injection";
16-
RscGrammar rsc = getRscGrammar();
17-
TmGrammar tm = toTmGrammar(rsc, scopeName, nameGeneration = short())[injectionSelector = "R:source.rascalmpl"];
18-
toJSON(tm, indent = 2, l = |project://vscode-extension/syntaxes/rascal.tmLanguage.json|);
12+
VSCodePico::main();
13+
VSCodeRascal::main();
1914
return 0;
20-
}
21-
22-
RscGrammar getRscGrammar() {
23-
Production setCategory(p: prod(_, _, attributes), str category)
24-
= {\tag("category"(_)), *rest} := attributes
25-
? p[attributes = rest + \tag("category"(category))]
26-
: p[attributes = attributes + \tag("category"(category))];
27-
28-
return visit (Grammar::grammar(#Module)) {
29-
30-
// The following mapping is based on:
31-
// - https://github.com/usethesource/rascal/blob/83023f60a6eb9df7a19ccc7a4194b513ac7b7157/src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L44-L59
32-
// - https://github.com/usethesource/rascal-language-servers/blob/752fea3ea09101e5b22ee426b11c5e36db880225/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/SemanticTokenizer.java#L121-L142
33-
// With updates based on:
34-
// - https://github.com/eclipse-lsp4j/lsp4j/blob/f235e91fbe2e45f62e185bbb9f6d21bed48eb2b9/org.eclipse.lsp4j/src/main/java/org/eclipse/lsp4j/Protocol.xtend#L5639-L5695
35-
// - https://github.com/usethesource/rascal-language-servers/blob/88be4a326128da8c81d581c2b918b4927f2185be/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/SemanticTokenizer.java#L134-L152
36-
case \tag("category"("Normal")) => \tag("category"("source"))
37-
case \tag("category"("Type")) => \tag("category"("type")) // Updated (before: storage.type)
38-
case \tag("category"("Identifier")) => \tag("category"("variable"))
39-
case \tag("category"("Variable")) => \tag("category"("variable"))
40-
case \tag("category"("Constant")) => \tag("category"("string")) // Updated (before: constant)
41-
case \tag("category"("Comment")) => \tag("category"("comment"))
42-
case \tag("category"("Todo")) => \tag("category"("comment"))
43-
case \tag("category"("Quote")) => \tag("category"("string")) // Updated (before: meta.string)
44-
case \tag("category"("MetaAmbiguity")) => \tag("category"("invalid"))
45-
case \tag("category"("MetaVariable")) => \tag("category"("variable"))
46-
case \tag("category"("MetaKeyword")) => \tag("category"("keyword")) // Updated (before: keyword.other)
47-
case \tag("category"("MetaSkipped")) => \tag("category"("string"))
48-
case \tag("category"("NonterminalLabel")) => \tag("category"("variable")) // Updated (before: variable.parameter)
49-
case \tag("category"("Result")) => \tag("category"("string")) // Updated (before: text)
50-
case \tag("category"("StdOut")) => \tag("category"("string")) // Updated (before: text)
51-
case \tag("category"("StdErr")) => \tag("category"("string")) // Updated (before: text)
52-
53-
// With additional hot-patching as discussed:
54-
// - https://github.com/SWAT-engineering/rascal-textmate/pull/6
55-
case p: prod(label("integer", sort("Literal")), _, _) => setCategory(p, "constant.numeric")
56-
case p: prod(label("real", sort("Literal")), _, _) => setCategory(p, "constant.numeric")
57-
case p: prod(label("rational", sort("Literal")), _, _) => setCategory(p, "constant.numeric")
58-
case p: prod(label("location", sort("Literal")), _, _) => setCategory(p, "markup.underline.link")
59-
case p: prod(label("regExp", sort("Literal")), _, _) => setCategory(p, "constant.regexp")
60-
case p: prod(lex("StringConstant"), _, _) => setCategory(p, "string.quoted.double")
61-
case p: prod(lex("CaseInsensitiveStringConstant"), _, _) => setCategory(p, "string.quoted.single")
62-
case p: prod(lex("PreStringChars"), _, _) => setCategory(p, "string.quoted.double")
63-
case p: prod(lex("MidStringChars"), _, _) => setCategory(p, "string.quoted.double")
64-
case p: prod(lex("PostStringChars"), _, _) => setCategory(p, "string.quoted.double")
65-
};
6615
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@synopsis{
2+
Main function to generate a new TextMate grammar for Pico, to be used in the
3+
special VS Code extension
4+
}
5+
6+
module VSCodePico
7+
8+
import Main;
9+
extend lang::textmate::conversiontests::PicoWithCategories;
10+
11+
int main() = Main::main(rsc, "source.pico", |project://vscode-extension/syntaxes/pico.tmLanguage.json|);
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
@synopsis{
2+
Main function to generate a new TextMate grammar for Rascal, to be used in
3+
the special VS Code extension
4+
}
5+
6+
module VSCodeRascal
7+
8+
import Grammar;
9+
import Main;
10+
extend lang::textmate::conversiontests::Rascal;
11+
12+
int main() = Main::main(getRscGrammar(), "source.rascalmpl", |project://vscode-extension/syntaxes/rascal.tmLanguage.json|);
13+
14+
// Relevant comment regarding grammar precedence in VS Code:
15+
// - https://github.com/microsoft/vscode-docs/issues/2862#issuecomment-599994967
16+
17+
private Grammar getRscGrammar() {
18+
Production setCategory(p: prod(_, _, attributes), str category)
19+
= {\tag("category"(_)), *rest} := attributes
20+
? p[attributes = rest + \tag("category"(category))]
21+
: p[attributes = attributes + \tag("category"(category))];
22+
23+
return visit (rsc) {
24+
25+
// The following mapping is based on:
26+
// - https://github.com/usethesource/rascal/blob/83023f60a6eb9df7a19ccc7a4194b513ac7b7157/src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L44-L59
27+
// - https://github.com/usethesource/rascal-language-servers/blob/752fea3ea09101e5b22ee426b11c5e36db880225/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/SemanticTokenizer.java#L121-L142
28+
// With updates based on:
29+
// - https://github.com/eclipse-lsp4j/lsp4j/blob/f235e91fbe2e45f62e185bbb9f6d21bed48eb2b9/org.eclipse.lsp4j/src/main/java/org/eclipse/lsp4j/Protocol.xtend#L5639-L5695
30+
// - https://github.com/usethesource/rascal-language-servers/blob/88be4a326128da8c81d581c2b918b4927f2185be/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/SemanticTokenizer.java#L134-L152
31+
case \tag("category"("Normal")) => \tag("category"("source"))
32+
case \tag("category"("Type")) => \tag("category"("type")) // Updated (before: storage.type)
33+
case \tag("category"("Identifier")) => \tag("category"("variable"))
34+
case \tag("category"("Variable")) => \tag("category"("variable"))
35+
case \tag("category"("Constant")) => \tag("category"("string")) // Updated (before: constant)
36+
case \tag("category"("Comment")) => \tag("category"("comment"))
37+
case \tag("category"("Todo")) => \tag("category"("comment"))
38+
case \tag("category"("Quote")) => \tag("category"("string")) // Updated (before: meta.string)
39+
case \tag("category"("MetaAmbiguity")) => \tag("category"("invalid"))
40+
case \tag("category"("MetaVariable")) => \tag("category"("variable"))
41+
case \tag("category"("MetaKeyword")) => \tag("category"("keyword")) // Updated (before: keyword.other)
42+
case \tag("category"("MetaSkipped")) => \tag("category"("string"))
43+
case \tag("category"("NonterminalLabel")) => \tag("category"("variable")) // Updated (before: variable.parameter)
44+
case \tag("category"("Result")) => \tag("category"("string")) // Updated (before: text)
45+
case \tag("category"("StdOut")) => \tag("category"("string")) // Updated (before: text)
46+
case \tag("category"("StdErr")) => \tag("category"("string")) // Updated (before: text)
47+
48+
// With additional hot-patching as discussed:
49+
// - https://github.com/SWAT-engineering/rascal-textmate/pull/6
50+
case p: prod(label("integer", sort("Literal")), _, _) => setCategory(p, "constant.numeric")
51+
case p: prod(label("real", sort("Literal")), _, _) => setCategory(p, "constant.numeric")
52+
case p: prod(label("rational", sort("Literal")), _, _) => setCategory(p, "constant.numeric")
53+
case p: prod(label("location", sort("Literal")), _, _) => setCategory(p, "markup.underline.link")
54+
case p: prod(label("regExp", sort("Literal")), _, _) => setCategory(p, "constant.regexp")
55+
case p: prod(lex("StringConstant"), _, _) => setCategory(p, "string.quoted.double")
56+
case p: prod(lex("CaseInsensitiveStringConstant"), _, _) => setCategory(p, "string.quoted.single")
57+
case p: prod(lex("PreStringChars"), _, _) => setCategory(p, "string.quoted.double")
58+
case p: prod(lex("MidStringChars"), _, _) => setCategory(p, "string.quoted.double")
59+
case p: prod(lex("PostStringChars"), _, _) => setCategory(p, "string.quoted.double")
60+
};
61+
}

rascal-textmate-core/src/main/rascal/lang/textmate/conversiontests/PicoWithCategories.rsc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,23 @@ syntax Expression
4242
| min: Expression lhs "-" Expression rhs)
4343
;
4444

45-
lexical Id = [a-z][a-z0-9]* !>> [a-z0-9];
45+
lexical Id = ([a-z][a-z0-9]*) !>> [a-z0-9] \ Keyword;
4646
lexical Natural = [0-9]+ !>> [0-9];
4747
lexical String = "\"" ![\"]* "\"";
4848

49+
keyword Keyword
50+
= "begin"
51+
| "end"
52+
| "declare"
53+
| "if"
54+
| "then"
55+
| "else"
56+
| "fi"
57+
| "while"
58+
| "do"
59+
| "od"
60+
;
61+
4962
layout Layout = WhitespaceAndComment* !>> [\ \t\n\r%];
5063

5164
lexical WhitespaceAndComment

rascal-textmate-core/src/main/rascal/lang/textmate/conversiontests/PicoWithCategories.test

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
# ^^^^^ comment.block
1616

1717
do
18-
# ^^ variable.other
18+
# ^^ -variable.other
19+
# ^^ keyword.control
1920

2021
123
2122
# ^^^ constant.numeric
@@ -39,10 +40,6 @@
3940
# ^^^^^^^ variable.other
4041
# ^^^^^^^ storage.type
4142

42-
#begin
43-
## <----- keyword.control
44-
## TODO: `begin` outside `begin`-`end` can never be an identifier in Pico
45-
4643
"foo bar"
4744
# ^^^^^^^^^ string.quoted.double
4845

vscode-extension/package.json

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"name": "rascal-syntax-highlighting",
3-
"displayName": "Rascal Syntax Highlighting",
2+
"name": "rascalmpl-syntax-highlighting",
3+
"displayName": "Rascal Metaprogramming Language (Syntax Highlighting)",
44
"description": "",
55
"version": "0.0.1",
66
"engines": {
@@ -10,11 +10,31 @@
1010
"Programming Languages"
1111
],
1212
"contributes": {
13-
"grammars": [{
14-
"language": "rascalmpl",
15-
"scopeName": "source.rascalmpl.injection",
16-
"path": "./syntaxes/rascal.tmLanguage.json",
17-
"injectTo": ["source.rascalmpl"]
18-
}]
13+
"languages": [
14+
{
15+
"id": "rascalmpl",
16+
"aliases": ["Rascal MPL"],
17+
"extensions": [".rsc"],
18+
"configuration": "./language-configuration.json"
19+
},
20+
{
21+
"id": "pico",
22+
"aliases": ["Pico"],
23+
"extensions": [".pico"],
24+
"configuration": "./language-configuration.json"
25+
}
26+
],
27+
"grammars": [
28+
{
29+
"language": "rascalmpl",
30+
"scopeName": "source.rascalmpl",
31+
"path": "./syntaxes/rascal.tmLanguage.json"
32+
},
33+
{
34+
"language": "pico",
35+
"scopeName": "source.pico",
36+
"path": "./syntaxes/pico.tmLanguage.json"
37+
}
38+
]
1939
}
2040
}

0 commit comments

Comments
 (0)