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
This commit is contained in:
Arthur Deierlein 2024-03-19 17:26:50 +01:00 committed by GitHub
parent d9de809a57
commit 427dd2f383
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 119 additions and 1 deletions

View file

@ -60,6 +60,7 @@
| git-ignore | ✓ | | | | | git-ignore | ✓ | | | |
| git-rebase | ✓ | | | | | git-rebase | ✓ | | | |
| gleam | ✓ | ✓ | | `gleam` | | gleam | ✓ | ✓ | | `gleam` |
| glimmer | ✓ | | | `ember-language-server` |
| glsl | ✓ | ✓ | ✓ | | | glsl | ✓ | ✓ | ✓ | |
| gn | ✓ | | | | | gn | ✓ | | | |
| go | ✓ | ✓ | ✓ | `gopls`, `golangci-lint-langserver` | | go | ✓ | ✓ | ✓ | `gopls`, `golangci-lint-langserver` |

View file

@ -100,6 +100,7 @@ blueprint-compiler = { command = "blueprint-compiler", args = ["lsp"] }
typst-lsp = { command = "typst-lsp" } typst-lsp = { command = "typst-lsp" }
pkgbuild-language-server = { command = "pkgbuild-language-server" } pkgbuild-language-server = { command = "pkgbuild-language-server" }
helm_ls = { command = "helm_ls", args = ["serve"] } helm_ls = { command = "helm_ls", args = ["serve"] }
ember-language-server = { command = "ember-language-server", args = ["--stdio"] }
[language-server.ansible-language-server] [language-server.ansible-language-server]
command = "ansible-language-server" command = "ansible-language-server"
@ -3390,4 +3391,26 @@ scope = "source.helm"
roots = ["Chart.yaml"] roots = ["Chart.yaml"]
comment-token = "#" comment-token = "#"
language-servers = ["helm_ls"] language-servers = ["helm_ls"]
file-types = [ { glob = "templates/*.yaml" }, { glob = "templates/_helpers.tpl"}, { glob = "templates/NOTES.txt" } ] 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" }

View file

@ -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