Revert "Extract syntax highlighting properties from tree-sitter highlight queries (#2797)"

Max Brunsfeld created

This reverts commit 45c635872b5ef7bb8994e16d593aa25edf8e94bf, reversing
changes made to f2b82369f27b79fdcaa6a4276bb047abddf7171c.

Change summary

crates/zed/src/languages/bash/highlights.scm       |   2 
crates/zed/src/languages/c/highlights.scm          |   3 
crates/zed/src/languages/c/injections.scm          |   4 
crates/zed/src/languages/cpp/highlights.scm        |   4 
crates/zed/src/languages/cpp/injections.scm        |   4 
crates/zed/src/languages/css/highlights.scm        |   2 
crates/zed/src/languages/elixir/embedding.scm      |   6 
crates/zed/src/languages/elixir/highlights.scm     |  18 
crates/zed/src/languages/elixir/injections.scm     |   4 
crates/zed/src/languages/elixir/outline.scm        |   4 
crates/zed/src/languages/elm/injections.scm        |   2 
crates/zed/src/languages/erb/injections.scm        |   8 
crates/zed/src/languages/glsl/highlights.scm       |   4 
crates/zed/src/languages/heex/injections.scm       |   6 
crates/zed/src/languages/html/injections.scm       |   4 
crates/zed/src/languages/javascript/highlights.scm |   6 
crates/zed/src/languages/lua/highlights.scm        |  10 
crates/zed/src/languages/php/highlights.scm        |  10 
crates/zed/src/languages/php/injections.scm        |   4 
crates/zed/src/languages/python/highlights.scm     |   8 
crates/zed/src/languages/racket/highlights.scm     |   4 
crates/zed/src/languages/racket/outline.scm        |   4 
crates/zed/src/languages/ruby/brackets.scm         |   2 
crates/zed/src/languages/ruby/highlights.scm       |   8 
crates/zed/src/languages/rust/highlights.scm       |   4 
crates/zed/src/languages/rust/injections.scm       |   4 
crates/zed/src/languages/scheme/highlights.scm     |   4 
crates/zed/src/languages/scheme/outline.scm        |   4 
crates/zed/src/languages/svelte/injections.scm     |  14 
crates/zed/src/languages/typescript/highlights.scm |  10 
styles/package.json                                |   1 
styles/src/build_themes.ts                         |   9 
styles/src/build_tokens.ts                         |   4 
styles/src/component/icon_button.ts                |   5 
styles/src/component/tab_bar_button.ts             |  67 +-
styles/src/component/text_button.ts                |   5 
styles/src/style_tree/app.ts                       |   2 
styles/src/style_tree/assistant.ts                 |  69 +-
styles/src/style_tree/editor.ts                    |  32 
styles/src/style_tree/feedback.ts                  |   2 
styles/src/style_tree/picker.ts                    |   2 
styles/src/style_tree/project_panel.ts             |  16 
styles/src/style_tree/status_bar.ts                |  10 
styles/src/style_tree/titlebar.ts                  |   4 
styles/src/theme/create_theme.ts                   |  30 
styles/src/theme/syntax.ts                         | 389 ++++++++++++---
styles/src/theme/theme_config.ts                   |   6 
styles/src/theme/tokens/theme.ts                   |  10 
styles/src/themes/atelier/common.ts                |   9 
styles/src/themes/ayu/common.ts                    |   6 
styles/src/themes/gruvbox/gruvbox-common.ts        |   6 
styles/src/themes/one/one-dark.ts                  |   4 
styles/src/themes/one/one-light.ts                 |   2 
styles/src/themes/rose-pine/common.ts              |   4 
styles/src/types/extract_syntax_types.ts           | 111 ----
styles/src/types/syntax.ts                         | 202 --------
styles/tsconfig.json                               |   4 
57 files changed, 552 insertions(+), 630 deletions(-)

Detailed changes

crates/zed/src/languages/c/highlights.scm 🔗

@@ -86,7 +86,7 @@
 (identifier) @variable
 
 ((identifier) @constant
-    (.match? @constant "^_*[A-Z][A-Z\\d_]*$"))
+ (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
 
 (call_expression
   function: (identifier) @function)
@@ -106,3 +106,4 @@
   (primitive_type)
   (sized_type_specifier)
 ] @type
+

crates/zed/src/languages/c/injections.scm 🔗

@@ -1,7 +1,7 @@
 (preproc_def
     value: (preproc_arg) @content
-    (.set! "language" "c"))
+    (#set! "language" "c"))
 
 (preproc_function_def
     value: (preproc_arg) @content
-    (.set! "language" "c"))
+    (#set! "language" "c"))

crates/zed/src/languages/cpp/highlights.scm 🔗

@@ -31,13 +31,13 @@
   declarator: (field_identifier) @function)
 
 ((namespace_identifier) @type
-    (.match? @type "^[A-Z]"))
+ (#match? @type "^[A-Z]"))
 
 (auto) @type
 (type_identifier) @type
 
 ((identifier) @constant
-    (.match? @constant "^_*[A-Z][A-Z\\d_]*$"))
+ (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
 
 (field_identifier) @property
 (statement_identifier) @label

crates/zed/src/languages/cpp/injections.scm 🔗

@@ -1,7 +1,7 @@
 (preproc_def
     value: (preproc_arg) @content
-    (.set! "language" "c++"))
+    (#set! "language" "c++"))
 
 (preproc_function_def
     value: (preproc_arg) @content
-    (.set! "language" "c++"))
+    (#set! "language" "c++"))

crates/zed/src/languages/elixir/embedding.scm 🔗

@@ -3,7 +3,7 @@
         operator: "@"
         operand: (call
             target: (identifier) @unary
-            (.match? @unary "^(doc)$"))
+            (#match? @unary "^(doc)$"))
         ) @context
     .
     (call
@@ -18,10 +18,10 @@
                     target: (identifier) @name)
                     operator: "when")
             ])
-        (.match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item
+        (#match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item
         )
 
     (call
         target: (identifier) @name
         (arguments (alias) @name)
-        (.match? @name "^(defmodule|defprotocol)$")) @item
+        (#match? @name "^(defmodule|defprotocol)$")) @item

crates/zed/src/languages/elixir/highlights.scm 🔗

@@ -54,13 +54,13 @@
   (sigil_name) @__name__
   quoted_start: _ @string
   quoted_end: _ @string
-  (.match? @__name__ "^[sS]$")) @string
+  (#match? @__name__ "^[sS]$")) @string
 
 (sigil
   (sigil_name) @__name__
   quoted_start: _ @string.regex
   quoted_end: _ @string.regex
-  (.match? @__name__ "^[rR]$")) @string.regex
+  (#match? @__name__ "^[rR]$")) @string.regex
 
 (sigil
   (sigil_name) @__name__
@@ -69,7 +69,7 @@
 
 (
   (identifier) @comment.unused
-  (.match? @comment.unused "^_")
+  (#match? @comment.unused "^_")
 )
 
 (call
@@ -91,7 +91,7 @@
         operator: "|>"
         right: (identifier))
     ])
-  (.match? @keyword "^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$"))
+  (#match? @keyword "^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$"))
 
 (binary_operator
   operator: "|>"
@@ -99,15 +99,15 @@
 
 (call
   target: (identifier) @keyword
-  (.match? @keyword "^(def|defdelegate|defexception|defguard|defguardp|defimpl|defmacro|defmacrop|defmodule|defn|defnp|defoverridable|defp|defprotocol|defstruct)$"))
+  (#match? @keyword "^(def|defdelegate|defexception|defguard|defguardp|defimpl|defmacro|defmacrop|defmodule|defn|defnp|defoverridable|defp|defprotocol|defstruct)$"))
 
 (call
   target: (identifier) @keyword
-  (.match? @keyword "^(alias|case|cond|else|for|if|import|quote|raise|receive|require|reraise|super|throw|try|unless|unquote|unquote_splicing|use|with)$"))
+  (#match? @keyword "^(alias|case|cond|else|for|if|import|quote|raise|receive|require|reraise|super|throw|try|unless|unquote|unquote_splicing|use|with)$"))
 
 (
   (identifier) @constant.builtin
-  (.match? @constant.builtin "^(__MODULE__|__DIR__|__ENV__|__CALLER__|__STACKTRACE__)$")
+  (#match? @constant.builtin "^(__MODULE__|__DIR__|__ENV__|__CALLER__|__STACKTRACE__)$")
 )
 
 (unary_operator
@@ -121,7 +121,7 @@
         (sigil)
         (boolean)
       ] @comment.doc))
-  (.match? @__attribute__ "^(moduledoc|typedoc|doc)$"))
+  (#match? @__attribute__ "^(moduledoc|typedoc|doc)$"))
 
 (comment) @comment
 
@@ -150,4 +150,4 @@
 ((sigil
   (sigil_name) @_sigil_name
   (quoted_content) @embedded)
- (.eq? @_sigil_name "H"))
+ (#eq? @_sigil_name "H"))

crates/zed/src/languages/elixir/outline.scm 🔗

@@ -1,7 +1,7 @@
 (call
   target: (identifier) @context
   (arguments (alias) @name)
-  (.match? @context "^(defmodule|defprotocol)$")) @item
+  (#match? @context "^(defmodule|defprotocol)$")) @item
 
 (call
   target: (identifier) @context
@@ -23,4 +23,4 @@
                 ")" @context.extra))
         operator: "when")
     ])
-  (.match? @context "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item
+  (#match? @context "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item

crates/zed/src/languages/erb/injections.scm 🔗

@@ -1,7 +1,7 @@
 ((code) @content
- (.set! "language" "ruby")
- (.set! "combined"))
+ (#set! "language" "ruby")
+ (#set! "combined"))
 
 ((content) @content
- (.set! "language" "html")
- (.set! "combined"))
+ (#set! "language" "html")
+ (#set! "combined"))

crates/zed/src/languages/glsl/highlights.scm 🔗

@@ -74,7 +74,7 @@
 (sized_type_specifier) @type
 
 ((identifier) @constant
-    (.match? @constant "^[A-Z][A-Z\\d_]*$"))
+ (#match? @constant "^[A-Z][A-Z\\d_]*$"))
 
 (identifier) @variable
 
@@ -114,5 +114,5 @@
 
 (
   (identifier) @variable.builtin
-  (.match? @variable.builtin "^gl_")
+  (#match? @variable.builtin "^gl_")
 )

crates/zed/src/languages/heex/injections.scm 🔗

@@ -5,9 +5,9 @@
       (expression_value)
       (ending_expression_value)
     ] @content)
-  (.set! language "elixir")
-  (.set! combined)
+  (#set! language "elixir")
+  (#set! combined)
 )
 
 ((expression (expression_value) @content)
- (.set! language "elixir"))
+ (#set! language "elixir"))

crates/zed/src/languages/html/injections.scm 🔗

@@ -1,7 +1,7 @@
 (script_element
   (raw_text) @content
-  (.set! "language" "javascript"))
+  (#set! "language" "javascript"))
 
 (style_element
   (raw_text) @content
-  (.set! "language" "css"))
+  (#set! "language" "css"))

crates/zed/src/languages/javascript/highlights.scm 🔗

@@ -44,7 +44,7 @@
 ; Special identifiers
 
 ((identifier) @type
-    (.match? @type "^[A-Z]"))
+ (#match? @type "^[A-Z]"))
 (type_identifier) @type
 (predefined_type) @type.builtin
 
@@ -53,7 +53,7 @@
   (shorthand_property_identifier)
   (shorthand_property_identifier_pattern)
  ] @constant
-(.match? @constant "^_*[A-Z_][A-Z\\d_]*$"))
+ (#match? @constant "^_*[A-Z_][A-Z\\d_]*$"))
 
 ; Literals
 
@@ -214,4 +214,4 @@
   "type"
   "readonly"
   "override"
-] @keyword
+] @keyword

crates/zed/src/languages/lua/highlights.scm 🔗

@@ -127,7 +127,7 @@
 (identifier) @variable
 
 ((identifier) @variable.special
- (.eq? @variable.special "self"))
+ (#eq? @variable.special "self"))
 
 (variable_list
    attribute: (attribute
@@ -137,7 +137,7 @@
 ;; Constants
 
 ((identifier) @constant
- (.match? @constant "^[A-Z][A-Z_0-9]*$"))
+ (#match? @constant "^[A-Z][A-Z_0-9]*$"))
 
 (vararg_expression) @constant
 
@@ -158,7 +158,7 @@
 [
   "{"
   "}"
-] @method.constructor)
+] @constructor)
 
 ;; Functions
 
@@ -180,7 +180,7 @@
 
 (function_call
   (identifier) @function.builtin
-  (.any-of? @function.builtin
+  (#any-of? @function.builtin
     ;; built-in functions in Lua 5.1
     "assert" "collectgarbage" "dofile" "error" "getfenv" "getmetatable" "ipairs"
     "load" "loadfile" "loadstring" "module" "next" "pairs" "pcall" "print"
@@ -195,4 +195,4 @@
 
 (number) @number
 
-(string) @string
+(string) @string

crates/zed/src/languages/php/highlights.scm 🔗

@@ -43,15 +43,15 @@
 (relative_scope) @variable.builtin
 
 ((name) @constant
-    (.match? @constant "^_?[A-Z][A-Z\\d_]+$"))
+ (#match? @constant "^_?[A-Z][A-Z\\d_]+$"))
 ((name) @constant.builtin
- (.match? @constant.builtin "^__[A-Z][A-Z\d_]+__$"))
+ (#match? @constant.builtin "^__[A-Z][A-Z\d_]+__$"))
 
-((name) @method.constructor
-(.match? @method.constructor "^[A-Z]"))
+((name) @constructor
+ (#match? @constructor "^[A-Z]"))
 
 ((name) @variable.builtin
- (.eq? @variable.builtin "this"))
+ (#eq? @variable.builtin "this"))
 
 (variable_name) @variable
 

crates/zed/src/languages/python/highlights.scm 🔗

@@ -18,16 +18,16 @@
 ; Identifier naming conventions
 
 ((identifier) @type
-    (.match? @type "^[A-Z]"))
+ (#match? @type "^[A-Z]"))
 
 ((identifier) @constant
-    (.match? @constant "^_*[A-Z][A-Z\\d_]*$"))
+ (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
 
 ; Builtin functions
 
 ((call
   function: (identifier) @function.builtin)
- (.match?
+ (#match?
    @function.builtin
    "^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__)$"))
 
@@ -122,4 +122,4 @@
   "yield"
   "match"
   "case"
-] @keyword
+] @keyword

crates/zed/src/languages/racket/highlights.scm 🔗

@@ -22,7 +22,7 @@
 (lang_name) @variable.special
 
 ((symbol) @operator
-    (.match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$"))
+ (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$"))
 
 (list
   .
@@ -31,9 +31,10 @@
 (list
   .
   (symbol) @keyword
-  (.match? @keyword
+  (#match? @keyword

crates/zed/src/languages/ruby/brackets.scm 🔗

@@ -11,4 +11,4 @@
 (begin "begin" @open "end" @close)
 (module "module" @open "end" @close)
 (_ . "def" @open "end" @close)
-(_ . "class" @open "end" @close)
+(_ . "class" @open "end" @close)

crates/zed/src/languages/ruby/highlights.scm 🔗

@@ -33,12 +33,12 @@
 (identifier) @variable
 
 ((identifier) @keyword
-    (.match? @keyword "^(private|protected|public)$"))
+ (#match? @keyword "^(private|protected|public)$"))
 
 ; Function calls
 
 ((identifier) @function.method.builtin
-    (.eq? @function.method.builtin "require"))
+ (#eq? @function.method.builtin "require"))
 
 "defined?" @function.method.builtin
 
@@ -60,7 +60,7 @@
 ] @property
 
 ((identifier) @constant.builtin
- (.match? @constant.builtin "^__(FILE|LINE|ENCODING)__$"))
+ (#match? @constant.builtin "^__(FILE|LINE|ENCODING)__$"))
 
 (file) @constant.builtin
 (line) @constant.builtin
@@ -71,7 +71,7 @@
 ) @constant.builtin
 
 ((constant) @constant
- (.match? @constant "^[A-Z\\d_]+$"))
+ (#match? @constant "^[A-Z\\d_]+$"))
 
 (constant) @type
 

crates/zed/src/languages/rust/highlights.scm 🔗

@@ -38,11 +38,11 @@
 
 ; Assume uppercase names are types/enum-constructors
 ((identifier) @type
-    (.match? @type "^[A-Z]"))
+ (#match? @type "^[A-Z]"))
 
 ; Assume all-caps names are constants
 ((identifier) @constant
-    (.match? @constant "^_*[A-Z][A-Z\\d_]*$"))
+ (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
 
 [
   "("

crates/zed/src/languages/rust/injections.scm 🔗

@@ -1,7 +1,7 @@
 (macro_invocation
   (token_tree) @content
-  (.set! "language" "rust"))
+  (#set! "language" "rust"))
 
 (macro_rule
   (token_tree) @content
-  (.set! "language" "rust"))
+  (#set! "language" "rust"))

crates/zed/src/languages/scheme/highlights.scm 🔗

@@ -14,7 +14,7 @@
  (directive)] @comment
 
 ((symbol) @operator
-    (.match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$"))
+ (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$"))
 
 (list
   .
@@ -23,6 +23,6 @@
 (list
   .
   (symbol) @keyword
-  (.match? @keyword
+  (#match? @keyword
    "^(define-syntax|let\\*|lambda|λ|case|=>|quote-splicing|unquote-splicing|set!|let|letrec|letrec-syntax|let-values|let\\*-values|do|else|define|cond|syntax-rules|unquote|begin|quote|let-syntax|and|if|quasiquote|letrec|delay|or|when|unless|identifier-syntax|assert|library|export|import|rename|only|except|prefix)$"
    ))

crates/zed/src/languages/svelte/injections.scm 🔗

@@ -2,27 +2,27 @@
 ; --------------
 (script_element
   (raw_text) @content
-  (.set! "language" "javascript"))
+  (#set! "language" "javascript"))
 
  ((script_element
      (start_tag
        (attribute
          (quoted_attribute_value (attribute_value) @_language)))
       (raw_text) @content)
-    (.eq? @_language "ts")
-    (.set! "language" "typescript"))
+    (#eq? @_language "ts")
+    (#set! "language" "typescript"))
 
 ((script_element
     (start_tag
         (attribute
         (quoted_attribute_value (attribute_value) @_language)))
     (raw_text) @content)
-  (.eq? @_language "typescript")
-  (.set! "language" "typescript"))
+  (#eq? @_language "typescript")
+  (#set! "language" "typescript"))
 
 (style_element
   (raw_text) @content
-  (.set! "language" "css"))
+  (#set! "language" "css"))
 
 ((raw_text_expr) @content
-    (.set! "language" "javascript"))
+  (#set! "language" "javascript"))

crates/zed/src/languages/typescript/highlights.scm 🔗

@@ -43,11 +43,11 @@
 
 ; Special identifiers
 
-((identifier) @method.constructor
-    (.match? @method.constructor "^[A-Z]"))
+((identifier) @constructor
+ (#match? @constructor "^[A-Z]"))
 
 ((identifier) @type
-    (.match? @type "^[A-Z]"))
+ (#match? @type "^[A-Z]"))
 (type_identifier) @type
 (predefined_type) @type.builtin
 
@@ -56,7 +56,7 @@
   (shorthand_property_identifier)
   (shorthand_property_identifier_pattern)
  ] @constant
-(.match? @constant "^_*[A-Z_][A-Z\\d_]*$"))
+ (#match? @constant "^_*[A-Z_][A-Z\\d_]*$"))
 
 ; Literals
 
@@ -218,4 +218,4 @@
   "type"
   "readonly"
   "override"
-] @keyword
+] @keyword

styles/package.json 🔗

@@ -8,7 +8,6 @@
         "build-licenses": "ts-node ./src/build_licenses.ts",
         "build-tokens": "ts-node ./src/build_tokens.ts",
         "build-types": "ts-node ./src/build_types.ts",
-        "generate-syntax": "ts-node ./src/types/extract_syntax_types.ts",
         "test": "vitest"
     },
     "author": "Zed Industries (https://github.com/zed-industries/)",

styles/src/build_themes.ts 🔗

@@ -21,7 +21,9 @@ function clear_themes(theme_directory: string) {
     }
 }
 
-const all_themes: Theme[] = themes.map((theme) => create_theme(theme))
+const all_themes: Theme[] = themes.map((theme) =>
+    create_theme(theme)
+)
 
 function write_themes(themes: Theme[], output_directory: string) {
     clear_themes(output_directory)
@@ -32,7 +34,10 @@ function write_themes(themes: Theme[], output_directory: string) {
         const style_tree = app()
         const style_tree_json = JSON.stringify(style_tree, null, 2)
         const temp_path = path.join(temp_directory, `${theme.name}.json`)
-        const out_path = path.join(output_directory, `${theme.name}.json`)
+        const out_path = path.join(
+            output_directory,
+            `${theme.name}.json`
+        )
         fs.writeFileSync(temp_path, style_tree_json)
         fs.renameSync(temp_path, out_path)
         console.log(`- ${out_path} created`)

styles/src/build_tokens.ts 🔗

@@ -83,6 +83,8 @@ function write_tokens(themes: Theme[], tokens_directory: string) {
     console.log(`- ${METADATA_FILE} created`)
 }
 
-const all_themes: Theme[] = themes.map((theme) => create_theme(theme))
+const all_themes: Theme[] = themes.map((theme) =>
+    create_theme(theme)
+)
 
 write_tokens(all_themes, TOKENS_DIRECTORY)

styles/src/component/icon_button.ts 🔗

@@ -10,7 +10,10 @@ export type Margin = {
 }
 
 interface IconButtonOptions {
-    layer?: Theme["lowest"] | Theme["middle"] | Theme["highest"]
+    layer?:
+    | Theme["lowest"]
+    | Theme["middle"]
+    | Theme["highest"]
     color?: keyof Theme["lowest"]
     margin?: Partial<Margin>
 }

styles/src/component/tab_bar_button.ts 🔗

@@ -12,47 +12,44 @@ type TabBarButtonProps = TabBarButtonOptions & {
     state?: Partial<Record<InteractiveState, Partial<TabBarButtonOptions>>>
 }
 
-export function tab_bar_button(
-    theme: Theme,
-    { icon, color = "base" }: TabBarButtonProps
-) {
+export function tab_bar_button(theme: Theme, { icon, color = "base" }: TabBarButtonProps) {
     const button_spacing = 8
 
-    return interactive({
-        base: {
-            icon: {
-                color: foreground(theme.middle, color),
-                asset: icon,
-                dimensions: {
-                    width: 15,
-                    height: 15,
+    return (
+        interactive({
+            base: {
+                icon: {
+                    color: foreground(theme.middle, color),
+                    asset: icon,
+                    dimensions: {
+                        width: 15,
+                        height: 15,
+                    },
                 },
-            },
-            container: {
-                corner_radius: 4,
-                padding: {
-                    top: 4,
-                    bottom: 4,
-                    left: 4,
-                    right: 4,
-                },
-                margin: {
-                    left: button_spacing / 2,
-                    right: button_spacing / 2,
-                },
-            },
-        },
-        state: {
-            hovered: {
                 container: {
-                    background: background(theme.middle, color, "hovered"),
+                    corner_radius: 4,
+                    padding: {
+                        top: 4, bottom: 4, left: 4, right: 4
+                    },
+                    margin: {
+                        left: button_spacing / 2,
+                        right: button_spacing / 2,
+                    },
                 },
             },
-            clicked: {
-                container: {
-                    background: background(theme.middle, color, "pressed"),
+            state: {
+                hovered: {
+                    container: {
+                        background: background(theme.middle, color, "hovered"),
+
+                    }
+                },
+                clicked: {
+                    container: {
+                        background: background(theme.middle, color, "pressed"),
+                    }
                 },
             },
-        },
-    })
+        })
+    )
 }

styles/src/component/text_button.ts 🔗

@@ -9,7 +9,10 @@ import { useTheme, Theme } from "../theme"
 import { Margin } from "./icon_button"
 
 interface TextButtonOptions {
-    layer?: Theme["lowest"] | Theme["middle"] | Theme["highest"]
+    layer?:
+    | Theme["lowest"]
+    | Theme["middle"]
+    | Theme["highest"]
     color?: keyof Theme["lowest"]
     margin?: Partial<Margin>
     text_properties?: TextProperties

styles/src/style_tree/app.ts 🔗

@@ -57,6 +57,6 @@ export default function app(): any {
         tooltip: tooltip(),
         terminal: terminal(),
         assistant: assistant(),
-        feedback: feedback(),
+        feedback: feedback()
     }
 }

styles/src/style_tree/assistant.ts 🔗

@@ -8,48 +8,50 @@ type RoleCycleButton = TextStyle & {
 }
 // TODO: Replace these with zed types
 type RemainingTokens = TextStyle & {
-    background: string
-    margin: { top: number; right: number }
+    background: string,
+    margin: { top: number, right: number },
     padding: {
-        right: number
-        left: number
-        top: number
-        bottom: number
-    }
-    corner_radius: number
+        right: number,
+        left: number,
+        top: number,
+        bottom: number,
+    },
+    corner_radius: number,
 }
 
 export default function assistant(): any {
     const theme = useTheme()
 
-    const interactive_role = (
-        color: StyleSets
-    ): Interactive<RoleCycleButton> => {
-        return interactive({
-            base: {
-                ...text(theme.highest, "sans", color, { size: "sm" }),
-            },
-            state: {
-                hovered: {
+    const interactive_role = (color: StyleSets): Interactive<RoleCycleButton> => {
+        return (
+            interactive({
+                base: {
                     ...text(theme.highest, "sans", color, { size: "sm" }),
-                    background: background(theme.highest, color, "hovered"),
                 },
-                clicked: {
-                    ...text(theme.highest, "sans", color, { size: "sm" }),
-                    background: background(theme.highest, color, "pressed"),
+                state: {
+                    hovered: {
+                        ...text(theme.highest, "sans", color, { size: "sm" }),
+                        background: background(theme.highest, color, "hovered"),
+                    },
+                    clicked: {
+                        ...text(theme.highest, "sans", color, { size: "sm" }),
+                        background: background(theme.highest, color, "pressed"),
+                    }
                 },
-            },
-        })
+            })
+        )
     }
 
     const tokens_remaining = (color: StyleSets): RemainingTokens => {
-        return {
-            ...text(theme.highest, "mono", color, { size: "xs" }),
-            background: background(theme.highest, "on", "default"),
-            margin: { top: 12, right: 20 },
-            padding: { right: 4, left: 4, top: 1, bottom: 1 },
-            corner_radius: 6,
-        }
+        return (
+            {
+                ...text(theme.highest, "mono", color, { size: "xs" }),
+                background: background(theme.highest, "on", "default"),
+                margin: { top: 12, right: 20 },
+                padding: { right: 4, left: 4, top: 1, bottom: 1 },
+                corner_radius: 6,
+            }
+        )
     }
 
     return {
@@ -91,10 +93,7 @@ export default function assistant(): any {
                 base: {
                     background: background(theme.middle),
                     padding: { top: 4, bottom: 4 },
-                    border: border(theme.middle, "default", {
-                        top: true,
-                        overlay: true,
-                    }),
+                    border: border(theme.middle, "default", { top: true, overlay: true }),
                 },
                 state: {
                     hovered: {
@@ -102,7 +101,7 @@ export default function assistant(): any {
                     },
                     clicked: {
                         background: background(theme.middle, "pressed"),
-                    },
+                    }
                 },
             }),
             saved_at: {

styles/src/style_tree/editor.ts 🔗

@@ -9,9 +9,9 @@ import {
 } from "./components"
 import hover_popover from "./hover_popover"
 
+import { build_syntax } from "../theme/syntax"
 import { interactive, toggleable } from "../element"
 import { useTheme } from "../theme"
-import chroma from "chroma-js"
 
 export default function editor(): any {
     const theme = useTheme()
@@ -48,28 +48,16 @@ export default function editor(): any {
         }
     }
 
+    const syntax = build_syntax()
+
     return {
-        text_color: theme.syntax.primary.color,
+        text_color: syntax.primary.color,
         background: background(layer),
         active_line_background: with_opacity(background(layer, "on"), 0.75),
         highlighted_line_background: background(layer, "on"),
         // Inline autocomplete suggestions, Co-pilot suggestions, etc.
-        hint: chroma
-            .mix(
-                theme.ramps.neutral(0.6).hex(),
-                theme.ramps.blue(0.4).hex(),
-                0.45,
-                "lch"
-            )
-            .hex(),
-        suggestion: chroma
-            .mix(
-                theme.ramps.neutral(0.4).hex(),
-                theme.ramps.blue(0.4).hex(),
-                0.45,
-                "lch"
-            )
-            .hex(),
+        hint: syntax.hint,
+        suggestion: syntax.predictive,
         code_actions: {
             indicator: toggleable({
                 base: interactive({
@@ -267,8 +255,8 @@ export default function editor(): any {
         invalid_warning_diagnostic: diagnostic(theme.middle, "base"),
         hover_popover: hover_popover(),
         link_definition: {
-            color: theme.syntax.link_uri.color,
-            underline: theme.syntax.link_uri.underline,
+            color: syntax.link_uri.color,
+            underline: syntax.link_uri.underline,
         },
         jump_icon: interactive({
             base: {
@@ -318,7 +306,7 @@ export default function editor(): any {
                     ? with_opacity(theme.ramps.green(0.5).hex(), 0.8)
                     : with_opacity(theme.ramps.green(0.4).hex(), 0.8),
             },
-            selections: foreground(layer, "accent"),
+            selections: foreground(layer, "accent")
         },
         composition_mark: {
             underline: {
@@ -326,6 +314,6 @@ export default function editor(): any {
                 color: border_color(layer),
             },
         },
-        syntax: theme.syntax,
+        syntax,
     }
 }

styles/src/style_tree/feedback.ts 🔗

@@ -37,7 +37,7 @@ export default function feedback(): any {
                     ...text(theme.highest, "mono", "on", "disabled"),
                     background: background(theme.highest, "on", "disabled"),
                     border: border(theme.highest, "on", "disabled"),
-                },
+                }
             },
         }),
         button_margin: 8,

styles/src/style_tree/project_panel.ts 🔗

@@ -64,17 +64,17 @@ export default function project_panel(): any {
         const unselected_default_style = merge(
             base_properties,
             unselected?.default ?? {},
-            {}
+            {},
         )
         const unselected_hovered_style = merge(
             base_properties,
             { background: background(theme.middle, "hovered") },
-            unselected?.hovered ?? {}
+            unselected?.hovered ?? {},
         )
         const unselected_clicked_style = merge(
             base_properties,
             { background: background(theme.middle, "pressed") },
-            unselected?.clicked ?? {}
+            unselected?.clicked ?? {},
         )
         const selected_default_style = merge(
             base_properties,
@@ -82,7 +82,7 @@ export default function project_panel(): any {
                 background: background(theme.lowest),
                 text: text(theme.lowest, "sans", { size: "sm" }),
             },
-            selected_style?.default ?? {}
+            selected_style?.default ?? {},
         )
         const selected_hovered_style = merge(
             base_properties,
@@ -90,7 +90,7 @@ export default function project_panel(): any {
                 background: background(theme.lowest, "hovered"),
                 text: text(theme.lowest, "sans", { size: "sm" }),
             },
-            selected_style?.hovered ?? {}
+            selected_style?.hovered ?? {},
         )
         const selected_clicked_style = merge(
             base_properties,
@@ -98,7 +98,7 @@ export default function project_panel(): any {
                 background: background(theme.lowest, "pressed"),
                 text: text(theme.lowest, "sans", { size: "sm" }),
             },
-            selected_style?.clicked ?? {}
+            selected_style?.clicked ?? {},
         )
 
         return toggleable({
@@ -175,7 +175,7 @@ export default function project_panel(): any {
                 default: {
                     icon_color: foreground(theme.middle, "variant"),
                 },
-            }
+            },
         ),
         cut_entry: entry(
             {
@@ -190,7 +190,7 @@ export default function project_panel(): any {
                         size: "sm",
                     }),
                 },
-            }
+            },
         ),
         filename_editor: {
             background: background(theme.middle, "on"),

styles/src/style_tree/status_bar.ts 🔗

@@ -34,14 +34,10 @@ export default function status_bar(): any {
             ...text(layer, "mono", "variant", { size: "xs" }),
         },
         active_language: text_button({
-            color: "variant",
-        }),
-        auto_update_progress_message: text(layer, "sans", "variant", {
-            size: "xs",
-        }),
-        auto_update_done_message: text(layer, "sans", "variant", {
-            size: "xs",
+            color: "variant"
         }),
+        auto_update_progress_message: text(layer, "sans", "variant", { size: "xs" }),
+        auto_update_done_message: text(layer, "sans", "variant", { size: "xs" }),
         lsp_status: interactive({
             base: {
                 ...diagnostic_status_container,

styles/src/style_tree/titlebar.ts 🔗

@@ -183,10 +183,10 @@ export function titlebar(): any {
         project_name_divider: text(theme.lowest, "sans", "variant"),
 
         project_menu_button: toggleable_text_button(theme, {
-            color: "base",
+            color: 'base',
         }),
         git_menu_button: toggleable_text_button(theme, {
-            color: "variant",
+            color: 'variant',
         }),
 
         // Collaborators

styles/src/theme/create_theme.ts 🔗

@@ -1,28 +1,28 @@
 import { Scale, Color } from "chroma-js"
+import { Syntax, ThemeSyntax, SyntaxHighlightStyle } from "./syntax"
+export { Syntax, ThemeSyntax, SyntaxHighlightStyle }
 import {
     ThemeConfig,
     ThemeAppearance,
     ThemeConfigInputColors,
 } from "./theme_config"
 import { get_ramps } from "./ramps"
-import { syntaxStyle } from "./syntax"
-import { Syntax } from "../types/syntax"
 
 export interface Theme {
     name: string
     is_light: boolean
 
     /**
-     * App background, other elements that should sit directly on top of the background.
-     */
+    * App background, other elements that should sit directly on top of the background.
+    */
     lowest: Layer
     /**
-     * Panels, tabs, other UI surfaces that sit on top of the background.
-     */
+    * Panels, tabs, other UI surfaces that sit on top of the background.
+    */
     middle: Layer
     /**
-     * Editors like code buffers, conversation editors, etc.
-     */
+    * Editors like code buffers, conversation editors, etc.
+    */
     highest: Layer
 
     ramps: RampSet
@@ -31,7 +31,7 @@ export interface Theme {
     modal_shadow: Shadow
 
     players: Players
-    syntax: Syntax
+    syntax?: Partial<ThemeSyntax>
 }
 
 export interface Meta {
@@ -115,7 +115,12 @@ export interface Style {
 }
 
 export function create_theme(theme: ThemeConfig): Theme {
-    const { name, appearance, input_color } = theme
+    const {
+        name,
+        appearance,
+        input_color,
+        override: { syntax },
+    } = theme
 
     const is_light = appearance === ThemeAppearance.Light
     const color_ramps: ThemeConfigInputColors = input_color
@@ -157,11 +162,6 @@ export function create_theme(theme: ThemeConfig): Theme {
         "7": player(ramps.yellow),
     }
 
-    const syntax = syntaxStyle(
-        ramps,
-        theme.override.syntax ? theme.override.syntax : {}
-    )
-
     return {
         name,
         is_light,

styles/src/theme/syntax.ts 🔗

@@ -1,45 +1,325 @@
 import deepmerge from "deepmerge"
-import { font_weights, ThemeConfigInputSyntax, RampSet } from "../common"
-import { Syntax, SyntaxHighlightStyle, allSyntaxKeys } from "../types/syntax"
-
-// Apply defaults to any missing syntax properties that are not defined manually
-function apply_defaults(
-    ramps: RampSet,
-    syntax_highlights: Partial<Syntax>
-): Syntax {
-    const restKeys: (keyof Syntax)[] = allSyntaxKeys.filter(
-        (key) => !syntax_highlights[key]
-    )
+import { FontWeight, font_weights, useTheme } from "../common"
+import chroma from "chroma-js"
 
-    const completeSyntax: Syntax = {} as Syntax
+export interface SyntaxHighlightStyle {
+    color?: string
+    weight?: FontWeight
+    underline?: boolean
+    italic?: boolean
+}
 
-    const defaults: SyntaxHighlightStyle = {
-        color: ramps.neutral(1).hex(),
-    }
+export interface Syntax {
+    // == Text Styles ====== /
+    comment: SyntaxHighlightStyle
+    // elixir: doc comment
+    "comment.doc": SyntaxHighlightStyle
+    primary: SyntaxHighlightStyle
+    predictive: SyntaxHighlightStyle
+    hint: SyntaxHighlightStyle
 
-    for (const key of restKeys) {
-        {
-            completeSyntax[key] = {
-                ...defaults,
-            }
+    // === Formatted Text ====== /
+    emphasis: SyntaxHighlightStyle
+    "emphasis.strong": SyntaxHighlightStyle
+    title: SyntaxHighlightStyle
+    link_uri: SyntaxHighlightStyle
+    link_text: SyntaxHighlightStyle
+    /** md: indented_code_block, fenced_code_block, code_span */
+    "text.literal": SyntaxHighlightStyle
+
+    // == Punctuation ====== /
+    punctuation: SyntaxHighlightStyle
+    /** Example: `(`, `[`, `{`...*/
+    "punctuation.bracket": SyntaxHighlightStyle
+    /**., ;*/
+    "punctuation.delimiter": SyntaxHighlightStyle
+    // js, ts: ${, } in a template literal
+    // yaml: *, &, ---, ...
+    "punctuation.special": SyntaxHighlightStyle
+    // md: list_marker_plus, list_marker_dot, etc
+    "punctuation.list_marker": SyntaxHighlightStyle
+
+    // == Strings ====== /
+
+    string: SyntaxHighlightStyle
+    // css: color_value
+    // js: this, super
+    // toml: offset_date_time, local_date_time...
+    "string.special": SyntaxHighlightStyle
+    // elixir: atom, quoted_atom, keyword, quoted_keyword
+    // ruby: simple_symbol, delimited_symbol...
+    "string.special.symbol"?: SyntaxHighlightStyle
+    // elixir, python, yaml...: escape_sequence
+    "string.escape"?: SyntaxHighlightStyle
+    // Regular expressions
+    "string.regex"?: SyntaxHighlightStyle
+
+    // == Types ====== /
+    // We allow Function here because all JS objects literals have this property
+    constructor: SyntaxHighlightStyle | Function // eslint-disable-line  @typescript-eslint/ban-types
+    variant: SyntaxHighlightStyle
+    type: SyntaxHighlightStyle
+    // js: predefined_type
+    "type.builtin"?: SyntaxHighlightStyle
+
+    // == Values
+    variable: SyntaxHighlightStyle
+    // this, ...
+    // css: -- (var(--foo))
+    // lua: self
+    "variable.special"?: SyntaxHighlightStyle
+    // c: statement_identifier,
+    label: SyntaxHighlightStyle
+    // css: tag_name, nesting_selector, universal_selector...
+    tag: SyntaxHighlightStyle
+    // css: attribute, pseudo_element_selector (tag_name),
+    attribute: SyntaxHighlightStyle
+    // css: class_name, property_name, namespace_name...
+    property: SyntaxHighlightStyle
+    // true, false, null, nullptr
+    constant: SyntaxHighlightStyle
+    // css: @media, @import, @supports...
+    // js: declare, implements, interface, keyof, public...
+    keyword: SyntaxHighlightStyle
+    // note: js enum is currently defined as a keyword
+    enum: SyntaxHighlightStyle
+    // -, --, ->, !=, &&, ||, <=...
+    operator: SyntaxHighlightStyle
+    number: SyntaxHighlightStyle
+    boolean: SyntaxHighlightStyle
+    // elixir: __MODULE__, __DIR__, __ENV__, etc
+    // go: nil, iota
+    "constant.builtin"?: SyntaxHighlightStyle
+
+    // == Functions ====== /
+
+    function: SyntaxHighlightStyle
+    // lua: assert, error, loadfile, tostring, unpack...
+    "function.builtin"?: SyntaxHighlightStyle
+    // go: call_expression, method_declaration
+    // js: call_expression, method_definition, pair (key, arrow function)
+    // rust: function_item name: (identifier)
+    "function.definition"?: SyntaxHighlightStyle
+    // rust: macro_definition name: (identifier)
+    "function.special.definition"?: SyntaxHighlightStyle
+    "function.method"?: SyntaxHighlightStyle
+    // ruby: identifier/"defined?" // Nate note: I don't fully understand this one.
+    "function.method.builtin"?: SyntaxHighlightStyle
+
+    // == Unsorted ====== /
+    // lua: hash_bang_line
+    preproc: SyntaxHighlightStyle
+    // elixir, python: interpolation (ex: foo in ${foo})
+    // js: template_substitution
+    embedded: SyntaxHighlightStyle
+}
+
+export type ThemeSyntax = Partial<Syntax>
+
+const default_syntax_highlight_style: Omit<SyntaxHighlightStyle, "color"> = {
+    weight: "normal",
+    underline: false,
+    italic: false,
+}
+
+function build_default_syntax(): Syntax {
+    const theme = useTheme()
+
+    // Make a temporary object that is allowed to be missing
+    // the "color" property for each style
+    const syntax: {
+        [key: string]: Omit<SyntaxHighlightStyle, "color">
+    } = {}
+
+    // then spread the default to each style
+    for (const key of Object.keys({} as Syntax)) {
+        syntax[key as keyof Syntax] = {
+            ...default_syntax_highlight_style,
         }
     }
 
-    const mergedBaseSyntax = Object.assign(completeSyntax, syntax_highlights)
+    // Mix the neutral and blue colors to get a
+    // predictive color distinct from any other color in the theme
+    const predictive = chroma
+        .mix(
+            theme.ramps.neutral(0.4).hex(),
+            theme.ramps.blue(0.4).hex(),
+            0.45,
+            "lch"
+        )
+        .hex()
+    // Mix the neutral and green colors to get a
+    // hint color distinct from any other color in the theme
+    const hint = chroma
+        .mix(
+            theme.ramps.neutral(0.6).hex(),
+            theme.ramps.blue(0.4).hex(),
+            0.45,
+            "lch"
+        )
+        .hex()
 
-    return mergedBaseSyntax
+    const color = {
+        primary: theme.ramps.neutral(1).hex(),
+        comment: theme.ramps.neutral(0.71).hex(),
+        punctuation: theme.ramps.neutral(0.86).hex(),
+        predictive: predictive,
+        hint: hint,
+        emphasis: theme.ramps.blue(0.5).hex(),
+        string: theme.ramps.orange(0.5).hex(),
+        function: theme.ramps.yellow(0.5).hex(),
+        type: theme.ramps.cyan(0.5).hex(),
+        constructor: theme.ramps.blue(0.5).hex(),
+        variant: theme.ramps.blue(0.5).hex(),
+        property: theme.ramps.blue(0.5).hex(),
+        enum: theme.ramps.orange(0.5).hex(),
+        operator: theme.ramps.orange(0.5).hex(),
+        number: theme.ramps.green(0.5).hex(),
+        boolean: theme.ramps.green(0.5).hex(),
+        constant: theme.ramps.green(0.5).hex(),
+        keyword: theme.ramps.blue(0.5).hex(),
+    }
+
+    // Then assign colors and use Syntax to enforce each style getting it's own color
+    const default_syntax: Syntax = {
+        ...syntax,
+        comment: {
+            color: color.comment,
+        },
+        "comment.doc": {
+            color: color.comment,
+        },
+        primary: {
+            color: color.primary,
+        },
+        predictive: {
+            color: color.predictive,
+            italic: true,
+        },
+        hint: {
+            color: color.hint,
+            weight: font_weights.bold,
+        },
+        emphasis: {
+            color: color.emphasis,
+        },
+        "emphasis.strong": {
+            color: color.emphasis,
+            weight: font_weights.bold,
+        },
+        title: {
+            color: color.primary,
+            weight: font_weights.bold,
+        },
+        link_uri: {
+            color: theme.ramps.green(0.5).hex(),
+            underline: true,
+        },
+        link_text: {
+            color: theme.ramps.orange(0.5).hex(),
+            italic: true,
+        },
+        "text.literal": {
+            color: color.string,
+        },
+        punctuation: {
+            color: color.punctuation,
+        },
+        "punctuation.bracket": {
+            color: color.punctuation,
+        },
+        "punctuation.delimiter": {
+            color: color.punctuation,
+        },
+        "punctuation.special": {
+            color: theme.ramps.neutral(0.86).hex(),
+        },
+        "punctuation.list_marker": {
+            color: color.punctuation,
+        },
+        string: {
+            color: color.string,
+        },
+        "string.special": {
+            color: color.string,
+        },
+        "string.special.symbol": {
+            color: color.string,
+        },
+        "string.escape": {
+            color: color.comment,
+        },
+        "string.regex": {
+            color: color.string,
+        },
+        constructor: {
+            color: theme.ramps.blue(0.5).hex(),
+        },
+        variant: {
+            color: theme.ramps.blue(0.5).hex(),
+        },
+        type: {
+            color: color.type,
+        },
+        variable: {
+            color: color.primary,
+        },
+        label: {
+            color: theme.ramps.blue(0.5).hex(),
+        },
+        tag: {
+            color: theme.ramps.blue(0.5).hex(),
+        },
+        attribute: {
+            color: theme.ramps.blue(0.5).hex(),
+        },
+        property: {
+            color: theme.ramps.blue(0.5).hex(),
+        },
+        constant: {
+            color: color.constant,
+        },
+        keyword: {
+            color: color.keyword,
+        },
+        enum: {
+            color: color.enum,
+        },
+        operator: {
+            color: color.operator,
+        },
+        number: {
+            color: color.number,
+        },
+        boolean: {
+            color: color.boolean,
+        },
+        function: {
+            color: color.function,
+        },
+        preproc: {
+            color: color.primary,
+        },
+        embedded: {
+            color: color.primary,
+        },
+    }
+
+    return default_syntax
 }
 
-// Merge the base syntax with the theme syntax overrides
-// This is a deep merge, so any nested properties will be merged as well
-// This allows for a theme to only override a single property of a syntax highlight style
-const merge_syntax = (
-    baseSyntax: Syntax,
-    theme_syntax_overrides: ThemeConfigInputSyntax
-): Syntax => {
-    return deepmerge<Syntax, ThemeConfigInputSyntax>(
-        baseSyntax,
-        theme_syntax_overrides,
+export function build_syntax(): Syntax {
+    const theme = useTheme()
+
+    const default_syntax: Syntax = build_default_syntax()
+
+    if (!theme.syntax) {
+        return default_syntax
+    }
+
+    const syntax = deepmerge<Syntax, Partial<ThemeSyntax>>(
+        default_syntax,
+        theme.syntax,
         {
             arrayMerge: (destinationArray, sourceArray) => [
                 ...destinationArray,
@@ -47,49 +327,6 @@ const merge_syntax = (
             ],
         }
     )
-}
-
-/** Returns a complete Syntax object of the combined styles of a theme's syntax overrides and the default syntax styles */
-export const syntaxStyle = (
-    ramps: RampSet,
-    theme_syntax_overrides: ThemeConfigInputSyntax
-): Syntax => {
-    const syntax_highlights: Partial<Syntax> = {
-        comment: { color: ramps.neutral(0.71).hex() },
-        "comment.doc": { color: ramps.neutral(0.71).hex() },
-        primary: { color: ramps.neutral(1).hex() },
-        emphasis: { color: ramps.blue(0.5).hex() },
-        "emphasis.strong": {
-            color: ramps.blue(0.5).hex(),
-            weight: font_weights.bold,
-        },
-        link_uri: { color: ramps.green(0.5).hex(), underline: true },
-        link_text: { color: ramps.orange(0.5).hex(), italic: true },
-        "text.literal": { color: ramps.orange(0.5).hex() },
-        punctuation: { color: ramps.neutral(0.86).hex() },
-        "punctuation.bracket": { color: ramps.neutral(0.86).hex() },
-        "punctuation.special": { color: ramps.neutral(0.86).hex() },
-        "punctuation.delimiter": { color: ramps.neutral(0.86).hex() },
-        "punctuation.list_marker": { color: ramps.neutral(0.86).hex() },
-        string: { color: ramps.orange(0.5).hex() },
-        "string.special": { color: ramps.orange(0.5).hex() },
-        "string.special.symbol": { color: ramps.orange(0.5).hex() },
-        "string.escape": { color: ramps.neutral(0.71).hex() },
-        "string.regex": { color: ramps.orange(0.5).hex() },
-        "method.constructor": { color: ramps.blue(0.5).hex() },
-        type: { color: ramps.cyan(0.5).hex() },
-        label: { color: ramps.blue(0.5).hex() },
-        attribute: { color: ramps.blue(0.5).hex() },
-        property: { color: ramps.blue(0.5).hex() },
-        constant: { color: ramps.green(0.5).hex() },
-        keyword: { color: ramps.blue(0.5).hex() },
-        operator: { color: ramps.orange(0.5).hex() },
-        number: { color: ramps.green(0.5).hex() },
-        boolean: { color: ramps.green(0.5).hex() },
-        function: { color: ramps.yellow(0.5).hex() },
-    }
 
-    const baseSyntax = apply_defaults(ramps, syntax_highlights)
-    const mergedSyntax = merge_syntax(baseSyntax, theme_syntax_overrides)
-    return mergedSyntax
+    return syntax
 }

styles/src/theme/theme_config.ts 🔗

@@ -1,5 +1,5 @@
 import { Scale, Color } from "chroma-js"
-import { SyntaxHighlightStyle, SyntaxProperty } from "../types/syntax"
+import { Syntax } from "./syntax"
 
 interface ThemeMeta {
     /** The name of the theme */
@@ -55,9 +55,7 @@ export type ThemeConfigInputColorsKeys = keyof ThemeConfigInputColors
  * }
  * ```
  */
-export type ThemeConfigInputSyntax = Partial<
-    Record<SyntaxProperty, Partial<SyntaxHighlightStyle>>
->
+export type ThemeConfigInputSyntax = Partial<Syntax>
 
 interface ThemeConfigOverrides {
     syntax: ThemeConfigInputSyntax

styles/src/theme/tokens/theme.ts 🔗

@@ -4,13 +4,17 @@ import {
     SingleOtherToken,
     TokenTypes,
 } from "@tokens-studio/types"
-import { Shadow } from "../create_theme"
+import {
+    Shadow,
+    SyntaxHighlightStyle,
+    ThemeSyntax,
+} from "../create_theme"
 import { LayerToken, layer_token } from "./layer"
 import { PlayersToken, players_token } from "./players"
 import { color_token } from "./token"
+import { Syntax } from "../syntax"
 import editor from "../../style_tree/editor"
 import { useTheme } from "../../../src/common"
-import { Syntax, SyntaxHighlightStyle } from "../../types/syntax"
 
 interface ThemeTokens {
     name: SingleOtherToken
@@ -47,7 +51,7 @@ const modal_shadow_token = (): SingleBoxShadowToken => {
     return create_shadow_token(shadow, "modal_shadow")
 }
 
-type ThemeSyntaxColorTokens = Record<keyof Syntax, SingleColorToken>
+type ThemeSyntaxColorTokens = Record<keyof ThemeSyntax, SingleColorToken>
 
 function syntax_highlight_style_color_tokens(
     syntax: Syntax

styles/src/themes/atelier/common.ts 🔗

@@ -1,8 +1,4 @@
-import {
-    ThemeLicenseType,
-    ThemeFamilyMeta,
-    ThemeConfigInputSyntax,
-} from "../../common"
+import { ThemeLicenseType, ThemeSyntax, ThemeFamilyMeta } from "../../common"
 
 export interface Variant {
     colors: {
@@ -33,7 +29,7 @@ export const meta: ThemeFamilyMeta = {
         "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/",
 }
 
-export const build_syntax = (variant: Variant): ThemeConfigInputSyntax => {
+export const build_syntax = (variant: Variant): ThemeSyntax => {
     const { colors } = variant
     return {
         primary: { color: colors.base06 },
@@ -54,6 +50,7 @@ export const build_syntax = (variant: Variant): ThemeConfigInputSyntax => {
         property: { color: colors.base08 },
         variable: { color: colors.base06 },
         "variable.special": { color: colors.base0E },
+        variant: { color: colors.base0A },
         keyword: { color: colors.base0E },
     }
 }

styles/src/themes/ayu/common.ts 🔗

@@ -3,8 +3,8 @@ import {
     chroma,
     color_ramp,
     ThemeLicenseType,
+    ThemeSyntax,
     ThemeFamilyMeta,
-    ThemeConfigInputSyntax,
 } from "../../common"
 
 export const ayu = {
@@ -27,7 +27,7 @@ export const build_theme = (t: typeof dark, light: boolean) => {
         purple: t.syntax.constant.hex(),
     }
 
-    const syntax: ThemeConfigInputSyntax = {
+    const syntax: ThemeSyntax = {
         constant: { color: t.syntax.constant.hex() },
         "string.regex": { color: t.syntax.regexp.hex() },
         string: { color: t.syntax.string.hex() },
@@ -61,7 +61,7 @@ export const build_theme = (t: typeof dark, light: boolean) => {
     }
 }
 
-export const build_syntax = (t: typeof dark): ThemeConfigInputSyntax => {
+export const build_syntax = (t: typeof dark): ThemeSyntax => {
     return {
         constant: { color: t.syntax.constant.hex() },
         "string.regex": { color: t.syntax.regexp.hex() },

styles/src/themes/gruvbox/gruvbox-common.ts 🔗

@@ -4,8 +4,8 @@ import {
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
+    ThemeSyntax,
     ThemeFamilyMeta,
-    ThemeConfigInputSyntax,
 } from "../../common"
 
 const meta: ThemeFamilyMeta = {
@@ -214,7 +214,7 @@ const build_variant = (variant: Variant): ThemeConfig => {
         magenta: color_ramp(chroma(variant.colors.gray)),
     }
 
-    const syntax: ThemeConfigInputSyntax = {
+    const syntax: ThemeSyntax = {
         primary: { color: neutral[is_light ? 0 : 8] },
         "text.literal": { color: colors.blue },
         comment: { color: colors.gray },
@@ -229,7 +229,7 @@ const build_variant = (variant: Variant): ThemeConfig => {
         "string.special.symbol": { color: colors.aqua },
         "string.regex": { color: colors.orange },
         type: { color: colors.yellow },
-        // enum: { color: colors.orange },
+        enum: { color: colors.orange },
         tag: { color: colors.aqua },
         constant: { color: colors.yellow },
         keyword: { color: colors.red },

styles/src/themes/one/one-dark.ts 🔗

@@ -54,6 +54,7 @@ export const theme: ThemeConfig = {
         syntax: {
             boolean: { color: color.orange },
             comment: { color: color.grey },
+            enum: { color: color.red },
             "emphasis.strong": { color: color.orange },
             function: { color: color.blue },
             keyword: { color: color.purple },
@@ -72,7 +73,8 @@ export const theme: ThemeConfig = {
             "text.literal": { color: color.green },
             type: { color: color.teal },
             "variable.special": { color: color.orange },
-            "method.constructor": { color: color.blue },
+            variant: { color: color.blue },
+            constructor: { color: color.blue },
         },
     },
 }

styles/src/themes/one/one-light.ts 🔗

@@ -55,6 +55,7 @@ export const theme: ThemeConfig = {
         syntax: {
             boolean: { color: color.orange },
             comment: { color: color.grey },
+            enum: { color: color.red },
             "emphasis.strong": { color: color.orange },
             function: { color: color.blue },
             keyword: { color: color.purple },
@@ -72,6 +73,7 @@ export const theme: ThemeConfig = {
             "text.literal": { color: color.green },
             type: { color: color.teal },
             "variable.special": { color: color.orange },
+            variant: { color: color.blue },
         },
     },
 }

styles/src/themes/rose-pine/common.ts 🔗

@@ -1,4 +1,4 @@
-import { ThemeConfigInputSyntax } from "../../common"
+import { ThemeSyntax } from "../../common"
 
 export const color = {
     default: {
@@ -54,7 +54,7 @@ export const color = {
     },
 }
 
-export const syntax = (c: typeof color.default): ThemeConfigInputSyntax => {
+export const syntax = (c: typeof color.default): Partial<ThemeSyntax> => {
     return {
         comment: { color: c.muted },
         operator: { color: c.pine },

styles/src/types/extract_syntax_types.ts 🔗

@@ -1,111 +0,0 @@
-import fs from "fs"
-import path from "path"
-import readline from "readline"
-
-function escapeTypeName(name: string): string {
-    return `'${name.replace("@", "").toLowerCase()}'`
-}
-
-const generatedNote = `// This file is generated by extract_syntax_types.ts
-// Do not edit this file directly
-// It is generated from the highlight.scm files in the zed crate
-
-// To regenerate this file manually:
-//     'npm run extract-syntax-types' from ./styles`
-
-const defaultTextProperty = `    /** Default text color */
-    | 'primary'`
-
-const main = async () => {
-    const pathFromRoot = "crates/zed/src/languages"
-    const directoryPath = path.join(__dirname, "../../../", pathFromRoot)
-    const stylesMap: Record<string, Set<string>> = {}
-    const propertyLanguageMap: Record<string, Set<string>> = {}
-
-    const processFile = async (filePath: string, language: string) => {
-        const fileStream = fs.createReadStream(filePath)
-        const rl = readline.createInterface({
-            input: fileStream,
-            crlfDelay: Infinity,
-        })
-
-        for await (const line of rl) {
-            const cleanedLine = line.replace(/"@[a-zA-Z0-9_.]*"/g, "")
-            const match = cleanedLine.match(/@(\w+\.*)*/g)
-            if (match) {
-                match.forEach((property) => {
-                    const formattedProperty = escapeTypeName(property)
-                    // Only add non-empty properties
-                    if (formattedProperty !== "''") {
-                        if (!propertyLanguageMap[formattedProperty]) {
-                            propertyLanguageMap[formattedProperty] = new Set()
-                        }
-                        propertyLanguageMap[formattedProperty].add(language)
-                    }
-                })
-            }
-        }
-    }
-
-    const directories = fs
-        .readdirSync(directoryPath, { withFileTypes: true })
-        .filter((dirent) => dirent.isDirectory())
-        .map((dirent) => dirent.name)
-
-    for (const dir of directories) {
-        const highlightsFilePath = path.join(
-            directoryPath,
-            dir,
-            "highlights.scm"
-        )
-        if (fs.existsSync(highlightsFilePath)) {
-            await processFile(highlightsFilePath, dir)
-        }
-    }
-
-    for (const [language, properties] of Object.entries(stylesMap)) {
-        console.log(`${language}: ${Array.from(properties).join(", ")}`)
-    }
-
-    const sortedProperties = Object.entries(propertyLanguageMap).sort(
-        ([propA], [propB]) => propA.localeCompare(propB)
-    )
-
-    const outStream = fs.createWriteStream(path.join(__dirname, "syntax.ts"))
-    let allProperties = ""
-    const syntaxKeys = []
-    for (const [property, languages] of sortedProperties) {
-        let languagesArray = Array.from(languages)
-        const moreThanSeven = languagesArray.length > 7
-        // Limit to the first 7 languages, append "..." if more than 7
-        languagesArray = languagesArray.slice(0, 7)
-        if (moreThanSeven) {
-            languagesArray.push("...")
-        }
-        const languagesString = languagesArray.join(", ")
-        const comment = `/** ${languagesString} */`
-        allProperties += `    ${comment}\n    | ${property} \n`
-        syntaxKeys.push(property)
-    }
-    outStream.write(`${generatedNote}
-
-export type SyntaxHighlightStyle = {
-    color: string,
-    fade_out?: number,
-    italic?: boolean,
-    underline?: boolean,
-    weight?: string,
-}
-
-export type Syntax = Record<SyntaxProperty, SyntaxHighlightStyle>
-export type SyntaxOverride = Partial<Syntax>
-
-export type SyntaxProperty = \n${defaultTextProperty}\n\n${allProperties}
-
-export const allSyntaxKeys: SyntaxProperty[] = [\n    ${syntaxKeys.join(
-        ",\n    "
-    )}\n]`)
-    outStream.end()
-}
-
-main().catch(console.error)

styles/src/types/syntax.ts 🔗

@@ -1,202 +0,0 @@
-// This file is generated by extract_syntax_types.ts
-// Do not edit this file directly
-// It is generated from the highlight.scm files in the zed crate
-
-// To regenerate this file manually:
-//     'npm run extract-syntax-types' from ./styles
-
-export type SyntaxHighlightStyle = {
-    color: string
-    fade_out?: number
-    italic?: boolean
-    underline?: boolean
-    weight?: string
-}
-
-export type Syntax = Record<SyntaxProperty, SyntaxHighlightStyle>
-export type SyntaxOverride = Partial<Syntax>
-
-export type SyntaxProperty =
-    /** Default text color */
-    | "primary"
-
-    /** elixir */
-    | "__attribute__"
-    /** elixir */
-    | "__name__"
-    /** elixir */
-    | "_sigil_name"
-    /** css, heex, lua */
-    | "attribute"
-    /** javascript, lua, tsx, typescript, yaml */
-    | "boolean"
-    /** elixir */
-    | "comment.doc"
-    /** elixir */
-    | "comment.unused"
-    /** bash, c, cpp, css, elixir, elm, erb, ... */
-    | "comment"
-    /** elixir, go, javascript, lua, php, python, racket, ... */
-    | "constant.builtin"
-    /** bash, c, cpp, elixir, elm, glsl, heex, ... */
-    | "constant"
-    /** glsl */
-    | "delimiter"
-    /** bash, elixir, javascript, python, ruby, tsx, typescript */
-    | "embedded"
-    /** markdown */
-    | "emphasis.strong"
-    /** markdown */
-    | "emphasis"
-    /** go, python, racket, ruby, scheme */
-    | "escape"
-    /** lua */
-    | "field"
-    /** lua, php, python */
-    | "function.builtin"
-    /** elm, lua, rust */
-    | "function.definition"
-    /** ruby */
-    | "function.method.builtin"
-    /** go, javascript, php, python, ruby, rust, tsx, ... */
-    | "function.method"
-    /** rust */
-    | "function.special.definition"
-    /** c, cpp, glsl, rust */
-    | "function.special"
-    /** bash, c, cpp, css, elixir, elm, glsl, ... */
-    | "function"
-    /** elm */
-    | "identifier"
-    /** glsl */
-    | "keyword.function"
-    /** bash, c, cpp, css, elixir, elm, erb, ... */
-    | "keyword"
-    /** c, cpp, glsl */
-    | "label"
-    /** markdown */
-    | "link_text"
-    /** markdown */
-    | "link_uri"
-    /** lua, php, tsx, typescript */
-    | "method.constructor"
-    /** lua */
-    | "method"
-    /** heex */
-    | "module"
-    /** svelte */
-    | "none"
-    /** bash, c, cpp, css, elixir, glsl, go, ... */
-    | "number"
-    /** bash, c, cpp, css, elixir, elm, glsl, ... */
-    | "operator"
-    /** lua */
-    | "parameter"
-    /** lua */
-    | "preproc"
-    /** bash, c, cpp, css, glsl, go, html, ... */
-    | "property"
-    /** c, cpp, elixir, elm, heex, html, javascript, ... */
-    | "punctuation.bracket"
-    /** c, cpp, css, elixir, elm, heex, javascript, ... */
-    | "punctuation.delimiter"
-    /** markdown */
-    | "punctuation.list_marker"
-    /** elixir, javascript, python, ruby, tsx, typescript, yaml */
-    | "punctuation.special"
-    /** elixir */
-    | "punctuation"
-    /** glsl */
-    | "storageclass"
-    /** elixir, elm, yaml */
-    | "string.escape"
-    /** elixir, javascript, racket, ruby, tsx, typescript */
-    | "string.regex"
-    /** elixir, ruby */
-    | "string.special.symbol"
-    /** css, elixir, toml */
-    | "string.special"
-    /** bash, c, cpp, css, elixir, elm, glsl, ... */
-    | "string"
-    /** svelte */
-    | "tag.delimiter"
-    /** css, heex, php, svelte */
-    | "tag"
-    /** markdown */
-    | "text.literal"
-    /** markdown */
-    | "title"
-    /** javascript, php, rust, tsx, typescript */
-    | "type.builtin"
-    /** glsl */
-    | "type.qualifier"
-    /** c, cpp, css, elixir, elm, glsl, go, ... */
-    | "type"
-    /** glsl, php */
-    | "variable.builtin"
-    /** cpp, css, javascript, lua, racket, ruby, rust, ... */
-    | "variable.special"
-    /** c, cpp, elm, glsl, go, javascript, lua, ... */
-    | "variable"
-
-export const allSyntaxKeys: SyntaxProperty[] = [
-    "__attribute__",
-    "__name__",
-    "_sigil_name",
-    "attribute",
-    "boolean",
-    "comment.doc",
-    "comment.unused",
-    "comment",
-    "constant.builtin",
-    "constant",
-    "delimiter",
-    "embedded",
-    "emphasis.strong",
-    "emphasis",
-    "escape",
-    "field",
-    "function.builtin",
-    "function.definition",
-    "function.method.builtin",
-    "function.method",
-    "function.special.definition",
-    "function.special",
-    "function",
-    "identifier",
-    "keyword.function",
-    "keyword",
-    "label",
-    "link_text",
-    "link_uri",
-    "method.constructor",
-    "method",
-    "module",
-    "none",
-    "number",
-    "operator",
-    "parameter",
-    "preproc",
-    "property",
-    "punctuation.bracket",
-    "punctuation.delimiter",
-    "punctuation.list_marker",
-    "punctuation.special",
-    "punctuation",
-    "storageclass",
-    "string.escape",
-    "string.regex",
-    "string.special.symbol",
-    "string.special",
-    "string",
-    "tag.delimiter",
-    "tag",
-    "text.literal",
-    "title",
-    "type.builtin",
-    "type.qualifier",
-    "type",
-    "variable.builtin",
-    "variable.special",
-    "variable",
-]

styles/tsconfig.json 🔗

@@ -24,5 +24,7 @@
         "useUnknownInCatchVariables": false,
         "baseUrl": "."
     },
-    "exclude": ["node_modules"]
+    "exclude": [
+        "node_modules"
+    ]
 }