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

This reverts commit 45c635872b, reversing
changes made to f2b82369f2.
This commit is contained in:
Max Brunsfeld 2023-08-02 12:15:39 -07:00
parent b0ec05a732
commit 9e755bb855
57 changed files with 553 additions and 630 deletions

View File

@ -54,5 +54,5 @@
( (
(command (_) @constant) (command (_) @constant)
(.match? @constant "^-") (#match? @constant "^-")
) )

View File

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

View File

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

View File

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

View File

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

View File

@ -46,7 +46,7 @@
(property_name) (property_name)
(plain_value) (plain_value)
] @variable.special ] @variable.special
(.match? @variable.special "^--") (#match? @variable.special "^--")
) )
[ [

View File

@ -3,7 +3,7 @@
operator: "@" operator: "@"
operand: (call operand: (call
target: (identifier) @unary target: (identifier) @unary
(.match? @unary "^(doc)$")) (#match? @unary "^(doc)$"))
) @context ) @context
. .
(call (call
@ -18,10 +18,10 @@
target: (identifier) @name) target: (identifier) @name)
operator: "when") 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 (call
target: (identifier) @name target: (identifier) @name
(arguments (alias) @name) (arguments (alias) @name)
(.match? @name "^(defmodule|defprotocol)$")) @item (#match? @name "^(defmodule|defprotocol)$")) @item

View File

@ -54,13 +54,13 @@
(sigil_name) @__name__ (sigil_name) @__name__
quoted_start: _ @string quoted_start: _ @string
quoted_end: _ @string quoted_end: _ @string
(.match? @__name__ "^[sS]$")) @string (#match? @__name__ "^[sS]$")) @string
(sigil (sigil
(sigil_name) @__name__ (sigil_name) @__name__
quoted_start: _ @string.regex quoted_start: _ @string.regex
quoted_end: _ @string.regex quoted_end: _ @string.regex
(.match? @__name__ "^[rR]$")) @string.regex (#match? @__name__ "^[rR]$")) @string.regex
(sigil (sigil
(sigil_name) @__name__ (sigil_name) @__name__
@ -69,7 +69,7 @@
( (
(identifier) @comment.unused (identifier) @comment.unused
(.match? @comment.unused "^_") (#match? @comment.unused "^_")
) )
(call (call
@ -91,7 +91,7 @@
operator: "|>" operator: "|>"
right: (identifier)) 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 (binary_operator
operator: "|>" operator: "|>"
@ -99,15 +99,15 @@
(call (call
target: (identifier) @keyword 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 (call
target: (identifier) @keyword 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 (identifier) @constant.builtin
(.match? @constant.builtin "^(__MODULE__|__DIR__|__ENV__|__CALLER__|__STACKTRACE__)$") (#match? @constant.builtin "^(__MODULE__|__DIR__|__ENV__|__CALLER__|__STACKTRACE__)$")
) )
(unary_operator (unary_operator
@ -121,7 +121,7 @@
(sigil) (sigil)
(boolean) (boolean)
] @comment.doc)) ] @comment.doc))
(.match? @__attribute__ "^(moduledoc|typedoc|doc)$")) (#match? @__attribute__ "^(moduledoc|typedoc|doc)$"))
(comment) @comment (comment) @comment
@ -150,4 +150,4 @@
((sigil ((sigil
(sigil_name) @_sigil_name (sigil_name) @_sigil_name
(quoted_content) @embedded) (quoted_content) @embedded)
(.eq? @_sigil_name "H")) (#eq? @_sigil_name "H"))

View File

@ -3,5 +3,5 @@
((sigil ((sigil
(sigil_name) @_sigil_name (sigil_name) @_sigil_name
(quoted_content) @content) (quoted_content) @content)
(.eq? @_sigil_name "H") (#eq? @_sigil_name "H")
(.set! language "heex")) (#set! language "heex"))

View File

@ -1,7 +1,7 @@
(call (call
target: (identifier) @context target: (identifier) @context
(arguments (alias) @name) (arguments (alias) @name)
(.match? @context "^(defmodule|defprotocol)$")) @item (#match? @context "^(defmodule|defprotocol)$")) @item
(call (call
target: (identifier) @context target: (identifier) @context
@ -23,4 +23,4 @@
")" @context.extra)) ")" @context.extra))
operator: "when") 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

View File

@ -1,2 +1,2 @@
((glsl_content) @content ((glsl_content) @content
(.set! "language" "glsl")) (#set! "language" "glsl"))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,3 @@
((text) @content ((text) @content
(.set! "language" "html") (#set! "language" "html")
(.set! "combined")) (#set! "combined"))

View File

@ -18,16 +18,16 @@
; Identifier naming conventions ; Identifier naming conventions
((identifier) @type ((identifier) @type
(.match? @type "^[A-Z]")) (#match? @type "^[A-Z]"))
((identifier) @constant ((identifier) @constant
(.match? @constant "^_*[A-Z][A-Z\\d_]*$")) (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
; Builtin functions ; Builtin functions
((call ((call
function: (identifier) @function.builtin) function: (identifier) @function.builtin)
(.match? (#match?
@function.builtin @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__)$")) "^(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" "yield"
"match" "match"
"case" "case"
] @keyword ] @keyword

File diff suppressed because one or more lines are too long

View File

@ -6,5 +6,5 @@
(symbol) @name (symbol) @name
(list . (symbol) @name) (list . (symbol) @name)
] ]
(.match? @start-symbol "^define") (#match? @start-symbol "^define")
) @item ) @item

View File

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

View File

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

View File

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

View File

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

View File

@ -14,7 +14,7 @@
(directive)] @comment (directive)] @comment
((symbol) @operator ((symbol) @operator
(.match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$")) (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$"))
(list (list
. .
@ -23,6 +23,6 @@
(list (list
. .
(symbol) @keyword (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)$" "^(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)$"
)) ))

View File

@ -6,5 +6,5 @@
(symbol) @name (symbol) @name
(list . (symbol) @name) (list . (symbol) @name)
] ]
(.match? @start-symbol "^define") (#match? @start-symbol "^define")
) @item ) @item

View File

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

View File

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

View File

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

View File

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

View File

@ -83,6 +83,8 @@ function write_tokens(themes: Theme[], tokens_directory: string) {
console.log(`- ${METADATA_FILE} created`) 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) write_tokens(all_themes, TOKENS_DIRECTORY)

View File

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

View File

@ -12,47 +12,44 @@ type TabBarButtonProps = TabBarButtonOptions & {
state?: Partial<Record<InteractiveState, Partial<TabBarButtonOptions>>> state?: Partial<Record<InteractiveState, Partial<TabBarButtonOptions>>>
} }
export function tab_bar_button( export function tab_bar_button(theme: Theme, { icon, color = "base" }: TabBarButtonProps) {
theme: Theme,
{ icon, color = "base" }: TabBarButtonProps
) {
const button_spacing = 8 const button_spacing = 8
return interactive({ return (
base: { interactive({
icon: { base: {
color: foreground(theme.middle, color), icon: {
asset: icon, color: foreground(theme.middle, color),
dimensions: { asset: icon,
width: 15, dimensions: {
height: 15, 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: { 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: { state: {
container: { hovered: {
background: background(theme.middle, color, "pressed"), container: {
background: background(theme.middle, color, "hovered"),
}
},
clicked: {
container: {
background: background(theme.middle, color, "pressed"),
}
}, },
}, },
}, })
}) )
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -152,7 +152,7 @@ export default function picker(): any {
0.5 0.5
), ),
}, },
}, }
}), }),
} }
} }

View File

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

View File

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

View File

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

View File

@ -1,28 +1,28 @@
import { Scale, Color } from "chroma-js" import { Scale, Color } from "chroma-js"
import { Syntax, ThemeSyntax, SyntaxHighlightStyle } from "./syntax"
export { Syntax, ThemeSyntax, SyntaxHighlightStyle }
import { import {
ThemeConfig, ThemeConfig,
ThemeAppearance, ThemeAppearance,
ThemeConfigInputColors, ThemeConfigInputColors,
} from "./theme_config" } from "./theme_config"
import { get_ramps } from "./ramps" import { get_ramps } from "./ramps"
import { syntaxStyle } from "./syntax"
import { Syntax } from "../types/syntax"
export interface Theme { export interface Theme {
name: string name: string
is_light: boolean 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 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 middle: Layer
/** /**
* Editors like code buffers, conversation editors, etc. * Editors like code buffers, conversation editors, etc.
*/ */
highest: Layer highest: Layer
ramps: RampSet ramps: RampSet
@ -31,7 +31,7 @@ export interface Theme {
modal_shadow: Shadow modal_shadow: Shadow
players: Players players: Players
syntax: Syntax syntax?: Partial<ThemeSyntax>
} }
export interface Meta { export interface Meta {
@ -115,7 +115,12 @@ export interface Style {
} }
export function create_theme(theme: ThemeConfig): Theme { 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 is_light = appearance === ThemeAppearance.Light
const color_ramps: ThemeConfigInputColors = input_color const color_ramps: ThemeConfigInputColors = input_color
@ -157,11 +162,6 @@ export function create_theme(theme: ThemeConfig): Theme {
"7": player(ramps.yellow), "7": player(ramps.yellow),
} }
const syntax = syntaxStyle(
ramps,
theme.override.syntax ? theme.override.syntax : {}
)
return { return {
name, name,
is_light, is_light,

View File

@ -1,45 +1,325 @@
import deepmerge from "deepmerge" import deepmerge from "deepmerge"
import { font_weights, ThemeConfigInputSyntax, RampSet } from "../common" import { FontWeight, font_weights, useTheme } from "../common"
import { Syntax, SyntaxHighlightStyle, allSyntaxKeys } from "../types/syntax" import chroma from "chroma-js"
// Apply defaults to any missing syntax properties that are not defined manually export interface SyntaxHighlightStyle {
function apply_defaults( color?: string
ramps: RampSet, weight?: FontWeight
syntax_highlights: Partial<Syntax> underline?: boolean
): Syntax { italic?: boolean
const restKeys: (keyof Syntax)[] = allSyntaxKeys.filter( }
(key) => !syntax_highlights[key]
)
const completeSyntax: Syntax = {} as Syntax export interface Syntax {
// == Text Styles ====== /
comment: SyntaxHighlightStyle
// elixir: doc comment
"comment.doc": SyntaxHighlightStyle
primary: SyntaxHighlightStyle
predictive: SyntaxHighlightStyle
hint: SyntaxHighlightStyle
const defaults: SyntaxHighlightStyle = { // === Formatted Text ====== /
color: ramps.neutral(1).hex(), 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
for (const key of restKeys) { // == Punctuation ====== /
{ punctuation: SyntaxHighlightStyle
completeSyntax[key] = { /** Example: `(`, `[`, `{`...*/
...defaults, "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 export function build_syntax(): Syntax {
// This is a deep merge, so any nested properties will be merged as well const theme = useTheme()
// This allows for a theme to only override a single property of a syntax highlight style
const merge_syntax = ( const default_syntax: Syntax = build_default_syntax()
baseSyntax: Syntax,
theme_syntax_overrides: ThemeConfigInputSyntax if (!theme.syntax) {
): Syntax => { return default_syntax
return deepmerge<Syntax, ThemeConfigInputSyntax>( }
baseSyntax,
theme_syntax_overrides, const syntax = deepmerge<Syntax, Partial<ThemeSyntax>>(
default_syntax,
theme.syntax,
{ {
arrayMerge: (destinationArray, sourceArray) => [ arrayMerge: (destinationArray, sourceArray) => [
...destinationArray, ...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 */ return syntax
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
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
import { ThemeConfigInputSyntax } from "../../common" import { ThemeSyntax } from "../../common"
export const color = { export const color = {
default: { 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 { return {
comment: { color: c.muted }, comment: { color: c.muted },
operator: { color: c.pine }, operator: { color: c.pine },

View File

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

View File

@ -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",
]

View File

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