aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Deierlein2024-03-19 16:26:50 +0000
committerGitHub2024-03-19 16:26:50 +0000
commit427dd2f383ab54457ec4e7bbb9cf0d83b9d7908a (patch)
treef5cefc3f4de74b1a32b4c91292df15cd3c08b00e
parentd9de809a573e28c425b5da9da8c77340d2a0174e (diff)
Add support for ember.js templates (#9902)
* feat: add support for ember .hbs (glimmer) templates * adjust highlights to helix * highlight this correctly in block statements * correctly highlight attributes * correctly highlight hash_pair * add newline to highlights.scm * refactor: use #any-of and #eq instead of #match * chore: add newline to languages.toml
-rw-r--r--book/src/generated/lang-support.md1
-rw-r--r--languages.toml25
-rw-r--r--runtime/queries/glimmer/highlights.scm94
3 files changed, 119 insertions, 1 deletions
diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md
index 47f8057e..b74a8cdb 100644
--- a/book/src/generated/lang-support.md
+++ b/book/src/generated/lang-support.md
@@ -60,6 +60,7 @@
| git-ignore | ✓ | | | |
| git-rebase | ✓ | | | |
| gleam | ✓ | ✓ | | `gleam` |
+| glimmer | ✓ | | | `ember-language-server` |
| glsl | ✓ | ✓ | ✓ | |
| gn | ✓ | | | |
| go | ✓ | ✓ | ✓ | `gopls`, `golangci-lint-langserver` |
diff --git a/languages.toml b/languages.toml
index ccd546fa..5ce10bf0 100644
--- a/languages.toml
+++ b/languages.toml
@@ -100,6 +100,7 @@ blueprint-compiler = { command = "blueprint-compiler", args = ["lsp"] }
typst-lsp = { command = "typst-lsp" }
pkgbuild-language-server = { command = "pkgbuild-language-server" }
helm_ls = { command = "helm_ls", args = ["serve"] }
+ember-language-server = { command = "ember-language-server", args = ["--stdio"] }
[language-server.ansible-language-server]
command = "ansible-language-server"
@@ -3390,4 +3391,26 @@ scope = "source.helm"
roots = ["Chart.yaml"]
comment-token = "#"
language-servers = ["helm_ls"]
-file-types = [ { glob = "templates/*.yaml" }, { glob = "templates/_helpers.tpl"}, { glob = "templates/NOTES.txt" } ] \ No newline at end of file
+file-types = [ { glob = "templates/*.yaml" }, { glob = "templates/_helpers.tpl"}, { glob = "templates/NOTES.txt" } ]
+
+[[language]]
+name = "glimmer"
+scope = "source.glimmer"
+injection-regex = "hbs"
+file-types = [{ glob = "{app,addon}/{components,templates}/*.hbs" }]
+block-comment-tokens = { start = "{{!", end = "}}" }
+roots = ["package.json", "ember-cli-build.js"]
+grammar = "glimmer"
+language-servers = ["ember-language-server"]
+formatter = { command = "prettier", args = ['--parser', 'glimmer'] }
+
+[language.auto-pairs]
+'"' = '"'
+'{' = '}'
+'(' = ')'
+'<' = '>'
+"'" = "'"
+
+[[grammar]]
+name = "glimmer"
+source = { git = "https://github.com/ember-tooling/tree-sitter-glimmer", rev = "5dc6d1040e8ff8978ff3680e818d85447bbc10aa" }
diff --git a/runtime/queries/glimmer/highlights.scm b/runtime/queries/glimmer/highlights.scm
new file mode 100644
index 00000000..789722ad
--- /dev/null
+++ b/runtime/queries/glimmer/highlights.scm
@@ -0,0 +1,94 @@
+; === Tag Names ===
+
+; Tags that start with a lower case letter are HTML tags
+; We'll also use this highlighting for named blocks (which start with `:`)
+((tag_name) @tag
+ (#match? @tag "^(:)?[a-z]"))
+; Tags that start with a capital letter are Glimmer components
+((tag_name) @constructor
+ (#match? @constructor "^[A-Z]"))
+
+(attribute_name) @attribute
+
+(string_literal) @string
+(number_literal) @constant.numeric.integer
+(boolean_literal) @constant.builtin.boolean
+
+(concat_statement) @string
+
+; === Block Statements ===
+
+; Highlight the brackets
+(block_statement_start) @punctuation.delimiter
+(block_statement_end) @punctuation.delimiter
+
+; Highlight `if`/`each`/`let`
+(block_statement_start path: (identifier) @keyword.control.conditional)
+(block_statement_end path: (identifier) @keyword.control.conditional)
+((mustache_statement (identifier) @keyword.control.conditional)
+ (#eq? @keyword.control.conditional "else"))
+
+; == Mustache Statements ===
+
+; Hightlight the whole statement, to color brackets and separators
+(mustache_statement) @punctuation.delimiter
+
+; An identifier in a mustache expression is a variable
+((mustache_statement [
+ (path_expression (identifier) @variable)
+ (identifier) @variable
+ ])
+ (#not-any-of? @variable "yield" "outlet" "this" "else"))
+; As are arguments in a block statement
+((block_statement_start argument: [
+ (path_expression (identifier) @variable)
+ (identifier) @variable
+ ])
+ (#not-eq? @variable "this"))
+; As is an identifier in a block param
+(block_params (identifier) @variable)
+; As are helper arguments
+((helper_invocation argument: [
+ (path_expression (identifier) @variable)
+ (identifier) @variable
+ ])
+ (#not-eq? @variable "this"))
+; `this` should be highlighted as a built-in variable
+((identifier) @variable.builtin
+ (#eq? @variable.builtin "this"))
+
+; If the identifier is just "yield" or "outlet", it's a keyword
+((mustache_statement (identifier) @keyword.control.return)
+ (#any-of? @keyword.control.return "yield" "outlet"))
+
+; Helpers are functions
+((helper_invocation helper: [
+ (path_expression (identifier) @function)
+ (identifier) @function
+ ])
+ (#not-any-of? @function "if" "yield"))
+
+((helper_invocation helper: (identifier) @keyword.control.conditional)
+ (#any-of? @keyword.control.conditional "if" "yield"))
+
+(hash_pair key: (identifier) @variable)
+(hash_pair value: (identifier) @variable)
+(hash_pair [
+ (path_expression (identifier) @variable)
+ (identifier) @variable
+ ])
+
+(comment_statement) @comment
+
+(attribute_node "=" @operator)
+
+(block_params "as" @keyword.control)
+(block_params "|" @operator)
+
+[
+ "<"
+ ">"
+ "</"
+ "/>"
+] @punctuation.delimiter
+