Skip to content

Commit be24880

Browse files
committed
feat: add Amber syntax highlighting
1 parent 1fb67f5 commit be24880

File tree

12 files changed

+353
-0
lines changed

12 files changed

+353
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
## <a name="what-is-it"></a>What is it?
1919

2020
This [EclipseⓇ](https://eclipse.org) plug-in adds syntax highlighting support for the following languages/file formats utilizing [TM4E](https://github.com/eclipse/tm4e):
21+
1. Amber - https://amber-lang.com/
2122
1. ANTRL4 - https://www.antlr.org/
2223
1. Apache HTTP configuration files - https://httpd.apache.org/docs/current/configuring.html
2324
1. Astro - https://astro.build/
@@ -113,6 +114,7 @@ To install the plugin into an existing Eclipse installation do:
113114

114115
| Language/Format | File Associations | Source
115116
|:--------------- |:----------------- |:------ |
117+
| Amber <img src="plugin/syntaxes/amber/amber.icon.png" width=16/> | file-extensions="ab, amber" | [main@amber-lang/amber-vsc](https://github.com/amber-lang/amber-vsc/tree/c0ebd53e075698fa62efffd492a41b27bff1c227/)
116118
| ANTLR <img src="plugin/syntaxes/antlr4/icon.png" width=16/> | file-extensions="g, g4" | [master@mike-lischke/vscode-antlr4](https://github.com/mike-lischke/vscode-antlr4/tree/8408f1d50c59bc81f52795525ad41a6b50787316/)
117119
| Apache HTTP Config <img src="plugin/syntaxes/apache-http/icon.png" width=16/> | file-extensions="conf, htaccess, htgroups, htpasswd" | [master@mrmlnc/vscode-apache](https://github.com/mrmlnc/vscode-apache/tree/0585b0bb3d390fc541aa27cfcfb83b3204156be3/)
118120
| Astro <img src="plugin/syntaxes/astro/astro.icon.png" width=16/> | file-extensions="astro" | [main@withastro/language-tools](https://github.com/withastro/language-tools/tree/b4bcb4fc02cd960936a5faee6c9cc0ad94fc4c05/packages/vscode)

plugin/plugin.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,30 @@
5656

5757
<!-- START-GENERATED -->
5858

59+
<!-- ======================================== -->
60+
<!-- amber/amber: Amber -->
61+
<!-- ======================================== -->
62+
<extension point="org.eclipse.core.contenttype.contentTypes">
63+
<content-type id="extra-syntax-highlighting.amber" name="Amber" base-type="extra-syntax-highlighting.basetype" priority="normal"
64+
file-extensions="ab,amber" />
65+
</extension>
66+
<extension point="org.eclipse.tm4e.registry.grammars">
67+
<grammar scopeName="source.amber" path="syntaxes/amber/amber.tmLanguage.json" />
68+
<scopeNameContentTypeBinding scopeName="source.amber" contentTypeId="extra-syntax-highlighting.amber" />
69+
</extension>
70+
71+
<extension point="org.eclipse.tm4e.languageconfiguration.languageConfigurations">
72+
<languageConfiguration contentTypeId="extra-syntax-highlighting.amber" path="syntaxes/amber/amber.language-configuration.json" />
73+
</extension>
74+
75+
<extension point="org.eclipse.ui.genericeditor.icons">
76+
<icon contentType="extra-syntax-highlighting.amber" icon="syntaxes/amber/amber.icon.png"/>
77+
</extension>
78+
79+
<extension point="org.eclipse.tm4e.ui.snippets">
80+
<snippet name="Amber Example" path="syntaxes/amber/amber.example.ab" scopeName="source.amber" />
81+
</extension>
82+
5983
<!-- ======================================== -->
6084
<!-- antlr4/antlr: ANTLR -->
6185
<!-- ======================================== -->

plugin/syntaxes/amber/LICENSE.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Amber
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/// Sample Amber file for syntax highlighting showcase
2+
module demo.syntax
3+
4+
// --- Imports ---------------------------------------------------------
5+
6+
import std::io
7+
import std::collections::{Map, Set}
8+
import app::utils as utils
9+
10+
11+
// --- Records, Enums, Traits -----------------------------------------
12+
13+
/// A simple record with typed fields
14+
record User {
15+
id: Int,
16+
name: String,
17+
email: Option<String>,
18+
}
19+
20+
/// An enum with payloads and unit cases
21+
enum Message {
22+
Ping
23+
Text(content: String)
24+
Error(code: Int, reason: String)
25+
}
26+
27+
/// A trait (interface)
28+
trait Printable {
29+
fn print(self)
30+
}
31+
32+
33+
// --- Implementations -------------------------------------------------
34+
35+
impl Printable for User {
36+
fn print(self) {
37+
io::println("User(#{}): {}", self.id, self.name)
38+
}
39+
}
40+
41+
impl Printable for Message {
42+
fn print(self) {
43+
match self {
44+
Ping =>
45+
io::println("Ping"),
46+
Text(content) =>
47+
io::println("Text: {}", content),
48+
Error(code, reason) =>
49+
io::println("Error {}: {}", code, reason)
50+
}
51+
}
52+
}
53+
54+
55+
// --- Generic Functions ----------------------------------------------
56+
57+
fn identity<T>(value: T): T {
58+
value
59+
}
60+
61+
fn map_usernames(users: List<User>): List<String> {
62+
users.map(|u| u.name)
63+
}
64+
65+
66+
// --- Async/await -----------------------------------------------------
67+
68+
async fn fetch_user(id: Int): Result<User, String> {
69+
let response = await utils::http_get("https://api.example.com/users/{}", id)
70+
match response {
71+
Ok(json) => utils::parse_user(json),
72+
Err(e) => Err("Network error: {}".format(e))
73+
}
74+
}
75+
76+
77+
// --- Main Program ----------------------------------------------------
78+
79+
fn main() {
80+
// Variables
81+
let mut users = List<User>::new()
82+
83+
// Creating instances
84+
let u1 = User(id: 1, name: "Alice", email: Some("alice@example.com"))
85+
let u2 = User(id: 2, name: "Bob", email: None)
86+
87+
users.push(u1)
88+
users.push(u2)
89+
90+
// Pattern matching
91+
let msg = Message::Text("Hello Amber!")
92+
msg.print()
93+
94+
// Pipeline operator
95+
let names =
96+
users
97+
|> map_usernames
98+
|> List::sort
99+
100+
io::println("Usernames: {}", names)
101+
102+
// Async example
103+
let result = await fetch_user(3)
104+
match result {
105+
Ok(user) => user.print(),
106+
Err(err) => io::println("Failed to fetch user: {}", err)
107+
}
108+
}
397 Bytes
Loading
972 Bytes
Loading
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"comments": {
3+
"lineComment": "//"
4+
},
5+
"brackets": [
6+
["{", "}"],
7+
["[", "]"],
8+
["(", ")"]
9+
],
10+
"autoClosingPairs": [
11+
["{", "}"],
12+
["[", "]"],
13+
["(", ")"],
14+
["\"", "\""],
15+
["$", "$"]
16+
],
17+
"surroundingPairs": [
18+
["{", "}"],
19+
["[", "]"],
20+
["(", ")"],
21+
["\"", "\""],
22+
["$", "$"]
23+
],
24+
"indentationRules": {
25+
"increaseIndentPattern": "^.*(\\{|:)\\s*$",
26+
"decreaseIndentPattern": "^\\s*\\}.*$"
27+
}
28+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
3+
"name": "amber",
4+
"patterns": [
5+
{
6+
"include": "#keywords"
7+
},
8+
{
9+
"include": "#strings"
10+
},
11+
{
12+
"include": "#commands"
13+
},
14+
{
15+
"include": "#chars"
16+
},
17+
{
18+
"include": "#commentLine"
19+
}
20+
],
21+
"repository": {
22+
"keywords": {
23+
"patterns": [
24+
{
25+
"match": "^#!.*$",
26+
"name": "comment.line.shebang.amber"
27+
},
28+
{
29+
"match": "(fun)\\s+(\\w[^\\(]+)",
30+
31+
"captures": {
32+
"1" : {
33+
"name" : "keyword.control.amber"
34+
},
35+
"2" : {
36+
"name" : "entity.name.function"
37+
}
38+
}
39+
},
40+
{
41+
"name": "keyword.control.amber",
42+
"match": "\\b(if|loop|for|ref|return|fun|else|then|break|continue|and|or|not|let|const|import|from|pub|main|echo|cd|exit|mv|as|in|fail|failed|succeeded|exited|status|silent|nameof|len|lines|is|unsafe|trust|sudo|while)\\b"
43+
},
44+
{
45+
"match": "^#\\[.*\\]$",
46+
"name": "comment.compiler.amber"
47+
},
48+
{
49+
"match": "\\b(true|false|null)\\b(?![?!])",
50+
"name": "constant.language.boolean.amber"
51+
},
52+
{
53+
"match": "\\b(Text|Num|Int|Bool|Null)\\b",
54+
"name": "support.type.amber"
55+
},
56+
{
57+
"match": "[A-Z][a-z0-9_]+",
58+
"name": "entity.name.class.amber"
59+
},
60+
{
61+
"match": "[+-]?([0-9]*[.])?[0-9]+",
62+
"name": "constant.language.float.amber"
63+
},
64+
{
65+
"match": "\\b\\w+\\s*(?=\\([\\S\\s]*?\\)?)",
66+
"name": "entity.name.function"
67+
},
68+
{
69+
"name" : "keyword.operator.amber",
70+
"match" : "(\\+|\\-|\\^|\\*|\\=|\\||\\%|!|>|<|[.]{2}|\\?)"
71+
},
72+
{
73+
"name" : "comment.block",
74+
"match": "(\\/\\*[\\w\\'\\s\\r\\n\\*]*\\*\\/)"
75+
},
76+
{
77+
"name" : "variable.name",
78+
"match" : "\\b\\w+\\b"
79+
}
80+
]
81+
},
82+
"string-insides" : {
83+
"patterns": [
84+
{
85+
"name": "constant.character.escape.amber",
86+
"match": "\\\\."
87+
},
88+
{
89+
"name": "keyword.control",
90+
"begin" : "\\{",
91+
"end" : "\\}",
92+
"patterns": [
93+
{
94+
"include" : "$self"
95+
}
96+
]
97+
}
98+
]
99+
},
100+
"command-insides" : {
101+
"patterns": [
102+
{
103+
"name": "constant.character.escape.amber",
104+
"match": "\\\\."
105+
},
106+
{
107+
"name": "constant.language",
108+
"match": "-{1,2}[A-Za-z0-9-_]+"
109+
},
110+
{
111+
"name": "nothing",
112+
"match": "[A-Za-z0-9-_]+"
113+
},
114+
{
115+
"name": "keyword.control",
116+
"begin" : "\\{",
117+
"end" : "\\}",
118+
"patterns": [
119+
{
120+
"include" : "$self"
121+
}
122+
]
123+
}
124+
]
125+
},
126+
"strings": {
127+
"name": "string.quoted.double.amber",
128+
"begin": "\"",
129+
"end": "\"",
130+
"patterns": [
131+
{
132+
"include": "#string-insides"
133+
}
134+
]
135+
},
136+
"commands": {
137+
"name": "string",
138+
"begin": "\\$",
139+
"end": "\\$",
140+
"patterns": [
141+
{
142+
"include": "#command-insides"
143+
}
144+
]
145+
},
146+
"commentLine" : {
147+
"name":"comment.line",
148+
"begin" : "//",
149+
"end" : "$"
150+
}
151+
},
152+
"scopeName": "source.amber"
153+
}

plugin/syntaxes/amber/icon.png

397 Bytes
Loading

plugin/syntaxes/amber/icon@2x.png

972 Bytes
Loading

0 commit comments

Comments
 (0)