From 98415f288ffa043520b0c85bc4464dc44b85f948 Mon Sep 17 00:00:00 2001
From: Philipp Mildenberger <philipp@mildenberger.me>
Date: Fri, 10 Mar 2023 17:32:45 +0100
Subject: [PATCH] Improved yuck highlighting (and parser), and introduced a
 tag.builtin scope (#6242)

---
 book/src/themes.md                  |   1 +
 languages.toml                      |   2 +-
 runtime/queries/yuck/highlights.scm | 137 ++++++++++++++++++----------
 runtime/queries/yuck/injections.scm |   2 +-
 4 files changed, 92 insertions(+), 50 deletions(-)

diff --git a/book/src/themes.md b/book/src/themes.md
index af238e94..5ddd4f2c 100644
--- a/book/src/themes.md
+++ b/book/src/themes.md
@@ -215,6 +215,7 @@ We use a similar set of scopes as
   - `special` (preprocessor in C)
 
 - `tag` - Tags (e.g. `<body>` in HTML)
+  - `builtin`
 
 - `namespace`
 
diff --git a/languages.toml b/languages.toml
index 8697f9fc..86f4a64d 100644
--- a/languages.toml
+++ b/languages.toml
@@ -2206,7 +2206,7 @@ indent = { tab-width = 2, unit = "  " }
 
 [[grammar]]
 name = "yuck"
-source = { git = "https://github.com/Philipp-M/tree-sitter-yuck", rev = "9e97da5773f82123a8c8cccf8f7e795d140ed7d1" }
+source = { git = "https://github.com/Philipp-M/tree-sitter-yuck", rev = "e3d91a3c65decdea467adebe4127b8366fa47919" }
 
 [[language]]
 name = "prql"
diff --git a/runtime/queries/yuck/highlights.scm b/runtime/queries/yuck/highlights.scm
index 483348a8..9f116f15 100644
--- a/runtime/queries/yuck/highlights.scm
+++ b/runtime/queries/yuck/highlights.scm
@@ -1,66 +1,107 @@
+; Errors
+
 (ERROR) @error
 
-(line_comment) @comment
+; Comments
 
-; keywords and symbols
+(comment) @comment
 
-(keyword) @keyword
-(symbol) @tag
+; Operators
 
-; literals
+[
+  "+"
+  "-"
+  "*"
+  "/"
+  "%"
+  "||"
+  "&&"
+  "=="
+  "!="
+  "=~"
+  ">"
+  "<"
+  ">="
+  "<="
+  "!"
+  "?."
+  "?:"
+] @operator
 
-(bool_literal) @constant.builtin.boolean
-(num_literal) @constant.numeric
+(ternary_expression
+  ["?" ":"] @operator)
 
-; strings
-(string_interpolation
-  (string_interpolation_start) @punctuation.special
-  (string_interpolation_end) @punctuation.special)
+; Punctuation
+
+[ ":" "." "," ] @punctuation.delimiter
+
+[ "{" "}" "[" "]" "(" ")" ] @punctuation.bracket
+
+; Literals
+
+(number (float)) @constant.numeric.float
+
+(number (integer)) @constant.numeric.integer
+
+(boolean) @constant.builtin.boolean
+
+; Strings
 
 (escape_sequence) @constant.character.escape
 
-(string
-  [
-    (unescaped_single_quote_string_fragment)
-    (unescaped_double_quote_string_fragment)
-    (unescaped_backtick_string_fragment)
-    "\""
-    "'"
-    "`"
-  ]) @string
+(string_interpolation
+  "${" @punctuation.special
+  "}" @punctuation.special)
 
-; operators and general punctuation
+[ (string_fragment) "\"" "'" "`" ] @string
 
-(unary_expression
-  operator: _ @operator)
+; Attributes & Fields
 
-(binary_expression
-  operator: _ @operator)
+(keyword) @attribute
 
-(ternary_expression
-  operator: _ @operator)
+; Functions
 
-[
-  ":"
-  "."
-  ","
-] @punctuation.delimiter
+(function_call
+  name: (ident) @function)
 
-[
-  "("
-  ")"
-  "["
-  "]"
-  "{"
-  "}"
-] @punctuation.bracket
-[
-  ":"
-  "."
-  ","
-] @punctuation.delimiter
+; Variables
 
-; Rest (general identifiers that are not yet catched)
-
-(index) @variable
 (ident) @variable
+
+(array
+  (symbol) @variable)
+
+; Builtin widgets
+
+(list .
+  ((symbol) @tag.builtin
+    (#match? @tag.builtin "^(box|button|calendar|centerbox|checkbox|circular-progress|color-button|color-chooser|combo-box-text|eventbox|expander|graph|image|input|label|literal|overlay|progress|revealer|scale|scroll|transform)$")))
+
+; Keywords
+
+; I think there's a bug in tree-sitter the anchor doesn't seem to be working, see
+; https://github.com/tree-sitter/tree-sitter/pull/2107
+(list .
+  ((symbol) @keyword
+    (#match? @keyword "^(defwindow|defwidget|defvar|defpoll|deflisten|geometry|children|struts)$")))
+
+(list .
+  ((symbol) @keyword.control.import
+    (#eq? @keyword.control.import "include")))
+
+; Loop
+
+(loop_widget . "for" @keyword.control.repeat . (symbol) @variable . "in" @keyword.operator . (symbol) @variable)
+
+(loop_widget . "for" @keyword.control.repeat . (symbol) @variable . "in" @keyword.operator)
+
+; Tags
+
+; TODO apply to every symbol in list? I think it should probably only be applied to the first child of the list
+(list
+  (symbol) @tag)
+
+; Other stuff that has not been catched by the previous queries yet
+
+(ident) @variable
+(index) @variable
diff --git a/runtime/queries/yuck/injections.scm b/runtime/queries/yuck/injections.scm
index d3fdb0ca..321c90ad 100644
--- a/runtime/queries/yuck/injections.scm
+++ b/runtime/queries/yuck/injections.scm
@@ -1,2 +1,2 @@
-((line_comment) @injection.content
+((comment) @injection.content
  (#set! injection.language "comment"))