Skip to content

Commit

Permalink
Add support for ember.js templates (helix-editor#9902)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
c0rydoras authored and postsolar committed Apr 4, 2024
1 parent acd6f86 commit 39c69ce
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 1 deletion.
1 change: 1 addition & 0 deletions book/src/generated/lang-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
| git-ignore || | | |
| git-rebase || | | |
| gleam ||| | `gleam` |
| glimmer || | | `ember-language-server` |
| glsl |||| |
| gn || | | |
| go |||| `gopls`, `golangci-lint-langserver` |
Expand Down
25 changes: 24 additions & 1 deletion languages.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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" } ]
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" }
94 changes: 94 additions & 0 deletions runtime/queries/glimmer/highlights.scm
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 39c69ce

Please sign in to comment.