From 5d25edeb2af1d61a7244a19ef5f622e53d0c0cfe Mon Sep 17 00:00:00 2001 From: Chris Birch Date: Sun, 8 Nov 2026 01:08:44 -0500 Subject: [PATCH 1/4] refactor(neovim): read syntax and tree-sitter groups from a shared table The syntax and tree-sitter highlight groups were Lua text inside neovim.py, so a second generator wanting the same styles could only copy them, and the copies would drift. They now live in lib/neovim_highlights.py as Python data, with the semantic colors palette.lua maps them through, and neovim.py writes the same Lua from it. Every theme's generated colorscheme is byte-identical. The table sits in lib/ because every script in lib/generators/ is read as a generator. Importing it from there writes __pycache__/, now ignored. Agent-Name: claude-code-unattended Agent-Session: 4773265d-bd77-424c-b9db-836de857b797 Agent-Run: 01a1b9b4-580a-78e4-993a-0b0cbf56760f Worklog: 2555.1 --- .gitignore | 1 + lib/generators/neovim.py | 272 +++++++++------------------------------ lib/neovim_highlights.py | 247 +++++++++++++++++++++++++++++++++++ 3 files changed, 311 insertions(+), 209 deletions(-) create mode 100644 lib/neovim_highlights.py diff --git a/.gitignore b/.gitignore index b5656f6..3dd3c9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .envrc .dev-data/ +__pycache__/ # The installer clones this repo to ~/.local/share/theme, and set_desktop_wallpaper # writes the hyprpaper restart fallback to ~/.local/share/theme/background.png — diff --git a/lib/generators/neovim.py b/lib/generators/neovim.py index a68ef24..1f67055 100755 --- a/lib/generators/neovim.py +++ b/lib/generators/neovim.py @@ -17,6 +17,14 @@ import yaml +sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) +from neovim_highlights import ( + SEMANTIC_COLORS, + TREESITTER_GROUPS, + UI_SLOTS, + VIM_SYNTAX_GROUPS, +) + def load_theme(theme_path: Path) -> dict: """Load theme.yml file.""" @@ -48,13 +56,50 @@ def colorscheme_name_for(meta: dict, slug: str) -> str: return slug -def get_color(extended: dict, extended_key: str, base16_fallback: str) -> str: +def get_color(extended: dict, extended_key: str | None, base16_fallback: str) -> str: """Get color preferring extended palette, falling back to base16.""" if extended_key in extended: return f"M.palette.{extended_key}" return f"M.palette.{base16_fallback}" +def semantic_lua(extended: dict, group: str) -> list[str]: + """One M.theme block's lines, from the shared table.""" + return [ + f" {name} = {get_color(extended, key, fallback)}," + for name, key, fallback in SEMANTIC_COLORS[group] + ] + + +def lua_spec(spec: dict) -> str: + """A highlight spec from the shared table, as a Lua table over M.theme.""" + parts = [] + for key, value in spec.items(): + if key == "link": + parts.append(f'link = "{value}"') + elif value is True: + parts.append(f"{key} = true") + elif value == "NONE": + parts.append(f'{key} = "NONE"') + else: + parts.append(f"{key} = theme.{value}") + return "{ " + ", ".join(parts) + " }" + + +def lua_groups(runs: list) -> str: + """Runs of highlight groups as the entries of a Lua return table.""" + lines = [] + for i, (title, groups) in enumerate(runs): + if i: + lines.append("") + if title: + lines.append(f" -- {title}") + for name, spec in groups: + key = f'["{name}"]' if name.startswith("@") else name + lines.append(f" {key} = {lua_spec(spec)},") + return "\n".join(lines) + + def resolve_color(base16: dict, extended: dict, extended_key: str, base16_fallback: str) -> str: """Resolve a semantic colour to its hex value rather than a palette reference. @@ -225,11 +270,11 @@ def generate_palette_lua(theme: dict) -> str: f' bg_search = M.palette.base0A,', f' fg_search = "{text_on(search, text, background)}",', f' fg_substitute = "{text_on(vcs_removed, text, background)}",', - f' fg = M.palette.base05,', - f' fg_dim = M.palette.base04,', - f' fg_reverse = M.palette.base00,', + f' fg = M.palette.{UI_SLOTS["fg"]},', + f' fg_dim = M.palette.{UI_SLOTS["fg_dim"]},', + f' fg_reverse = M.palette.{UI_SLOTS["fg_reverse"]},', f' special = M.palette.base0C,', - f' nontext = M.palette.base03,', + f' nontext = M.palette.{UI_SLOTS["nontext"]},', f' whitespace = M.palette.base02,', " float = {", f' fg = M.palette.base05,', @@ -247,36 +292,13 @@ def generate_palette_lua(theme: dict) -> str: " },", " },", " syn = {", - f' comment = {get_color(extended, "syntax_comment", "base03")},', - f' string = {get_color(extended, "syntax_string", "base0B")},', - f' number = {get_color(extended, "syntax_number", "base0E")},', - f' constant = {get_color(extended, "syntax_constant", "base0E")},', - f' identifier = {get_color(extended, "syntax_identifier", "base0D")},', - f' parameter = {get_color(extended, "syntax_parameter", "base0D")},', - f' fun = {get_color(extended, "syntax_function", "base0B")},', - f' statement = {get_color(extended, "syntax_statement", "base08")},', - f' keyword = {get_color(extended, "syntax_keyword", "base08")},', - f' operator = {get_color(extended, "syntax_operator", "base09")},', - f' preproc = {get_color(extended, "syntax_preproc", "base0C")},', - f' type = {get_color(extended, "syntax_type", "base0A")},', - f' special1 = {get_color(extended, "syntax_special1", "base09")},', - f' special2 = {get_color(extended, "syntax_special2", "base08")},', - f' special3 = {get_color(extended, "syntax_special3", "base0C")},', - f' punct = {get_color(extended, "syntax_punctuation", "base04")},', - f' regex = {get_color(extended, "syntax_regex", "base0C")},', - f' deprecated = M.palette.base03,', + *semantic_lua(extended, "syn"), " },", " diag = {", - f' error = {get_color(extended, "diagnostic_error", "base08")},', - f' warning = {get_color(extended, "diagnostic_warning", "base09")},', - f' info = {get_color(extended, "diagnostic_info", "base0D")},', - f' hint = {get_color(extended, "diagnostic_hint", "base0C")},', - f' ok = {get_color(extended, "diagnostic_ok", "base0B")},', + *semantic_lua(extended, "diag"), " },", " vcs = {", - f' added = {get_color(extended, "git_add", "base0B")},', - f' changed = {get_color(extended, "git_change", "base0A")},', - f' removed = {get_color(extended, "git_delete", "base08")},', + *semantic_lua(extended, "vcs"), " },", # Literals rather than palette references: a band is a solved value, not # a slot. Solved against base00 because that is what Normal's background @@ -461,65 +483,14 @@ def generate_editor_lua() -> str: def generate_syntax_lua() -> str: """Generate syntax.lua with traditional Vim syntax groups.""" - return '''-- Auto-generated syntax highlights -local M = {} + return f'''-- Auto-generated syntax highlights +local M = {{}} function M.setup(colors) local theme = colors.theme - return { - Comment = { fg = theme.syn.comment }, - - Constant = { fg = theme.syn.constant }, - String = { fg = theme.syn.string }, - Character = { link = "String" }, - Number = { fg = theme.syn.number }, - Boolean = { fg = theme.syn.constant, bold = true }, - Float = { link = "Number" }, - - Identifier = { fg = theme.syn.identifier }, - Function = { fg = theme.syn.fun }, - - Statement = { fg = theme.syn.statement }, - Conditional = { link = "Statement" }, - Repeat = { link = "Statement" }, - Label = { link = "Statement" }, - Operator = { fg = theme.syn.operator }, - Keyword = { fg = theme.syn.keyword }, - Exception = { fg = theme.syn.special2 }, - - PreProc = { fg = theme.syn.preproc }, - Include = { link = "PreProc" }, - Define = { link = "PreProc" }, - Macro = { link = "PreProc" }, - PreCondit = { link = "PreProc" }, - - Type = { fg = theme.syn.type }, - StorageClass = { link = "Type" }, - Structure = { link = "Type" }, - Typedef = { link = "Type" }, - - Special = { fg = theme.syn.special1 }, - SpecialChar = { link = "Special" }, - Tag = { fg = theme.syn.special3 }, - Delimiter = { fg = theme.syn.punct }, - SpecialComment = { link = "Special" }, - Debug = { fg = theme.diag.warning }, - - Underlined = { fg = theme.syn.special1, underline = true }, - Bold = { bold = true }, - Italic = { italic = true }, - - Ignore = { link = "NonText" }, - Error = { fg = theme.diag.error }, - Todo = { fg = theme.ui.fg_reverse, bg = theme.diag.info, bold = true }, - - qfLineNr = { link = "LineNr" }, - qfFileName = { link = "Directory" }, - - markdownCode = { fg = theme.syn.string }, - markdownCodeBlock = { fg = theme.syn.string }, - markdownEscape = { fg = "NONE" }, - } + return {{ +{lua_groups(VIM_SYNTAX_GROUPS)} + }} end return M @@ -528,131 +499,14 @@ def generate_syntax_lua() -> str: def generate_treesitter_lua() -> str: """Generate treesitter.lua with @capture groups.""" - return '''-- Auto-generated treesitter highlights -local M = {} + return f'''-- Auto-generated treesitter highlights +local M = {{}} function M.setup(colors) local theme = colors.theme - return { - -- Variables - ["@variable"] = { fg = theme.ui.fg }, - ["@variable.builtin"] = { fg = theme.syn.special2, italic = true }, - ["@variable.parameter"] = { fg = theme.syn.parameter }, - ["@variable.member"] = { fg = theme.syn.identifier }, - - -- Constants - ["@constant"] = { link = "Constant" }, - ["@constant.builtin"] = { fg = theme.syn.constant, bold = true }, - ["@constant.macro"] = { link = "Macro" }, - - -- Modules - ["@module"] = { link = "Structure" }, - ["@module.builtin"] = { fg = theme.syn.special1 }, - ["@label"] = { link = "Label" }, - - -- Strings - ["@string"] = { link = "String" }, - ["@string.documentation"] = { fg = theme.syn.string, italic = true }, - ["@string.regexp"] = { fg = theme.syn.regex }, - ["@string.escape"] = { fg = theme.syn.regex, bold = true }, - ["@string.special"] = { link = "Special" }, - ["@string.special.symbol"] = { fg = theme.syn.identifier }, - ["@string.special.path"] = { link = "Directory" }, - ["@string.special.url"] = { fg = theme.syn.special1, undercurl = true }, - - -- Characters - ["@character"] = { link = "Character" }, - ["@character.special"] = { link = "SpecialChar" }, - - -- Booleans and numbers - ["@boolean"] = { link = "Boolean" }, - ["@number"] = { link = "Number" }, - ["@number.float"] = { link = "Float" }, - - -- Types - ["@type"] = { link = "Type" }, - ["@type.builtin"] = { fg = theme.syn.type, italic = true }, - ["@type.definition"] = { link = "Type" }, - - -- Attributes - ["@attribute"] = { link = "Constant" }, - ["@attribute.builtin"] = { fg = theme.syn.special1 }, - ["@property"] = { fg = theme.syn.identifier }, - - -- Functions - ["@function"] = { link = "Function" }, - ["@function.builtin"] = { fg = theme.syn.fun, italic = true }, - ["@function.call"] = { link = "Function" }, - ["@function.macro"] = { link = "Macro" }, - ["@function.method"] = { link = "Function" }, - ["@function.method.call"] = { link = "Function" }, - - -- Constructors - ["@constructor"] = { fg = theme.syn.special1 }, - ["@constructor.lua"] = { fg = theme.syn.keyword }, - - -- Operators - ["@operator"] = { link = "Operator" }, - - -- Keywords - ["@keyword"] = { link = "Keyword" }, - ["@keyword.coroutine"] = { fg = theme.syn.keyword, italic = true }, - ["@keyword.function"] = { fg = theme.syn.keyword }, - ["@keyword.operator"] = { fg = theme.syn.operator, bold = true }, - ["@keyword.import"] = { link = "PreProc" }, - ["@keyword.type"] = { link = "Type" }, - ["@keyword.modifier"] = { link = "StorageClass" }, - ["@keyword.repeat"] = { link = "Repeat" }, - ["@keyword.return"] = { fg = theme.syn.special3 }, - ["@keyword.debug"] = { link = "Debug" }, - ["@keyword.exception"] = { fg = theme.syn.special3 }, - ["@keyword.conditional"] = { link = "Conditional" }, - ["@keyword.conditional.ternary"] = { link = "Operator" }, - ["@keyword.directive"] = { link = "PreProc" }, - ["@keyword.directive.define"] = { link = "Define" }, - - -- Punctuation - ["@punctuation.delimiter"] = { fg = theme.syn.punct }, - ["@punctuation.bracket"] = { fg = theme.syn.punct }, - ["@punctuation.special"] = { fg = theme.syn.special1 }, - - -- Comments - ["@comment"] = { link = "Comment" }, - ["@comment.documentation"] = { fg = theme.syn.comment }, - ["@comment.error"] = { fg = theme.ui.fg, bg = theme.diag.error, bold = true }, - ["@comment.warning"] = { fg = theme.ui.fg_reverse, bg = theme.diag.warning, bold = true }, - ["@comment.todo"] = { fg = theme.ui.fg_reverse, bg = theme.diag.hint, bold = true }, - ["@comment.note"] = { fg = theme.ui.fg_reverse, bg = theme.diag.info, bold = true }, - - -- Markup - ["@markup.strong"] = { bold = true }, - ["@markup.italic"] = { italic = true }, - ["@markup.strikethrough"] = { strikethrough = true }, - ["@markup.underline"] = { underline = true }, - ["@markup.heading"] = { link = "Function" }, - ["@markup.quote"] = { fg = theme.syn.parameter, italic = true }, - ["@markup.math"] = { link = "Constant" }, - ["@markup.environment"] = { link = "Keyword" }, - ["@markup.link"] = { fg = theme.syn.special1 }, - ["@markup.link.label"] = { link = "Special" }, - ["@markup.link.url"] = { fg = theme.syn.special1, undercurl = true }, - ["@markup.raw"] = { link = "String" }, - ["@markup.raw.block"] = { fg = theme.syn.string }, - ["@markup.list"] = { fg = theme.syn.punct }, - ["@markup.list.checked"] = { fg = theme.diag.ok }, - ["@markup.list.unchecked"] = { fg = theme.ui.nontext }, - - -- Diff - ["@diff.plus"] = { fg = theme.vcs.added }, - ["@diff.minus"] = { fg = theme.vcs.removed }, - ["@diff.delta"] = { fg = theme.vcs.changed }, - - -- Tags (HTML/XML) - ["@tag"] = { link = "Tag" }, - ["@tag.builtin"] = { fg = theme.syn.special3 }, - ["@tag.attribute"] = { fg = theme.syn.identifier }, - ["@tag.delimiter"] = { fg = theme.syn.punct }, - } + return {{ +{lua_groups(TREESITTER_GROUPS)} + }} end return M diff --git a/lib/neovim_highlights.py b/lib/neovim_highlights.py new file mode 100644 index 0000000..5927b47 --- /dev/null +++ b/lib/neovim_highlights.py @@ -0,0 +1,247 @@ +"""The Neovim highlight groups that both neovim.py and tui-theme.py read. + +neovim.py writes these as Lua, symbolic over the generated palette. tui-theme.py +resolves them to hex, so a note or a snippet in a terminal program wears the +styles the same text has in Neovim. One table means the two cannot drift. + +A color in a group is a reference into the generated `M.theme`, such as +"syn.comment", or the literal "NONE". A group whose spec is {"link": name} wears +the linked group's style. This sits outside lib/generators/ because every +script there is a generator, and generate-all.sh runs each one. +""" + +# M.theme's semantic colors: (name, extended key, base16 fallback). The extended +# key wins where theme.yml sets it. A None key always takes the fallback. +SEMANTIC_COLORS = { + "syn": [ + ("comment", "syntax_comment", "base03"), + ("string", "syntax_string", "base0B"), + ("number", "syntax_number", "base0E"), + ("constant", "syntax_constant", "base0E"), + ("identifier", "syntax_identifier", "base0D"), + ("parameter", "syntax_parameter", "base0D"), + ("fun", "syntax_function", "base0B"), + ("statement", "syntax_statement", "base08"), + ("keyword", "syntax_keyword", "base08"), + ("operator", "syntax_operator", "base09"), + ("preproc", "syntax_preproc", "base0C"), + ("type", "syntax_type", "base0A"), + ("special1", "syntax_special1", "base09"), + ("special2", "syntax_special2", "base08"), + ("special3", "syntax_special3", "base0C"), + ("punct", "syntax_punctuation", "base04"), + ("regex", "syntax_regex", "base0C"), + ("deprecated", None, "base03"), + ], + "diag": [ + ("error", "diagnostic_error", "base08"), + ("warning", "diagnostic_warning", "base09"), + ("info", "diagnostic_info", "base0D"), + ("hint", "diagnostic_hint", "base0C"), + ("ok", "diagnostic_ok", "base0B"), + ], + "vcs": [ + ("added", "git_add", "base0B"), + ("changed", "git_change", "base0A"), + ("removed", "git_delete", "base08"), + ], +} + +# The M.theme.ui colors the groups below read, each a base16 slot. +UI_SLOTS = { + "fg": "base05", + "fg_dim": "base04", + "fg_reverse": "base00", + "nontext": "base03", +} + +# syntax.lua: the traditional Vim syntax groups, in blank-line-separated runs. +VIM_SYNTAX_GROUPS = [ + (None, [ + ("Comment", {"fg": "syn.comment"}), + ]), + (None, [ + ("Constant", {"fg": "syn.constant"}), + ("String", {"fg": "syn.string"}), + ("Character", {"link": "String"}), + ("Number", {"fg": "syn.number"}), + ("Boolean", {"fg": "syn.constant", "bold": True}), + ("Float", {"link": "Number"}), + ]), + (None, [ + ("Identifier", {"fg": "syn.identifier"}), + ("Function", {"fg": "syn.fun"}), + ]), + (None, [ + ("Statement", {"fg": "syn.statement"}), + ("Conditional", {"link": "Statement"}), + ("Repeat", {"link": "Statement"}), + ("Label", {"link": "Statement"}), + ("Operator", {"fg": "syn.operator"}), + ("Keyword", {"fg": "syn.keyword"}), + ("Exception", {"fg": "syn.special2"}), + ]), + (None, [ + ("PreProc", {"fg": "syn.preproc"}), + ("Include", {"link": "PreProc"}), + ("Define", {"link": "PreProc"}), + ("Macro", {"link": "PreProc"}), + ("PreCondit", {"link": "PreProc"}), + ]), + (None, [ + ("Type", {"fg": "syn.type"}), + ("StorageClass", {"link": "Type"}), + ("Structure", {"link": "Type"}), + ("Typedef", {"link": "Type"}), + ]), + (None, [ + ("Special", {"fg": "syn.special1"}), + ("SpecialChar", {"link": "Special"}), + ("Tag", {"fg": "syn.special3"}), + ("Delimiter", {"fg": "syn.punct"}), + ("SpecialComment", {"link": "Special"}), + ("Debug", {"fg": "diag.warning"}), + ]), + (None, [ + ("Underlined", {"fg": "syn.special1", "underline": True}), + ("Bold", {"bold": True}), + ("Italic", {"italic": True}), + ]), + (None, [ + ("Ignore", {"link": "NonText"}), + ("Error", {"fg": "diag.error"}), + ("Todo", {"fg": "ui.fg_reverse", "bg": "diag.info", "bold": True}), + ]), + (None, [ + ("qfLineNr", {"link": "LineNr"}), + ("qfFileName", {"link": "Directory"}), + ]), + (None, [ + ("markdownCode", {"fg": "syn.string"}), + ("markdownCodeBlock", {"fg": "syn.string"}), + ("markdownEscape", {"fg": "NONE"}), + ]), +] + +# treesitter.lua: the @capture groups, in titled runs. +TREESITTER_GROUPS = [ + ("Variables", [ + ("@variable", {"fg": "ui.fg"}), + ("@variable.builtin", {"fg": "syn.special2", "italic": True}), + ("@variable.parameter", {"fg": "syn.parameter"}), + ("@variable.member", {"fg": "syn.identifier"}), + ]), + ("Constants", [ + ("@constant", {"link": "Constant"}), + ("@constant.builtin", {"fg": "syn.constant", "bold": True}), + ("@constant.macro", {"link": "Macro"}), + ]), + ("Modules", [ + ("@module", {"link": "Structure"}), + ("@module.builtin", {"fg": "syn.special1"}), + ("@label", {"link": "Label"}), + ]), + ("Strings", [ + ("@string", {"link": "String"}), + ("@string.documentation", {"fg": "syn.string", "italic": True}), + ("@string.regexp", {"fg": "syn.regex"}), + ("@string.escape", {"fg": "syn.regex", "bold": True}), + ("@string.special", {"link": "Special"}), + ("@string.special.symbol", {"fg": "syn.identifier"}), + ("@string.special.path", {"link": "Directory"}), + ("@string.special.url", {"fg": "syn.special1", "undercurl": True}), + ]), + ("Characters", [ + ("@character", {"link": "Character"}), + ("@character.special", {"link": "SpecialChar"}), + ]), + ("Booleans and numbers", [ + ("@boolean", {"link": "Boolean"}), + ("@number", {"link": "Number"}), + ("@number.float", {"link": "Float"}), + ]), + ("Types", [ + ("@type", {"link": "Type"}), + ("@type.builtin", {"fg": "syn.type", "italic": True}), + ("@type.definition", {"link": "Type"}), + ]), + ("Attributes", [ + ("@attribute", {"link": "Constant"}), + ("@attribute.builtin", {"fg": "syn.special1"}), + ("@property", {"fg": "syn.identifier"}), + ]), + ("Functions", [ + ("@function", {"link": "Function"}), + ("@function.builtin", {"fg": "syn.fun", "italic": True}), + ("@function.call", {"link": "Function"}), + ("@function.macro", {"link": "Macro"}), + ("@function.method", {"link": "Function"}), + ("@function.method.call", {"link": "Function"}), + ]), + ("Constructors", [ + ("@constructor", {"fg": "syn.special1"}), + ("@constructor.lua", {"fg": "syn.keyword"}), + ]), + ("Operators", [ + ("@operator", {"link": "Operator"}), + ]), + ("Keywords", [ + ("@keyword", {"link": "Keyword"}), + ("@keyword.coroutine", {"fg": "syn.keyword", "italic": True}), + ("@keyword.function", {"fg": "syn.keyword"}), + ("@keyword.operator", {"fg": "syn.operator", "bold": True}), + ("@keyword.import", {"link": "PreProc"}), + ("@keyword.type", {"link": "Type"}), + ("@keyword.modifier", {"link": "StorageClass"}), + ("@keyword.repeat", {"link": "Repeat"}), + ("@keyword.return", {"fg": "syn.special3"}), + ("@keyword.debug", {"link": "Debug"}), + ("@keyword.exception", {"fg": "syn.special3"}), + ("@keyword.conditional", {"link": "Conditional"}), + ("@keyword.conditional.ternary", {"link": "Operator"}), + ("@keyword.directive", {"link": "PreProc"}), + ("@keyword.directive.define", {"link": "Define"}), + ]), + ("Punctuation", [ + ("@punctuation.delimiter", {"fg": "syn.punct"}), + ("@punctuation.bracket", {"fg": "syn.punct"}), + ("@punctuation.special", {"fg": "syn.special1"}), + ]), + ("Comments", [ + ("@comment", {"link": "Comment"}), + ("@comment.documentation", {"fg": "syn.comment"}), + ("@comment.error", {"fg": "ui.fg", "bg": "diag.error", "bold": True}), + ("@comment.warning", {"fg": "ui.fg_reverse", "bg": "diag.warning", "bold": True}), + ("@comment.todo", {"fg": "ui.fg_reverse", "bg": "diag.hint", "bold": True}), + ("@comment.note", {"fg": "ui.fg_reverse", "bg": "diag.info", "bold": True}), + ]), + ("Markup", [ + ("@markup.strong", {"bold": True}), + ("@markup.italic", {"italic": True}), + ("@markup.strikethrough", {"strikethrough": True}), + ("@markup.underline", {"underline": True}), + ("@markup.heading", {"link": "Function"}), + ("@markup.quote", {"fg": "syn.parameter", "italic": True}), + ("@markup.math", {"link": "Constant"}), + ("@markup.environment", {"link": "Keyword"}), + ("@markup.link", {"fg": "syn.special1"}), + ("@markup.link.label", {"link": "Special"}), + ("@markup.link.url", {"fg": "syn.special1", "undercurl": True}), + ("@markup.raw", {"link": "String"}), + ("@markup.raw.block", {"fg": "syn.string"}), + ("@markup.list", {"fg": "syn.punct"}), + ("@markup.list.checked", {"fg": "diag.ok"}), + ("@markup.list.unchecked", {"fg": "ui.nontext"}), + ]), + ("Diff", [ + ("@diff.plus", {"fg": "vcs.added"}), + ("@diff.minus", {"fg": "vcs.removed"}), + ("@diff.delta", {"fg": "vcs.changed"}), + ]), + ("Tags (HTML/XML)", [ + ("@tag", {"link": "Tag"}), + ("@tag.builtin", {"fg": "syn.special3"}), + ("@tag.attribute", {"fg": "syn.identifier"}), + ("@tag.delimiter", {"fg": "syn.punct"}), + ]), +] From 5441a0057ebfcdc48e60eedef5c59d5c4550541f Mon Sep 17 00:00:00 2001 From: Chris Birch Date: Sun, 8 Nov 2026 01:09:08 -0500 Subject: [PATCH 2/4] feat(tui-theme): write the TUI theme file for every theme and signal its readers Terminal programs on gotermstyle draw in the 16 ANSI colors, which hold no shade near the background, so a selected row can only be reversed into a slab. gotermstyle's tuitheme reads a theme file of colors and styles keyed by role. This writes that file for every theme, installs it where the reader looks, and asks each running reader to reread it on apply. tui-theme.py writes tui-theme.json. ui comes from theme.yml with its fallbacks resolved: the selection is special.selection_fg on extended.ui_selection or special.selection_bg, and the accent is extended.ui_accent or base0D. markdown and syntax resolve the shared Neovim highlight table, so a note or snippet in a terminal program wears the styles it has in Neovim. Every key the format names is written. apply_tui_theme installs it as ~/.config/tui-theme/.json with current.json linking to it, the path tuitheme reads with none given. The directory holds only theme files, so the themes sit beside the link. reload_tui_theme sends SIGUSR2 to each reader by name. Off Linux it first checks the binary on PATH carries Go's build-info marker, because the Go runtime ignores an unrequested SIGUSR2 and another program may die of it. reload_apps maps a hyphen in an app's name to its reload function's underscore. Agent-Name: claude-code-unattended Agent-Session: 4773265d-bd77-424c-b9db-836de857b797 Agent-Run: 01a1b9b4-580a-78e4-993a-0b0cbf56760f Worklog: 2555.1 --- CLAUDE.md | 12 +- README.md | 4 + lib/generate-all.sh | 7 +- lib/generators/tui-theme.py | 200 +++++++++++++++++++++ lib/lib.sh | 58 +++++- tests/apply-install.bats | 11 ++ tests/generators.bats | 5 +- themes/cendre-medium/tui-theme.json | 176 ++++++++++++++++++ themes/cendre-soft/tui-theme.json | 176 ++++++++++++++++++ themes/cendre/tui-theme.json | 176 ++++++++++++++++++ themes/charcoal-ember/tui-theme.json | 176 ++++++++++++++++++ themes/everforest-dark-hard/tui-theme.json | 176 ++++++++++++++++++ themes/flexoki-moon-black/tui-theme.json | 176 ++++++++++++++++++ themes/flexoki-moon-green/tui-theme.json | 176 ++++++++++++++++++ themes/flexoki-moon-purple/tui-theme.json | 176 ++++++++++++++++++ themes/flexoki-moon-red/tui-theme.json | 176 ++++++++++++++++++ themes/gruvbox/tui-theme.json | 176 ++++++++++++++++++ themes/kanagawa/tui-theme.json | 176 ++++++++++++++++++ themes/nightfox/tui-theme.json | 176 ++++++++++++++++++ themes/nordic/tui-theme.json | 176 ++++++++++++++++++ themes/oceanic-next/tui-theme.json | 176 ++++++++++++++++++ themes/popping-and-locking/tui-theme.json | 176 ++++++++++++++++++ themes/retrobox/tui-theme.json | 176 ++++++++++++++++++ themes/rose-pine/tui-theme.json | 176 ++++++++++++++++++ themes/solarized-osaka/tui-theme.json | 176 ++++++++++++++++++ themes/sora/tui-theme.json | 176 ++++++++++++++++++ themes/terafox/tui-theme.json | 176 ++++++++++++++++++ 27 files changed, 3805 insertions(+), 12 deletions(-) create mode 100755 lib/generators/tui-theme.py create mode 100644 themes/cendre-medium/tui-theme.json create mode 100644 themes/cendre-soft/tui-theme.json create mode 100644 themes/cendre/tui-theme.json create mode 100644 themes/charcoal-ember/tui-theme.json create mode 100644 themes/everforest-dark-hard/tui-theme.json create mode 100644 themes/flexoki-moon-black/tui-theme.json create mode 100644 themes/flexoki-moon-green/tui-theme.json create mode 100644 themes/flexoki-moon-purple/tui-theme.json create mode 100644 themes/flexoki-moon-red/tui-theme.json create mode 100644 themes/gruvbox/tui-theme.json create mode 100644 themes/kanagawa/tui-theme.json create mode 100644 themes/nightfox/tui-theme.json create mode 100644 themes/nordic/tui-theme.json create mode 100644 themes/oceanic-next/tui-theme.json create mode 100644 themes/popping-and-locking/tui-theme.json create mode 100644 themes/retrobox/tui-theme.json create mode 100644 themes/rose-pine/tui-theme.json create mode 100644 themes/solarized-osaka/tui-theme.json create mode 100644 themes/sora/tui-theme.json create mode 100644 themes/terafox/tui-theme.json diff --git a/CLAUDE.md b/CLAUDE.md index 728fe6c..630ecdb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -131,11 +131,17 @@ same output file, so a role-based mapping puts a green in the slot a generator d ### The Generated Neovim Colorscheme Every theme has one, and `generate-all.sh` produces it like any other artifact: -`lib/generators/neovim.py`, mapped under `["neovim"]="neovim"`. It is the only generator written -in Python and the only one whose second argument is a directory. The job runner cares about -neither: it passes the mapped value through as `$2`. The PEP 723 header makes it directly +`lib/generators/neovim.py`, mapped under `["neovim"]="neovim"`. It is one of two generators +written in Python, and the only one whose second argument is a directory. The job runner cares +about neither: it passes the mapped value through as `$2`. The PEP 723 header makes it directly executable, so it needs no `uv run` wrapper at the call site. +**Its syntax and tree-sitter groups live in `lib/neovim_highlights.py`, not in the Lua text.** +`tui-theme.py` resolves the same table to hex, so a note or a snippet in a terminal program +wears the style it has in Neovim. A highlight changed in the Lua template alone drifts from +every terminal program. The table sits outside `lib/generators/` because the map check reads +every script there as a generator. + **The name it emits depends on where the theme's colors come from**, and this is the constraint to preserve: diff --git a/README.md b/README.md index b68aa44..d49f384 100644 --- a/README.md +++ b/README.md @@ -223,6 +223,10 @@ Both commands come from [`bashselfupdate`](https://github.com/datapointchris/bas - **abtop** — AI agent monitor. Needs [the fork](https://github.com/datapointchris/abtop) that reads theme files and reloads in place, with `theme = "current"` in `~/.config/abtop/config.toml` +- **TUIs on [gotermstyle](https://github.com/datapointchris/gotermstyle)** — the + theme's selection, accent, markdown and syntax colors, in + `~/.config/tui-theme/current.json`. A running program rereads it on SIGUSR2, + which `theme apply` sends to each reader it names in `TUI_THEME_READERS` - **bat** — syntax highlighter / pager - **delta** — git diff pager (requires bat; include `~/.config/delta/current.gitconfig` from your gitconfig) diff --git a/lib/generate-all.sh b/lib/generate-all.sh index e59c612..03c0759 100755 --- a/lib/generate-all.sh +++ b/lib/generate-all.sh @@ -58,10 +58,13 @@ declare -A GENERATOR_OUTPUT=( ["sioyek"]="sioyek.config" ["yazi"]="flavor.toml" ["aerc"]="aerc.styleset" - # The one generator whose output is a directory rather than a file, and the - # one written in Python. Both are incidental to the job runner, which only + # The one generator whose output is a directory rather than a file, and one + # of two written in Python. Both are incidental to the job runner, which only # ever passes this through as the second argument. ["neovim"]="neovim" + # The file terminal programs on gotermstyle read their colors from. Its + # markdown and syntax share neovim's highlight table, lib/neovim_highlights.py. + ["tui-theme"]="tui-theme.json" # delta resolves its syntax theme through bat's cache, but the config fragment # itself is generated from theme.yml alone — no ordering constraint here. ["delta"]="delta.conf" diff --git a/lib/generators/tui-theme.py b/lib/generators/tui-theme.py new file mode 100755 index 0000000..d2c292a --- /dev/null +++ b/lib/generators/tui-theme.py @@ -0,0 +1,200 @@ +#!/usr/bin/env -S uv run --script +# /// script +# requires-python = ">=3.11" +# dependencies = ["pyyaml"] +# /// +"""Generate tui-theme.json, the TUI theme file terminal programs read their colors from. + +Usage: tui-theme.py + +The format is gotermstyle's tuitheme: groups ui, markdown and syntax, each value +a #rrggbb color or a style object. The schema named in $schema documents every +key. markdown and syntax resolve the Neovim highlight groups in +lib/neovim_highlights.py, so text in a terminal program wears the style the same +text has in Neovim. Every key the format names is written, so a reader never +falls back to its built-in 16-color default for this theme. +""" + +import json +import re +import sys +from pathlib import Path + +import yaml + +sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) +from neovim_highlights import ( + SEMANTIC_COLORS, + TREESITTER_GROUPS, + UI_SLOTS, + VIM_SYNTAX_GROUPS, +) + +SCHEMA_URL = "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json" + +MARKDOWN_KEYS = [ + "strong", "italic", "strikethrough", "underline", + "heading", "heading.1", "heading.2", "heading.3", "heading.4", "heading.5", "heading.6", + "quote", "math", "link", "link.label", "link.url", "raw", "raw.block", + "list", "list.checked", "list.unchecked", +] + +# The format's base syntax roles, each read from the capture Neovim draws it +# with. Neovim has no bare @parameter or @punctuation. +SYNTAX_BASE = { + "comment": "@comment", + "string": "@string", + "number": "@number", + "constant": "@constant", + "parameter": "@variable.parameter", + "function": "@function", + "keyword": "@keyword", + "type": "@type", + "operator": "@operator", + "punctuation": "@punctuation.delimiter", + "attribute": "@attribute", + "variable": "@variable", + "tag": "@tag", +} + +HEX = re.compile(r"^#[0-9a-fA-F]{6}$") +ATTRIBUTES = ("bold", "italic", "underline", "strikethrough") + + +def is_hex(value) -> bool: + return isinstance(value, str) and bool(HEX.match(value)) + + +def required_hex(value, what: str) -> str: + if not is_hex(value): + sys.exit(f"tui-theme: {what} is {value!r}, not #rrggbb") + return value + + +def theme_colors(theme: dict) -> dict: + """M.theme's colors as hex, keyed as the highlight groups name them.""" + base16 = theme.get("base16") or {} + extended = theme.get("extended") or {} + colors = {} + for group, rows in SEMANTIC_COLORS.items(): + for name, key, fallback in rows: + value = extended.get(key) if key else None + colors[f"{group}.{name}"] = value if is_hex(value) else base16.get(fallback) + for name, slot in UI_SLOTS.items(): + colors[f"ui.{name}"] = base16.get(slot) + return colors + + +GROUPS = {name: spec for _, run in VIM_SYNTAX_GROUPS + TREESITTER_GROUPS for name, spec in run} + + +def group_style(name: str, colors: dict) -> dict | None: + """A highlight group's style in the format's terms, or None where its link + leads outside the shared table.""" + spec = GROUPS.get(name) + while spec is not None and "link" in spec: + spec = GROUPS.get(spec["link"]) + if spec is None: + return None + style = {} + for key in ("fg", "bg"): + if key in spec and spec[key] != "NONE": + style[key] = required_hex(colors.get(spec[key]), f"{name} {key} ({spec[key]})") + for key in ATTRIBUTES: + if spec.get(key) or (key == "underline" and spec.get("undercurl")): + style[key] = True + return style + + +def capture_style(capture: str, colors: dict) -> dict | None: + """A capture's style, falling back along its dots as Neovim does.""" + while True: + if capture in GROUPS: + return group_style(capture, colors) + head, dot, _ = capture.rpartition(".") + if not dot: + return None + capture = head + + +def value(style: dict): + """A style as the format writes it: a bare color where it is only a foreground.""" + return style["fg"] if list(style) == ["fg"] else style + + +def ui_group(theme: dict, colors: dict) -> dict: + base16 = theme.get("base16") or {} + extended = theme.get("extended") or {} + special = theme.get("special") or {} + + def pick(what: str, *candidates) -> str: + return required_hex(next((c for c in candidates if c), None), what) + + return { + "text": pick("ui.text", special.get("foreground"), base16.get("base05")), + "muted": pick("ui.muted", extended.get("fg_dim"), colors["ui.fg_dim"]), + "accent": pick("ui.accent", extended.get("ui_accent"), base16.get("base0D")), + "selection": { + "fg": pick("ui.selection.fg", special.get("selection_fg"), base16.get("base05")), + "bg": pick( + "ui.selection.bg", + extended.get("ui_selection"), special.get("selection_bg"), base16.get("base02"), + ), + }, + "match": pick("ui.match", extended.get("ui_match"), base16.get("base0A")), + "border": pick( + "ui.border", extended.get("ui_border"), special.get("border"), base16.get("base03"), + ), + "panel": { + "bg": pick("ui.panel", extended.get("ui_panel"), special.get("panel"), base16.get("base01")), + }, + "error": pick("ui.error", colors["diag.error"]), + "warning": pick("ui.warning", colors["diag.warning"]), + "info": pick("ui.info", colors["diag.info"]), + "success": pick("ui.success", colors["diag.ok"]), + } + + +def markdown_group(colors: dict) -> dict: + group = {} + for key in MARKDOWN_KEYS: + style = capture_style(f"@markup.{key}", colors) + if style is None: + sys.exit(f"tui-theme: markdown.{key} resolves to no Neovim group") + group[key] = value(style) + return group + + +def syntax_group(colors: dict) -> dict: + group = {key: value(capture_style(capture, colors)) for key, capture in SYNTAX_BASE.items()} + for _, run in TREESITTER_GROUPS: + for capture, _ in run: + key = capture.removeprefix("@") + if key in group or key.startswith("markup."): + continue + # A link into an editor group, such as Directory, is left to the + # reader's fallback along the dots. + style = group_style(capture, colors) + if style is not None: + group[key] = value(style) + return group + + +def main(): + if len(sys.argv) != 3: + sys.exit("Usage: tui-theme.py ") + theme_path, output = Path(sys.argv[1]), Path(sys.argv[2]) + with open(theme_path) as f: + theme = yaml.safe_load(f) + colors = theme_colors(theme) + document = { + "$schema": SCHEMA_URL, + "ui": ui_group(theme, colors), + "markdown": markdown_group(colors), + "syntax": syntax_group(colors), + } + output.write_text(json.dumps(document, indent=2) + "\n") + + +if __name__ == "__main__": + main() diff --git a/lib/lib.sh b/lib/lib.sh index 12556d4..6a11207 100755 --- a/lib/lib.sh +++ b/lib/lib.sh @@ -39,6 +39,7 @@ THEME_APP_ARTIFACTS=( "tmux.conf:tmux" "btop.theme:btop" "abtop.theme:abtop" + "tui-theme.json:tui-theme" "bat.tmTheme:bat" "delta.conf:delta" "flavor.toml:yazi" @@ -502,6 +503,22 @@ apply_abtop() { install_themed_artifact "$lib_path/abtop.theme" "$abtop_theme_dir" "$theme.theme" "current.theme" } +# tui-theme/current.json is where gotermstyle's tuitheme looks with no path +# given, so no reader's config needs a line for it. The directory holds only +# theme files, so each theme sits beside the pointer rather than in a themes/. +apply_tui_theme() { + local theme="$1" + local lib_path + lib_path=$(get_library_path "$theme") + + if [[ -z "$lib_path" ]] || [[ ! -f "$lib_path/tui-theme.json" ]]; then + return 1 + fi + + local tui_theme_dir="${XDG_CONFIG_HOME:-$HOME/.config}/tui-theme" + install_themed_artifact "$lib_path/tui-theme.json" "$tui_theme_dir" "$theme.json" "current.json" +} + # Apply JankyBorders theme (macOS) apply_borders() { local theme="$1" @@ -2069,6 +2086,15 @@ apply_theme_to_apps() { _print_app_status "abtop" "false" fi + # The TUI theme file (all platforms) + if apply_tui_theme "$theme" 2>/dev/null; then + applied+=("tui-theme") + _print_app_status "tui-theme" "true" + else + skipped+=("tui-theme") + _print_app_status "tui-theme" "false" + fi + # Yazi (all platforms) if apply_yazi "$theme" 2>/dev/null; then applied+=("yazi") @@ -2299,14 +2325,14 @@ reload_tmux() { # SIGUSR2 terminates a process with no handler for it. On Linux each process's # caught-signal mask (bit 11 is SIGUSR2) says whether it has one. Elsewhere the -# binary on PATH is asked instead, through the check named by $2. +# binary on PATH is asked instead, through the check named by $2, given $1. _signal_reload() { local name="$1" binary_handles_usr2="$2" local pids pid mask pids=$(pgrep -x "$name") || return 1 if [[ ! -d /proc/self ]]; then - "$binary_handles_usr2" || return 1 + "$binary_handles_usr2" "$name" || return 1 pkill -USR2 -x "$name" 2>/dev/null || true return 0 fi @@ -2336,6 +2362,27 @@ _abtop_handles_usr2() { reload_btop() { _signal_reload btop _btop_handles_usr2; } reload_abtop() { _signal_reload abtop _abtop_handles_usr2; } +# The programs that read tui-theme/current.json through gotermstyle, by process +# name. +TUI_THEME_READERS=(fleet slate psyche projects) + +# The Go runtime catches SIGUSR2 and ignores it in a program that never asked +# for it, so an older build, a CLI run and a daemon all survive the signal. A +# same-named program in another language may not, so off Linux the binary on +# PATH has to carry Go's build-info marker. +_go_binary_on_path() { + local binary + binary=$(command -v "$1") || return 1 + LC_ALL=C grep -qa 'Go buildinf:' "$binary" +} + +reload_tui_theme() { + local reader + for reader in "${TUI_THEME_READERS[@]}"; do + _signal_reload "$reader" _go_binary_on_path || true + done +} + reload_kitty() { if command -v pkill &>/dev/null; then pkill -USR1 kitty 2>/dev/null || true @@ -2421,17 +2468,18 @@ reload_apps() { local applied_apps=" ${1:-} " # rofi loads its theme on next launch, hyprlock on next lock. - local reloadable=(tmux btop abtop) + local reloadable=(tmux btop abtop tui-theme) if [[ "$platform" == "arch" ]]; then reloadable+=(kitty ghostty hyprland waybar dunst) fi # A reload returns 1 when its app is not running, which errexit would turn - # into an aborted apply. + # into an aborted apply. An app's name may hold a hyphen, which its reload + # function spells as an underscore. local app for app in "${reloadable[@]}"; do if [[ "$applied_apps" == *" $app "* ]]; then - "reload_$app" || true + "reload_${app//-/_}" || true fi done } diff --git a/tests/apply-install.bats b/tests/apply-install.bats index fab6775..4f3a30b 100755 --- a/tests/apply-install.bats +++ b/tests/apply-install.bats @@ -91,6 +91,17 @@ give_artifact() { assert_output "beta-light.conf" } +@test "the TUI theme lands at the path gotermstyle reads with none given" { + # tuitheme.DefaultPath is $XDG_CONFIG_HOME/tui-theme/current.json. Installed + # anywhere else, every reader stays on its built-in 16 colors with no error. + give_artifact alpha-dark tui-theme.json + + run apply_tui_theme alpha-dark + assert_success + run cat "$XDG_CONFIG_HOME/tui-theme/current.json" + assert_output "generated for alpha-dark" +} + @test "yazi installs a flavor directory and links current.yazi at it" { give_artifact alpha-dark flavor.toml diff --git a/tests/generators.bats b/tests/generators.bats index 2e48533..f02d390 100755 --- a/tests/generators.bats +++ b/tests/generators.bats @@ -50,8 +50,9 @@ map_keys() { printf '%s\n' "${!MAP_ARTIFACT[@]}" } -# Generators are bash except neovim, which is Python because it writes a Lua tree -# rather than a config file. Resolution order matches generate-all.sh's. +# Generators are bash except neovim and tui-theme, which are Python because they +# read the highlight table in lib/neovim_highlights.py. Resolution order matches +# generate-all.sh's. generator_script() { local name="$1" candidate for candidate in "$GENERATORS_DIR/$name.sh" "$GENERATORS_DIR/$name.py"; do diff --git a/themes/cendre-medium/tui-theme.json b/themes/cendre-medium/tui-theme.json new file mode 100644 index 0000000..185df41 --- /dev/null +++ b/themes/cendre-medium/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#e6d5c2", + "muted": "#a09384", + "accent": "#ea9875", + "selection": { + "fg": "#e6d5c2", + "bg": "#36241d" + }, + "match": "#fcba81", + "border": "#3d3633", + "panel": { + "bg": "#141110" + }, + "error": "#d25780", + "warning": "#f4a21c", + "info": "#58bdff", + "success": "#43b16a" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#fcba81", + "heading.1": "#fcba81", + "heading.2": "#fcba81", + "heading.3": "#fcba81", + "heading.4": "#fcba81", + "heading.5": "#fcba81", + "heading.6": "#fcba81", + "quote": { + "fg": "#ea9875", + "italic": true + }, + "math": "#e6d5c2", + "link": "#ea9875", + "link.label": "#ea9875", + "link.url": { + "fg": "#ea9875", + "underline": true + }, + "raw": "#99af6b", + "raw.block": "#99af6b", + "list": "#a09384", + "list.checked": "#43b16a", + "list.unchecked": "#73665b" + }, + "syntax": { + "comment": "#73665b", + "string": "#99af6b", + "number": "#99af6b", + "constant": "#e6d5c2", + "parameter": "#ea9875", + "function": "#fcba81", + "keyword": "#d1766e", + "type": "#4e89a2", + "operator": "#a09384", + "punctuation": "#a09384", + "attribute": "#e6d5c2", + "variable": "#e6d5c2", + "tag": "#20c9cb", + "variable.builtin": { + "fg": "#d1766e", + "italic": true + }, + "variable.parameter": "#ea9875", + "variable.member": "#4e89a2", + "constant.builtin": { + "fg": "#e6d5c2", + "bold": true + }, + "constant.macro": "#d1766e", + "module": "#4e89a2", + "module.builtin": "#ea9875", + "label": "#d1766e", + "string.documentation": { + "fg": "#99af6b", + "italic": true + }, + "string.regexp": "#20c9cb", + "string.escape": { + "fg": "#20c9cb", + "bold": true + }, + "string.special": "#ea9875", + "string.special.symbol": "#4e89a2", + "string.special.url": { + "fg": "#ea9875", + "underline": true + }, + "character": "#99af6b", + "character.special": "#ea9875", + "boolean": { + "fg": "#e6d5c2", + "bold": true + }, + "number.float": "#99af6b", + "type.builtin": { + "fg": "#4e89a2", + "italic": true + }, + "type.definition": "#4e89a2", + "attribute.builtin": "#ea9875", + "property": "#4e89a2", + "function.builtin": { + "fg": "#fcba81", + "italic": true + }, + "function.call": "#fcba81", + "function.macro": "#d1766e", + "function.method": "#fcba81", + "function.method.call": "#fcba81", + "constructor": "#ea9875", + "constructor.lua": "#d1766e", + "keyword.coroutine": { + "fg": "#d1766e", + "italic": true + }, + "keyword.function": "#d1766e", + "keyword.operator": { + "fg": "#a09384", + "bold": true + }, + "keyword.import": "#d1766e", + "keyword.type": "#4e89a2", + "keyword.modifier": "#4e89a2", + "keyword.repeat": "#d1766e", + "keyword.return": "#20c9cb", + "keyword.debug": "#f4a21c", + "keyword.exception": "#20c9cb", + "keyword.conditional": "#d1766e", + "keyword.conditional.ternary": "#a09384", + "keyword.directive": "#d1766e", + "keyword.directive.define": "#d1766e", + "punctuation.delimiter": "#a09384", + "punctuation.bracket": "#a09384", + "punctuation.special": "#ea9875", + "comment.documentation": "#73665b", + "comment.error": { + "fg": "#e6d5c2", + "bg": "#d25780", + "bold": true + }, + "comment.warning": { + "fg": "#1d1917", + "bg": "#f4a21c", + "bold": true + }, + "comment.todo": { + "fg": "#1d1917", + "bg": "#20c9cb", + "bold": true + }, + "comment.note": { + "fg": "#1d1917", + "bg": "#58bdff", + "bold": true + }, + "diff.plus": "#43b16a", + "diff.minus": "#d25780", + "diff.delta": "#58bdff", + "tag.builtin": "#20c9cb", + "tag.attribute": "#4e89a2", + "tag.delimiter": "#a09384" + } +} diff --git a/themes/cendre-soft/tui-theme.json b/themes/cendre-soft/tui-theme.json new file mode 100644 index 0000000..2700ccc --- /dev/null +++ b/themes/cendre-soft/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#e6d5c2", + "muted": "#a09384", + "accent": "#ea9875", + "selection": { + "fg": "#e6d5c2", + "bg": "#3d2b23" + }, + "match": "#fcba81", + "border": "#443c39", + "panel": { + "bg": "#1a1716" + }, + "error": "#d25780", + "warning": "#f4a21c", + "info": "#58bdff", + "success": "#43b16a" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#fcba81", + "heading.1": "#fcba81", + "heading.2": "#fcba81", + "heading.3": "#fcba81", + "heading.4": "#fcba81", + "heading.5": "#fcba81", + "heading.6": "#fcba81", + "quote": { + "fg": "#ea9875", + "italic": true + }, + "math": "#e6d5c2", + "link": "#ea9875", + "link.label": "#ea9875", + "link.url": { + "fg": "#ea9875", + "underline": true + }, + "raw": "#99af6b", + "raw.block": "#99af6b", + "list": "#a09384", + "list.checked": "#43b16a", + "list.unchecked": "#73665b" + }, + "syntax": { + "comment": "#73665b", + "string": "#99af6b", + "number": "#99af6b", + "constant": "#e6d5c2", + "parameter": "#ea9875", + "function": "#fcba81", + "keyword": "#d1766e", + "type": "#4e89a2", + "operator": "#a09384", + "punctuation": "#a09384", + "attribute": "#e6d5c2", + "variable": "#e6d5c2", + "tag": "#20c9cb", + "variable.builtin": { + "fg": "#d1766e", + "italic": true + }, + "variable.parameter": "#ea9875", + "variable.member": "#4e89a2", + "constant.builtin": { + "fg": "#e6d5c2", + "bold": true + }, + "constant.macro": "#d1766e", + "module": "#4e89a2", + "module.builtin": "#ea9875", + "label": "#d1766e", + "string.documentation": { + "fg": "#99af6b", + "italic": true + }, + "string.regexp": "#20c9cb", + "string.escape": { + "fg": "#20c9cb", + "bold": true + }, + "string.special": "#ea9875", + "string.special.symbol": "#4e89a2", + "string.special.url": { + "fg": "#ea9875", + "underline": true + }, + "character": "#99af6b", + "character.special": "#ea9875", + "boolean": { + "fg": "#e6d5c2", + "bold": true + }, + "number.float": "#99af6b", + "type.builtin": { + "fg": "#4e89a2", + "italic": true + }, + "type.definition": "#4e89a2", + "attribute.builtin": "#ea9875", + "property": "#4e89a2", + "function.builtin": { + "fg": "#fcba81", + "italic": true + }, + "function.call": "#fcba81", + "function.macro": "#d1766e", + "function.method": "#fcba81", + "function.method.call": "#fcba81", + "constructor": "#ea9875", + "constructor.lua": "#d1766e", + "keyword.coroutine": { + "fg": "#d1766e", + "italic": true + }, + "keyword.function": "#d1766e", + "keyword.operator": { + "fg": "#a09384", + "bold": true + }, + "keyword.import": "#d1766e", + "keyword.type": "#4e89a2", + "keyword.modifier": "#4e89a2", + "keyword.repeat": "#d1766e", + "keyword.return": "#20c9cb", + "keyword.debug": "#f4a21c", + "keyword.exception": "#20c9cb", + "keyword.conditional": "#d1766e", + "keyword.conditional.ternary": "#a09384", + "keyword.directive": "#d1766e", + "keyword.directive.define": "#d1766e", + "punctuation.delimiter": "#a09384", + "punctuation.bracket": "#a09384", + "punctuation.special": "#ea9875", + "comment.documentation": "#73665b", + "comment.error": { + "fg": "#e6d5c2", + "bg": "#d25780", + "bold": true + }, + "comment.warning": { + "fg": "#231f1d", + "bg": "#f4a21c", + "bold": true + }, + "comment.todo": { + "fg": "#231f1d", + "bg": "#20c9cb", + "bold": true + }, + "comment.note": { + "fg": "#231f1d", + "bg": "#58bdff", + "bold": true + }, + "diff.plus": "#43b16a", + "diff.minus": "#d25780", + "diff.delta": "#58bdff", + "tag.builtin": "#20c9cb", + "tag.attribute": "#4e89a2", + "tag.delimiter": "#a09384" + } +} diff --git a/themes/cendre/tui-theme.json b/themes/cendre/tui-theme.json new file mode 100644 index 0000000..1f38e4a --- /dev/null +++ b/themes/cendre/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#e6d5c2", + "muted": "#a09384", + "accent": "#ea9875", + "selection": { + "fg": "#e6d5c2", + "bg": "#2f1e17" + }, + "match": "#fcba81", + "border": "#362f2c", + "panel": { + "bg": "#0f0c0a" + }, + "error": "#d25780", + "warning": "#f4a21c", + "info": "#58bdff", + "success": "#43b16a" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#fcba81", + "heading.1": "#fcba81", + "heading.2": "#fcba81", + "heading.3": "#fcba81", + "heading.4": "#fcba81", + "heading.5": "#fcba81", + "heading.6": "#fcba81", + "quote": { + "fg": "#ea9875", + "italic": true + }, + "math": "#e6d5c2", + "link": "#ea9875", + "link.label": "#ea9875", + "link.url": { + "fg": "#ea9875", + "underline": true + }, + "raw": "#99af6b", + "raw.block": "#99af6b", + "list": "#a09384", + "list.checked": "#43b16a", + "list.unchecked": "#73665b" + }, + "syntax": { + "comment": "#73665b", + "string": "#99af6b", + "number": "#99af6b", + "constant": "#e6d5c2", + "parameter": "#ea9875", + "function": "#fcba81", + "keyword": "#d1766e", + "type": "#4e89a2", + "operator": "#a09384", + "punctuation": "#a09384", + "attribute": "#e6d5c2", + "variable": "#e6d5c2", + "tag": "#20c9cb", + "variable.builtin": { + "fg": "#d1766e", + "italic": true + }, + "variable.parameter": "#ea9875", + "variable.member": "#4e89a2", + "constant.builtin": { + "fg": "#e6d5c2", + "bold": true + }, + "constant.macro": "#d1766e", + "module": "#4e89a2", + "module.builtin": "#ea9875", + "label": "#d1766e", + "string.documentation": { + "fg": "#99af6b", + "italic": true + }, + "string.regexp": "#20c9cb", + "string.escape": { + "fg": "#20c9cb", + "bold": true + }, + "string.special": "#ea9875", + "string.special.symbol": "#4e89a2", + "string.special.url": { + "fg": "#ea9875", + "underline": true + }, + "character": "#99af6b", + "character.special": "#ea9875", + "boolean": { + "fg": "#e6d5c2", + "bold": true + }, + "number.float": "#99af6b", + "type.builtin": { + "fg": "#4e89a2", + "italic": true + }, + "type.definition": "#4e89a2", + "attribute.builtin": "#ea9875", + "property": "#4e89a2", + "function.builtin": { + "fg": "#fcba81", + "italic": true + }, + "function.call": "#fcba81", + "function.macro": "#d1766e", + "function.method": "#fcba81", + "function.method.call": "#fcba81", + "constructor": "#ea9875", + "constructor.lua": "#d1766e", + "keyword.coroutine": { + "fg": "#d1766e", + "italic": true + }, + "keyword.function": "#d1766e", + "keyword.operator": { + "fg": "#a09384", + "bold": true + }, + "keyword.import": "#d1766e", + "keyword.type": "#4e89a2", + "keyword.modifier": "#4e89a2", + "keyword.repeat": "#d1766e", + "keyword.return": "#20c9cb", + "keyword.debug": "#f4a21c", + "keyword.exception": "#20c9cb", + "keyword.conditional": "#d1766e", + "keyword.conditional.ternary": "#a09384", + "keyword.directive": "#d1766e", + "keyword.directive.define": "#d1766e", + "punctuation.delimiter": "#a09384", + "punctuation.bracket": "#a09384", + "punctuation.special": "#ea9875", + "comment.documentation": "#73665b", + "comment.error": { + "fg": "#e6d5c2", + "bg": "#d25780", + "bold": true + }, + "comment.warning": { + "fg": "#171311", + "bg": "#f4a21c", + "bold": true + }, + "comment.todo": { + "fg": "#171311", + "bg": "#20c9cb", + "bold": true + }, + "comment.note": { + "fg": "#171311", + "bg": "#58bdff", + "bold": true + }, + "diff.plus": "#43b16a", + "diff.minus": "#d25780", + "diff.delta": "#58bdff", + "tag.builtin": "#20c9cb", + "tag.attribute": "#4e89a2", + "tag.delimiter": "#a09384" + } +} diff --git a/themes/charcoal-ember/tui-theme.json b/themes/charcoal-ember/tui-theme.json new file mode 100644 index 0000000..4bb8bf4 --- /dev/null +++ b/themes/charcoal-ember/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#c5c8c6", + "muted": "#969896", + "accent": "#4eb6fe", + "selection": { + "fg": "#c5c8c6", + "bg": "#373b41" + }, + "match": "#ffc400", + "border": "#373b41", + "panel": { + "bg": "#2d2d2d" + }, + "error": "#c90d00", + "warning": "#f79802", + "info": "#4eb6fe", + "success": "#60b45a" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#4eb6fe", + "heading.1": "#4eb6fe", + "heading.2": "#4eb6fe", + "heading.3": "#4eb6fe", + "heading.4": "#4eb6fe", + "heading.5": "#4eb6fe", + "heading.6": "#4eb6fe", + "quote": { + "fg": "#5fb3b3", + "italic": true + }, + "math": "#f79802", + "link": "#f79802", + "link.label": "#f79802", + "link.url": { + "fg": "#f79802", + "underline": true + }, + "raw": "#60b45a", + "raw.block": "#60b45a", + "list": "#969896", + "list.checked": "#60b45a", + "list.unchecked": "#969896" + }, + "syntax": { + "comment": "#969896", + "string": "#60b45a", + "number": "#f79802", + "constant": "#f79802", + "parameter": "#5fb3b3", + "function": "#4eb6fe", + "keyword": "#b294bb", + "type": "#ffc400", + "operator": "#f79802", + "punctuation": "#969896", + "attribute": "#f79802", + "variable": "#c5c8c6", + "tag": "#5fb3b3", + "variable.builtin": { + "fg": "#c90d00", + "italic": true + }, + "variable.parameter": "#5fb3b3", + "variable.member": "#4eb6fe", + "constant.builtin": { + "fg": "#f79802", + "bold": true + }, + "constant.macro": "#b294bb", + "module": "#ffc400", + "module.builtin": "#f79802", + "label": "#c90d00", + "string.documentation": { + "fg": "#60b45a", + "italic": true + }, + "string.regexp": "#5fb3b3", + "string.escape": { + "fg": "#5fb3b3", + "bold": true + }, + "string.special": "#f79802", + "string.special.symbol": "#4eb6fe", + "string.special.url": { + "fg": "#f79802", + "underline": true + }, + "character": "#60b45a", + "character.special": "#f79802", + "boolean": { + "fg": "#f79802", + "bold": true + }, + "number.float": "#f79802", + "type.builtin": { + "fg": "#ffc400", + "italic": true + }, + "type.definition": "#ffc400", + "attribute.builtin": "#f79802", + "property": "#4eb6fe", + "function.builtin": { + "fg": "#4eb6fe", + "italic": true + }, + "function.call": "#4eb6fe", + "function.macro": "#b294bb", + "function.method": "#4eb6fe", + "function.method.call": "#4eb6fe", + "constructor": "#f79802", + "constructor.lua": "#b294bb", + "keyword.coroutine": { + "fg": "#b294bb", + "italic": true + }, + "keyword.function": "#b294bb", + "keyword.operator": { + "fg": "#f79802", + "bold": true + }, + "keyword.import": "#b294bb", + "keyword.type": "#ffc400", + "keyword.modifier": "#ffc400", + "keyword.repeat": "#c90d00", + "keyword.return": "#5fb3b3", + "keyword.debug": "#f79802", + "keyword.exception": "#5fb3b3", + "keyword.conditional": "#c90d00", + "keyword.conditional.ternary": "#f79802", + "keyword.directive": "#b294bb", + "keyword.directive.define": "#b294bb", + "punctuation.delimiter": "#969896", + "punctuation.bracket": "#969896", + "punctuation.special": "#f79802", + "comment.documentation": "#969896", + "comment.error": { + "fg": "#c5c8c6", + "bg": "#c90d00", + "bold": true + }, + "comment.warning": { + "fg": "#1d1f21", + "bg": "#f79802", + "bold": true + }, + "comment.todo": { + "fg": "#1d1f21", + "bg": "#5fb3b3", + "bold": true + }, + "comment.note": { + "fg": "#1d1f21", + "bg": "#4eb6fe", + "bold": true + }, + "diff.plus": "#60b45a", + "diff.minus": "#c90d00", + "diff.delta": "#ffc400", + "tag.builtin": "#5fb3b3", + "tag.attribute": "#4eb6fe", + "tag.delimiter": "#969896" + } +} diff --git a/themes/everforest-dark-hard/tui-theme.json b/themes/everforest-dark-hard/tui-theme.json new file mode 100644 index 0000000..6dbcc10 --- /dev/null +++ b/themes/everforest-dark-hard/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#d3c6aa", + "muted": "#9da9a0", + "accent": "#a7c080", + "selection": { + "fg": "#d3c6aa", + "bg": "#4c3743" + }, + "match": "#dbbc7f", + "border": "#414b50", + "panel": { + "bg": "#2e383c" + }, + "error": "#e67e80", + "warning": "#dbbc7f", + "info": "#7fbbb3", + "success": "#a7c080" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#a7c080", + "heading.1": "#a7c080", + "heading.2": "#a7c080", + "heading.3": "#a7c080", + "heading.4": "#a7c080", + "heading.5": "#a7c080", + "heading.6": "#a7c080", + "quote": { + "fg": "#d3c6aa", + "italic": true + }, + "math": "#d699b6", + "link": "#e69875", + "link.label": "#e69875", + "link.url": { + "fg": "#e69875", + "underline": true + }, + "raw": "#83c092", + "raw.block": "#83c092", + "list": "#859289", + "list.checked": "#a7c080", + "list.unchecked": "#859289" + }, + "syntax": { + "comment": "#859289", + "string": "#83c092", + "number": "#d699b6", + "constant": "#d699b6", + "parameter": "#d3c6aa", + "function": "#a7c080", + "keyword": "#e67e80", + "type": "#dbbc7f", + "operator": "#e69875", + "punctuation": "#859289", + "attribute": "#d699b6", + "variable": "#d3c6aa", + "tag": "#83c092", + "variable.builtin": { + "fg": "#e67e80", + "italic": true + }, + "variable.parameter": "#d3c6aa", + "variable.member": "#7fbbb3", + "constant.builtin": { + "fg": "#d699b6", + "bold": true + }, + "constant.macro": "#d699b6", + "module": "#dbbc7f", + "module.builtin": "#e69875", + "label": "#e67e80", + "string.documentation": { + "fg": "#83c092", + "italic": true + }, + "string.regexp": "#83c092", + "string.escape": { + "fg": "#83c092", + "bold": true + }, + "string.special": "#e69875", + "string.special.symbol": "#7fbbb3", + "string.special.url": { + "fg": "#e69875", + "underline": true + }, + "character": "#83c092", + "character.special": "#e69875", + "boolean": { + "fg": "#d699b6", + "bold": true + }, + "number.float": "#d699b6", + "type.builtin": { + "fg": "#dbbc7f", + "italic": true + }, + "type.definition": "#dbbc7f", + "attribute.builtin": "#e69875", + "property": "#7fbbb3", + "function.builtin": { + "fg": "#a7c080", + "italic": true + }, + "function.call": "#a7c080", + "function.macro": "#d699b6", + "function.method": "#a7c080", + "function.method.call": "#a7c080", + "constructor": "#e69875", + "constructor.lua": "#e67e80", + "keyword.coroutine": { + "fg": "#e67e80", + "italic": true + }, + "keyword.function": "#e67e80", + "keyword.operator": { + "fg": "#e69875", + "bold": true + }, + "keyword.import": "#d699b6", + "keyword.type": "#dbbc7f", + "keyword.modifier": "#dbbc7f", + "keyword.repeat": "#e67e80", + "keyword.return": "#83c092", + "keyword.debug": "#dbbc7f", + "keyword.exception": "#83c092", + "keyword.conditional": "#e67e80", + "keyword.conditional.ternary": "#e69875", + "keyword.directive": "#d699b6", + "keyword.directive.define": "#d699b6", + "punctuation.delimiter": "#859289", + "punctuation.bracket": "#859289", + "punctuation.special": "#e69875", + "comment.documentation": "#859289", + "comment.error": { + "fg": "#d3c6aa", + "bg": "#e67e80", + "bold": true + }, + "comment.warning": { + "fg": "#1e2326", + "bg": "#dbbc7f", + "bold": true + }, + "comment.todo": { + "fg": "#1e2326", + "bg": "#d699b6", + "bold": true + }, + "comment.note": { + "fg": "#1e2326", + "bg": "#7fbbb3", + "bold": true + }, + "diff.plus": "#a7c080", + "diff.minus": "#e67e80", + "diff.delta": "#dbbc7f", + "tag.builtin": "#83c092", + "tag.attribute": "#7fbbb3", + "tag.delimiter": "#859289" + } +} diff --git a/themes/flexoki-moon-black/tui-theme.json b/themes/flexoki-moon-black/tui-theme.json new file mode 100644 index 0000000..c0983da --- /dev/null +++ b/themes/flexoki-moon-black/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#cecdc3", + "muted": "#878580", + "accent": "#3aa99f", + "selection": { + "fg": "#cecdc3", + "bg": "#343331" + }, + "match": "#d0a215", + "border": "#575653", + "panel": { + "bg": "#1c1b1a" + }, + "error": "#d14d41", + "warning": "#da702c", + "info": "#3aa99f", + "success": "#879a39" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#da702c", + "heading.1": "#da702c", + "heading.2": "#da702c", + "heading.3": "#da702c", + "heading.4": "#da702c", + "heading.5": "#da702c", + "heading.6": "#da702c", + "quote": { + "fg": "#8b7ec8", + "italic": true + }, + "math": "#da702c", + "link": "#da702c", + "link.label": "#da702c", + "link.url": { + "fg": "#da702c", + "underline": true + }, + "raw": "#3aa99f", + "raw.block": "#3aa99f", + "list": "#878580", + "list.checked": "#879a39", + "list.unchecked": "#575653" + }, + "syntax": { + "comment": "#878580", + "string": "#3aa99f", + "number": "#8b7ec8", + "constant": "#da702c", + "parameter": "#8b7ec8", + "function": "#da702c", + "keyword": "#879a39", + "type": "#3aa99f", + "operator": "#878580", + "punctuation": "#878580", + "attribute": "#da702c", + "variable": "#cecdc3", + "tag": "#3aa99f", + "variable.builtin": { + "fg": "#d14d41", + "italic": true + }, + "variable.parameter": "#8b7ec8", + "variable.member": "#4385be", + "constant.builtin": { + "fg": "#da702c", + "bold": true + }, + "constant.macro": "#8b7ec8", + "module": "#3aa99f", + "module.builtin": "#da702c", + "label": "#d14d41", + "string.documentation": { + "fg": "#3aa99f", + "italic": true + }, + "string.regexp": "#3aa99f", + "string.escape": { + "fg": "#3aa99f", + "bold": true + }, + "string.special": "#da702c", + "string.special.symbol": "#4385be", + "string.special.url": { + "fg": "#da702c", + "underline": true + }, + "character": "#3aa99f", + "character.special": "#da702c", + "boolean": { + "fg": "#da702c", + "bold": true + }, + "number.float": "#8b7ec8", + "type.builtin": { + "fg": "#3aa99f", + "italic": true + }, + "type.definition": "#3aa99f", + "attribute.builtin": "#da702c", + "property": "#4385be", + "function.builtin": { + "fg": "#da702c", + "italic": true + }, + "function.call": "#da702c", + "function.macro": "#8b7ec8", + "function.method": "#da702c", + "function.method.call": "#da702c", + "constructor": "#da702c", + "constructor.lua": "#879a39", + "keyword.coroutine": { + "fg": "#879a39", + "italic": true + }, + "keyword.function": "#879a39", + "keyword.operator": { + "fg": "#878580", + "bold": true + }, + "keyword.import": "#8b7ec8", + "keyword.type": "#3aa99f", + "keyword.modifier": "#3aa99f", + "keyword.repeat": "#d14d41", + "keyword.return": "#3aa99f", + "keyword.debug": "#da702c", + "keyword.exception": "#3aa99f", + "keyword.conditional": "#d14d41", + "keyword.conditional.ternary": "#878580", + "keyword.directive": "#8b7ec8", + "keyword.directive.define": "#8b7ec8", + "punctuation.delimiter": "#878580", + "punctuation.bracket": "#878580", + "punctuation.special": "#da702c", + "comment.documentation": "#878580", + "comment.error": { + "fg": "#cecdc3", + "bg": "#d14d41", + "bold": true + }, + "comment.warning": { + "fg": "#100f0f", + "bg": "#da702c", + "bold": true + }, + "comment.todo": { + "fg": "#100f0f", + "bg": "#8b7ec8", + "bold": true + }, + "comment.note": { + "fg": "#100f0f", + "bg": "#3aa99f", + "bold": true + }, + "diff.plus": "#66800b", + "diff.minus": "#af3029", + "diff.delta": "#ad8301", + "tag.builtin": "#3aa99f", + "tag.attribute": "#4385be", + "tag.delimiter": "#878580" + } +} diff --git a/themes/flexoki-moon-green/tui-theme.json b/themes/flexoki-moon-green/tui-theme.json new file mode 100644 index 0000000..3aecc2b --- /dev/null +++ b/themes/flexoki-moon-green/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#ddd8e8", + "muted": "#8f8a98", + "accent": "#3aa99f", + "selection": { + "fg": "#ddd8e8", + "bg": "#2c3b2d" + }, + "match": "#d0a215", + "border": "#6b7d6e", + "panel": { + "bg": "#151f18" + }, + "error": "#d14d41", + "warning": "#da702c", + "info": "#3aa99f", + "success": "#879a39" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#da702c", + "heading.1": "#da702c", + "heading.2": "#da702c", + "heading.3": "#da702c", + "heading.4": "#da702c", + "heading.5": "#da702c", + "heading.6": "#da702c", + "quote": { + "fg": "#8b7ec8", + "italic": true + }, + "math": "#da702c", + "link": "#da702c", + "link.label": "#da702c", + "link.url": { + "fg": "#da702c", + "underline": true + }, + "raw": "#3aa99f", + "raw.block": "#3aa99f", + "list": "#8f8a98", + "list.checked": "#879a39", + "list.unchecked": "#6b7d6e" + }, + "syntax": { + "comment": "#8f8a98", + "string": "#3aa99f", + "number": "#8b7ec8", + "constant": "#da702c", + "parameter": "#8b7ec8", + "function": "#da702c", + "keyword": "#879a39", + "type": "#3aa99f", + "operator": "#8f8a98", + "punctuation": "#8f8a98", + "attribute": "#da702c", + "variable": "#ddd8e8", + "tag": "#3aa99f", + "variable.builtin": { + "fg": "#d14d41", + "italic": true + }, + "variable.parameter": "#8b7ec8", + "variable.member": "#4385be", + "constant.builtin": { + "fg": "#da702c", + "bold": true + }, + "constant.macro": "#8b7ec8", + "module": "#3aa99f", + "module.builtin": "#da702c", + "label": "#d14d41", + "string.documentation": { + "fg": "#3aa99f", + "italic": true + }, + "string.regexp": "#3aa99f", + "string.escape": { + "fg": "#3aa99f", + "bold": true + }, + "string.special": "#da702c", + "string.special.symbol": "#4385be", + "string.special.url": { + "fg": "#da702c", + "underline": true + }, + "character": "#3aa99f", + "character.special": "#da702c", + "boolean": { + "fg": "#da702c", + "bold": true + }, + "number.float": "#8b7ec8", + "type.builtin": { + "fg": "#3aa99f", + "italic": true + }, + "type.definition": "#3aa99f", + "attribute.builtin": "#da702c", + "property": "#4385be", + "function.builtin": { + "fg": "#da702c", + "italic": true + }, + "function.call": "#da702c", + "function.macro": "#8b7ec8", + "function.method": "#da702c", + "function.method.call": "#da702c", + "constructor": "#da702c", + "constructor.lua": "#879a39", + "keyword.coroutine": { + "fg": "#879a39", + "italic": true + }, + "keyword.function": "#879a39", + "keyword.operator": { + "fg": "#8f8a98", + "bold": true + }, + "keyword.import": "#8b7ec8", + "keyword.type": "#3aa99f", + "keyword.modifier": "#3aa99f", + "keyword.repeat": "#d14d41", + "keyword.return": "#3aa99f", + "keyword.debug": "#da702c", + "keyword.exception": "#3aa99f", + "keyword.conditional": "#d14d41", + "keyword.conditional.ternary": "#8f8a98", + "keyword.directive": "#8b7ec8", + "keyword.directive.define": "#8b7ec8", + "punctuation.delimiter": "#8f8a98", + "punctuation.bracket": "#8f8a98", + "punctuation.special": "#da702c", + "comment.documentation": "#8f8a98", + "comment.error": { + "fg": "#ddd8e8", + "bg": "#d14d41", + "bold": true + }, + "comment.warning": { + "fg": "#08120b", + "bg": "#da702c", + "bold": true + }, + "comment.todo": { + "fg": "#08120b", + "bg": "#8b7ec8", + "bold": true + }, + "comment.note": { + "fg": "#08120b", + "bg": "#3aa99f", + "bold": true + }, + "diff.plus": "#66800b", + "diff.minus": "#af3029", + "diff.delta": "#ad8301", + "tag.builtin": "#3aa99f", + "tag.attribute": "#4385be", + "tag.delimiter": "#8f8a98" + } +} diff --git a/themes/flexoki-moon-purple/tui-theme.json b/themes/flexoki-moon-purple/tui-theme.json new file mode 100644 index 0000000..37351b2 --- /dev/null +++ b/themes/flexoki-moon-purple/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#ddd8e8", + "muted": "#8f8a98", + "accent": "#3aa99f", + "selection": { + "fg": "#ddd8e8", + "bg": "#252330" + }, + "match": "#d0a215", + "border": "#625f68", + "panel": { + "bg": "#1c1a25" + }, + "error": "#d14d41", + "warning": "#da702c", + "info": "#3aa99f", + "success": "#879a39" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#da702c", + "heading.1": "#da702c", + "heading.2": "#da702c", + "heading.3": "#da702c", + "heading.4": "#da702c", + "heading.5": "#da702c", + "heading.6": "#da702c", + "quote": { + "fg": "#8b7ec8", + "italic": true + }, + "math": "#da702c", + "link": "#da702c", + "link.label": "#da702c", + "link.url": { + "fg": "#da702c", + "underline": true + }, + "raw": "#3aa99f", + "raw.block": "#3aa99f", + "list": "#8f8a98", + "list.checked": "#879a39", + "list.unchecked": "#625f68" + }, + "syntax": { + "comment": "#8f8a98", + "string": "#3aa99f", + "number": "#8b7ec8", + "constant": "#da702c", + "parameter": "#8b7ec8", + "function": "#da702c", + "keyword": "#879a39", + "type": "#3aa99f", + "operator": "#8f8a98", + "punctuation": "#8f8a98", + "attribute": "#da702c", + "variable": "#ddd8e8", + "tag": "#3aa99f", + "variable.builtin": { + "fg": "#d14d41", + "italic": true + }, + "variable.parameter": "#8b7ec8", + "variable.member": "#4385be", + "constant.builtin": { + "fg": "#da702c", + "bold": true + }, + "constant.macro": "#8b7ec8", + "module": "#3aa99f", + "module.builtin": "#da702c", + "label": "#d14d41", + "string.documentation": { + "fg": "#3aa99f", + "italic": true + }, + "string.regexp": "#3aa99f", + "string.escape": { + "fg": "#3aa99f", + "bold": true + }, + "string.special": "#da702c", + "string.special.symbol": "#4385be", + "string.special.url": { + "fg": "#da702c", + "underline": true + }, + "character": "#3aa99f", + "character.special": "#da702c", + "boolean": { + "fg": "#da702c", + "bold": true + }, + "number.float": "#8b7ec8", + "type.builtin": { + "fg": "#3aa99f", + "italic": true + }, + "type.definition": "#3aa99f", + "attribute.builtin": "#da702c", + "property": "#4385be", + "function.builtin": { + "fg": "#da702c", + "italic": true + }, + "function.call": "#da702c", + "function.macro": "#8b7ec8", + "function.method": "#da702c", + "function.method.call": "#da702c", + "constructor": "#da702c", + "constructor.lua": "#879a39", + "keyword.coroutine": { + "fg": "#879a39", + "italic": true + }, + "keyword.function": "#879a39", + "keyword.operator": { + "fg": "#8f8a98", + "bold": true + }, + "keyword.import": "#8b7ec8", + "keyword.type": "#3aa99f", + "keyword.modifier": "#3aa99f", + "keyword.repeat": "#d14d41", + "keyword.return": "#3aa99f", + "keyword.debug": "#da702c", + "keyword.exception": "#3aa99f", + "keyword.conditional": "#d14d41", + "keyword.conditional.ternary": "#8f8a98", + "keyword.directive": "#8b7ec8", + "keyword.directive.define": "#8b7ec8", + "punctuation.delimiter": "#8f8a98", + "punctuation.bracket": "#8f8a98", + "punctuation.special": "#da702c", + "comment.documentation": "#8f8a98", + "comment.error": { + "fg": "#ddd8e8", + "bg": "#d14d41", + "bold": true + }, + "comment.warning": { + "fg": "#12101d", + "bg": "#da702c", + "bold": true + }, + "comment.todo": { + "fg": "#12101d", + "bg": "#8b7ec8", + "bold": true + }, + "comment.note": { + "fg": "#12101d", + "bg": "#3aa99f", + "bold": true + }, + "diff.plus": "#66800b", + "diff.minus": "#af3029", + "diff.delta": "#ad8301", + "tag.builtin": "#3aa99f", + "tag.attribute": "#4385be", + "tag.delimiter": "#8f8a98" + } +} diff --git a/themes/flexoki-moon-red/tui-theme.json b/themes/flexoki-moon-red/tui-theme.json new file mode 100644 index 0000000..830f8e6 --- /dev/null +++ b/themes/flexoki-moon-red/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#f0e8dd", + "muted": "#b5967e", + "accent": "#3aa99f", + "selection": { + "fg": "#f0e8dd", + "bg": "#42322e" + }, + "match": "#d0a215", + "border": "#8a6b60", + "panel": { + "bg": "#251a1a" + }, + "error": "#d14d41", + "warning": "#da702c", + "info": "#3aa99f", + "success": "#879a39" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#da702c", + "heading.1": "#da702c", + "heading.2": "#da702c", + "heading.3": "#da702c", + "heading.4": "#da702c", + "heading.5": "#da702c", + "heading.6": "#da702c", + "quote": { + "fg": "#8b7ec8", + "italic": true + }, + "math": "#da702c", + "link": "#da702c", + "link.label": "#da702c", + "link.url": { + "fg": "#da702c", + "underline": true + }, + "raw": "#3aa99f", + "raw.block": "#3aa99f", + "list": "#b5967e", + "list.checked": "#879a39", + "list.unchecked": "#8a6b60" + }, + "syntax": { + "comment": "#b5967e", + "string": "#3aa99f", + "number": "#8b7ec8", + "constant": "#da702c", + "parameter": "#8b7ec8", + "function": "#da702c", + "keyword": "#879a39", + "type": "#3aa99f", + "operator": "#b5967e", + "punctuation": "#b5967e", + "attribute": "#da702c", + "variable": "#f0e8dd", + "tag": "#3aa99f", + "variable.builtin": { + "fg": "#d14d41", + "italic": true + }, + "variable.parameter": "#8b7ec8", + "variable.member": "#4385be", + "constant.builtin": { + "fg": "#da702c", + "bold": true + }, + "constant.macro": "#8b7ec8", + "module": "#3aa99f", + "module.builtin": "#da702c", + "label": "#d14d41", + "string.documentation": { + "fg": "#3aa99f", + "italic": true + }, + "string.regexp": "#3aa99f", + "string.escape": { + "fg": "#3aa99f", + "bold": true + }, + "string.special": "#da702c", + "string.special.symbol": "#4385be", + "string.special.url": { + "fg": "#da702c", + "underline": true + }, + "character": "#3aa99f", + "character.special": "#da702c", + "boolean": { + "fg": "#da702c", + "bold": true + }, + "number.float": "#8b7ec8", + "type.builtin": { + "fg": "#3aa99f", + "italic": true + }, + "type.definition": "#3aa99f", + "attribute.builtin": "#da702c", + "property": "#4385be", + "function.builtin": { + "fg": "#da702c", + "italic": true + }, + "function.call": "#da702c", + "function.macro": "#8b7ec8", + "function.method": "#da702c", + "function.method.call": "#da702c", + "constructor": "#da702c", + "constructor.lua": "#879a39", + "keyword.coroutine": { + "fg": "#879a39", + "italic": true + }, + "keyword.function": "#879a39", + "keyword.operator": { + "fg": "#b5967e", + "bold": true + }, + "keyword.import": "#8b7ec8", + "keyword.type": "#3aa99f", + "keyword.modifier": "#3aa99f", + "keyword.repeat": "#d14d41", + "keyword.return": "#3aa99f", + "keyword.debug": "#da702c", + "keyword.exception": "#3aa99f", + "keyword.conditional": "#d14d41", + "keyword.conditional.ternary": "#b5967e", + "keyword.directive": "#8b7ec8", + "keyword.directive.define": "#8b7ec8", + "punctuation.delimiter": "#b5967e", + "punctuation.bracket": "#b5967e", + "punctuation.special": "#da702c", + "comment.documentation": "#b5967e", + "comment.error": { + "fg": "#f0e8dd", + "bg": "#d14d41", + "bold": true + }, + "comment.warning": { + "fg": "#18090b", + "bg": "#da702c", + "bold": true + }, + "comment.todo": { + "fg": "#18090b", + "bg": "#8b7ec8", + "bold": true + }, + "comment.note": { + "fg": "#18090b", + "bg": "#3aa99f", + "bold": true + }, + "diff.plus": "#66800b", + "diff.minus": "#af3029", + "diff.delta": "#ad8301", + "tag.builtin": "#3aa99f", + "tag.attribute": "#4385be", + "tag.delimiter": "#b5967e" + } +} diff --git a/themes/gruvbox/tui-theme.json b/themes/gruvbox/tui-theme.json new file mode 100644 index 0000000..658de17 --- /dev/null +++ b/themes/gruvbox/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#ebdbb2", + "muted": "#928374", + "accent": "#83a598", + "selection": { + "fg": "#ebdbb2", + "bg": "#504945" + }, + "match": "#fabd2f", + "border": "#504945", + "panel": { + "bg": "#3c3836" + }, + "error": "#fb4934", + "warning": "#fabd2f", + "info": "#83a598", + "success": "#b8bb26" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#b8bb26", + "heading.1": "#b8bb26", + "heading.2": "#b8bb26", + "heading.3": "#b8bb26", + "heading.4": "#b8bb26", + "heading.5": "#b8bb26", + "heading.6": "#b8bb26", + "quote": { + "fg": "#83a598", + "italic": true + }, + "math": "#fe8019", + "link": "#fe8019", + "link.label": "#fe8019", + "link.url": { + "fg": "#fe8019", + "underline": true + }, + "raw": "#b8bb26", + "raw.block": "#b8bb26", + "list": "#fe8019", + "list.checked": "#b8bb26", + "list.unchecked": "#665c54" + }, + "syntax": { + "comment": "#928374", + "string": "#b8bb26", + "number": "#d3869b", + "constant": "#fe8019", + "parameter": "#83a598", + "function": "#b8bb26", + "keyword": "#fb4934", + "type": "#fabd2f", + "operator": "#fe8019", + "punctuation": "#fe8019", + "attribute": "#fe8019", + "variable": "#ebdbb2", + "tag": "#8ec07c", + "variable.builtin": { + "fg": "#fb4934", + "italic": true + }, + "variable.parameter": "#83a598", + "variable.member": "#83a598", + "constant.builtin": { + "fg": "#fe8019", + "bold": true + }, + "constant.macro": "#8ec07c", + "module": "#fabd2f", + "module.builtin": "#fe8019", + "label": "#fb4934", + "string.documentation": { + "fg": "#b8bb26", + "italic": true + }, + "string.regexp": "#8ec07c", + "string.escape": { + "fg": "#8ec07c", + "bold": true + }, + "string.special": "#fe8019", + "string.special.symbol": "#83a598", + "string.special.url": { + "fg": "#fe8019", + "underline": true + }, + "character": "#b8bb26", + "character.special": "#fe8019", + "boolean": { + "fg": "#fe8019", + "bold": true + }, + "number.float": "#d3869b", + "type.builtin": { + "fg": "#fabd2f", + "italic": true + }, + "type.definition": "#fabd2f", + "attribute.builtin": "#fe8019", + "property": "#83a598", + "function.builtin": { + "fg": "#b8bb26", + "italic": true + }, + "function.call": "#b8bb26", + "function.macro": "#8ec07c", + "function.method": "#b8bb26", + "function.method.call": "#b8bb26", + "constructor": "#fe8019", + "constructor.lua": "#fb4934", + "keyword.coroutine": { + "fg": "#fb4934", + "italic": true + }, + "keyword.function": "#fb4934", + "keyword.operator": { + "fg": "#fe8019", + "bold": true + }, + "keyword.import": "#8ec07c", + "keyword.type": "#fabd2f", + "keyword.modifier": "#fabd2f", + "keyword.repeat": "#fb4934", + "keyword.return": "#8ec07c", + "keyword.debug": "#fabd2f", + "keyword.exception": "#8ec07c", + "keyword.conditional": "#fb4934", + "keyword.conditional.ternary": "#fe8019", + "keyword.directive": "#8ec07c", + "keyword.directive.define": "#8ec07c", + "punctuation.delimiter": "#fe8019", + "punctuation.bracket": "#fe8019", + "punctuation.special": "#fe8019", + "comment.documentation": "#928374", + "comment.error": { + "fg": "#ebdbb2", + "bg": "#fb4934", + "bold": true + }, + "comment.warning": { + "fg": "#1d2021", + "bg": "#fabd2f", + "bold": true + }, + "comment.todo": { + "fg": "#1d2021", + "bg": "#8ec07c", + "bold": true + }, + "comment.note": { + "fg": "#1d2021", + "bg": "#83a598", + "bold": true + }, + "diff.plus": "#b8bb26", + "diff.minus": "#fb4934", + "diff.delta": "#fe8019", + "tag.builtin": "#8ec07c", + "tag.attribute": "#83a598", + "tag.delimiter": "#fe8019" + } +} diff --git a/themes/kanagawa/tui-theme.json b/themes/kanagawa/tui-theme.json new file mode 100644 index 0000000..29fcee1 --- /dev/null +++ b/themes/kanagawa/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#dcd7ba", + "muted": "#c8c093", + "accent": "#7e9cd8", + "selection": { + "fg": "#c8c093", + "bg": "#2d4f67" + }, + "match": "#c0a36e", + "border": "#54546d", + "panel": { + "bg": "#16161d" + }, + "error": "#e82424", + "warning": "#ff9e3b", + "info": "#658594", + "success": "#98bb6c" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#7e9cd8", + "heading.1": "#7e9cd8", + "heading.2": "#7e9cd8", + "heading.3": "#7e9cd8", + "heading.4": "#7e9cd8", + "heading.5": "#7e9cd8", + "heading.6": "#7e9cd8", + "quote": { + "fg": "#b8b4d0", + "italic": true + }, + "math": "#7fb4ca", + "link": "#ffa066", + "link.label": "#ffa066", + "link.url": { + "fg": "#ffa066", + "underline": true + }, + "raw": "#98bb6c", + "raw.block": "#98bb6c", + "list": "#9cabca", + "list.checked": "#98bb6c", + "list.unchecked": "#727169" + }, + "syntax": { + "comment": "#727169", + "string": "#98bb6c", + "number": "#d27e99", + "constant": "#7fb4ca", + "parameter": "#b8b4d0", + "function": "#7e9cd8", + "keyword": "#957fb8", + "type": "#7aa89f", + "operator": "#c0a36e", + "punctuation": "#9cabca", + "attribute": "#7fb4ca", + "variable": "#dcd7ba", + "tag": "#6a9589", + "variable.builtin": { + "fg": "#c34043", + "italic": true + }, + "variable.parameter": "#b8b4d0", + "variable.member": "#7e9cd8", + "constant.builtin": { + "fg": "#7fb4ca", + "bold": true + }, + "constant.macro": "#e46876", + "module": "#7aa89f", + "module.builtin": "#ffa066", + "label": "#c34043", + "string.documentation": { + "fg": "#98bb6c", + "italic": true + }, + "string.regexp": "#6a9589", + "string.escape": { + "fg": "#6a9589", + "bold": true + }, + "string.special": "#ffa066", + "string.special.symbol": "#7e9cd8", + "string.special.url": { + "fg": "#ffa066", + "underline": true + }, + "character": "#98bb6c", + "character.special": "#ffa066", + "boolean": { + "fg": "#7fb4ca", + "bold": true + }, + "number.float": "#d27e99", + "type.builtin": { + "fg": "#7aa89f", + "italic": true + }, + "type.definition": "#7aa89f", + "attribute.builtin": "#ffa066", + "property": "#7e9cd8", + "function.builtin": { + "fg": "#7e9cd8", + "italic": true + }, + "function.call": "#7e9cd8", + "function.macro": "#e46876", + "function.method": "#7e9cd8", + "function.method.call": "#7e9cd8", + "constructor": "#ffa066", + "constructor.lua": "#957fb8", + "keyword.coroutine": { + "fg": "#957fb8", + "italic": true + }, + "keyword.function": "#957fb8", + "keyword.operator": { + "fg": "#c0a36e", + "bold": true + }, + "keyword.import": "#e46876", + "keyword.type": "#7aa89f", + "keyword.modifier": "#7aa89f", + "keyword.repeat": "#c34043", + "keyword.return": "#6a9589", + "keyword.debug": "#ff9e3b", + "keyword.exception": "#6a9589", + "keyword.conditional": "#c34043", + "keyword.conditional.ternary": "#c0a36e", + "keyword.directive": "#e46876", + "keyword.directive.define": "#e46876", + "punctuation.delimiter": "#9cabca", + "punctuation.bracket": "#9cabca", + "punctuation.special": "#ffa066", + "comment.documentation": "#727169", + "comment.error": { + "fg": "#dcd7ba", + "bg": "#e82424", + "bold": true + }, + "comment.warning": { + "fg": "#1f1f28", + "bg": "#ff9e3b", + "bold": true + }, + "comment.todo": { + "fg": "#1f1f28", + "bg": "#6a9589", + "bold": true + }, + "comment.note": { + "fg": "#1f1f28", + "bg": "#658594", + "bold": true + }, + "diff.plus": "#76946a", + "diff.minus": "#c34043", + "diff.delta": "#dca561", + "tag.builtin": "#6a9589", + "tag.attribute": "#7e9cd8", + "tag.delimiter": "#9cabca" + } +} diff --git a/themes/nightfox/tui-theme.json b/themes/nightfox/tui-theme.json new file mode 100644 index 0000000..d269366 --- /dev/null +++ b/themes/nightfox/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#cdcecf", + "muted": "#71839b", + "accent": "#719cd6", + "selection": { + "fg": "#cdcecf", + "bg": "#2b3b51" + }, + "match": "#dbc074", + "border": "#39506d", + "panel": { + "bg": "#131a24" + }, + "error": "#c94f6d", + "warning": "#dbc074", + "info": "#719cd6", + "success": "#81b29a" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#86abdc", + "heading.1": "#86abdc", + "heading.2": "#86abdc", + "heading.3": "#86abdc", + "heading.4": "#86abdc", + "heading.5": "#86abdc", + "heading.6": "#86abdc", + "quote": { + "fg": "#7ad5d6", + "italic": true + }, + "math": "#f6b079", + "link": "#f4a261", + "link.label": "#f4a261", + "link.url": { + "fg": "#f4a261", + "underline": true + }, + "raw": "#81b29a", + "raw.block": "#81b29a", + "list": "#aeafb0", + "list.checked": "#81b29a", + "list.unchecked": "#738091" + }, + "syntax": { + "comment": "#738091", + "string": "#81b29a", + "number": "#f4a261", + "constant": "#f6b079", + "parameter": "#7ad5d6", + "function": "#86abdc", + "keyword": "#9d79d6", + "type": "#dbc074", + "operator": "#aeafb0", + "punctuation": "#aeafb0", + "attribute": "#f6b079", + "variable": "#cdcecf", + "tag": "#63cdcf", + "variable.builtin": { + "fg": "#c94f6d", + "italic": true + }, + "variable.parameter": "#7ad5d6", + "variable.member": "#719cd6", + "constant.builtin": { + "fg": "#f6b079", + "bold": true + }, + "constant.macro": "#dc8ed9", + "module": "#dbc074", + "module.builtin": "#f4a261", + "label": "#c94f6d", + "string.documentation": { + "fg": "#81b29a", + "italic": true + }, + "string.regexp": "#e0c988", + "string.escape": { + "fg": "#e0c988", + "bold": true + }, + "string.special": "#f4a261", + "string.special.symbol": "#719cd6", + "string.special.url": { + "fg": "#f4a261", + "underline": true + }, + "character": "#81b29a", + "character.special": "#f4a261", + "boolean": { + "fg": "#f6b079", + "bold": true + }, + "number.float": "#f4a261", + "type.builtin": { + "fg": "#dbc074", + "italic": true + }, + "type.definition": "#dbc074", + "attribute.builtin": "#f4a261", + "property": "#719cd6", + "function.builtin": { + "fg": "#86abdc", + "italic": true + }, + "function.call": "#86abdc", + "function.macro": "#dc8ed9", + "function.method": "#86abdc", + "function.method.call": "#86abdc", + "constructor": "#f4a261", + "constructor.lua": "#9d79d6", + "keyword.coroutine": { + "fg": "#9d79d6", + "italic": true + }, + "keyword.function": "#9d79d6", + "keyword.operator": { + "fg": "#aeafb0", + "bold": true + }, + "keyword.import": "#dc8ed9", + "keyword.type": "#dbc074", + "keyword.modifier": "#dbc074", + "keyword.repeat": "#c94f6d", + "keyword.return": "#63cdcf", + "keyword.debug": "#dbc074", + "keyword.exception": "#63cdcf", + "keyword.conditional": "#c94f6d", + "keyword.conditional.ternary": "#aeafb0", + "keyword.directive": "#dc8ed9", + "keyword.directive.define": "#dc8ed9", + "punctuation.delimiter": "#aeafb0", + "punctuation.bracket": "#aeafb0", + "punctuation.special": "#f4a261", + "comment.documentation": "#738091", + "comment.error": { + "fg": "#cdcecf", + "bg": "#c94f6d", + "bold": true + }, + "comment.warning": { + "fg": "#192330", + "bg": "#dbc074", + "bold": true + }, + "comment.todo": { + "fg": "#192330", + "bg": "#81b29a", + "bold": true + }, + "comment.note": { + "fg": "#192330", + "bg": "#719cd6", + "bold": true + }, + "diff.plus": "#81b29a", + "diff.minus": "#c94f6d", + "diff.delta": "#dbc074", + "tag.builtin": "#63cdcf", + "tag.attribute": "#719cd6", + "tag.delimiter": "#aeafb0" + } +} diff --git a/themes/nordic/tui-theme.json b/themes/nordic/tui-theme.json new file mode 100644 index 0000000..b31c247 --- /dev/null +++ b/themes/nordic/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#BBC3D4", + "muted": "#60728A", + "accent": "#88C0D0", + "selection": { + "fg": "#D8DEE9", + "bg": "#3B4252" + }, + "match": "#EBCB8B", + "border": "#191D24", + "panel": { + "bg": "#191D24" + }, + "error": "#C5727A", + "warning": "#EBCB8B", + "info": "#88C0D0", + "success": "#A3BE8C" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#88C0D0", + "heading.1": "#88C0D0", + "heading.2": "#88C0D0", + "heading.3": "#88C0D0", + "heading.4": "#88C0D0", + "heading.5": "#88C0D0", + "heading.6": "#88C0D0", + "quote": { + "fg": "#c0c8d8", + "italic": true + }, + "math": "#be9db8", + "link": "#D08770", + "link.label": "#D08770", + "link.url": { + "fg": "#D08770", + "underline": true + }, + "raw": "#A3BE8C", + "raw.block": "#A3BE8C", + "list": "#60728a", + "list.checked": "#A3BE8C", + "list.unchecked": "#4C566A" + }, + "syntax": { + "comment": "#4C566A", + "string": "#A3BE8C", + "number": "#be9db8", + "constant": "#be9db8", + "parameter": "#c0c8d8", + "function": "#88C0D0", + "keyword": "#d08770", + "type": "#ebcb8b", + "operator": "#c0c8d8", + "punctuation": "#60728a", + "attribute": "#be9db8", + "variable": "#BBC3D4", + "tag": "#8FBCBB", + "variable.builtin": { + "fg": "#BF616A", + "italic": true + }, + "variable.parameter": "#c0c8d8", + "variable.member": "#81A1C1", + "constant.builtin": { + "fg": "#be9db8", + "bold": true + }, + "constant.macro": "#bf616a", + "module": "#ebcb8b", + "module.builtin": "#D08770", + "label": "#BF616A", + "string.documentation": { + "fg": "#A3BE8C", + "italic": true + }, + "string.regexp": "#8FBCBB", + "string.escape": { + "fg": "#8FBCBB", + "bold": true + }, + "string.special": "#D08770", + "string.special.symbol": "#81A1C1", + "string.special.url": { + "fg": "#D08770", + "underline": true + }, + "character": "#A3BE8C", + "character.special": "#D08770", + "boolean": { + "fg": "#be9db8", + "bold": true + }, + "number.float": "#be9db8", + "type.builtin": { + "fg": "#ebcb8b", + "italic": true + }, + "type.definition": "#ebcb8b", + "attribute.builtin": "#D08770", + "property": "#81A1C1", + "function.builtin": { + "fg": "#88C0D0", + "italic": true + }, + "function.call": "#88C0D0", + "function.macro": "#bf616a", + "function.method": "#88C0D0", + "function.method.call": "#88C0D0", + "constructor": "#D08770", + "constructor.lua": "#d08770", + "keyword.coroutine": { + "fg": "#d08770", + "italic": true + }, + "keyword.function": "#d08770", + "keyword.operator": { + "fg": "#c0c8d8", + "bold": true + }, + "keyword.import": "#bf616a", + "keyword.type": "#ebcb8b", + "keyword.modifier": "#ebcb8b", + "keyword.repeat": "#BF616A", + "keyword.return": "#8FBCBB", + "keyword.debug": "#EBCB8B", + "keyword.exception": "#8FBCBB", + "keyword.conditional": "#BF616A", + "keyword.conditional.ternary": "#c0c8d8", + "keyword.directive": "#bf616a", + "keyword.directive.define": "#bf616a", + "punctuation.delimiter": "#60728a", + "punctuation.bracket": "#60728a", + "punctuation.special": "#D08770", + "comment.documentation": "#4C566A", + "comment.error": { + "fg": "#BBC3D4", + "bg": "#C5727A", + "bold": true + }, + "comment.warning": { + "fg": "#242933", + "bg": "#EBCB8B", + "bold": true + }, + "comment.todo": { + "fg": "#242933", + "bg": "#B1C89D", + "bold": true + }, + "comment.note": { + "fg": "#242933", + "bg": "#88C0D0", + "bold": true + }, + "diff.plus": "#A3BE8C", + "diff.minus": "#BF616A", + "diff.delta": "#81A1C1", + "tag.builtin": "#8FBCBB", + "tag.attribute": "#81A1C1", + "tag.delimiter": "#60728a" + } +} diff --git a/themes/oceanic-next/tui-theme.json b/themes/oceanic-next/tui-theme.json new file mode 100644 index 0000000..cfc0687 --- /dev/null +++ b/themes/oceanic-next/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#c0c5ce", + "muted": "#ffffff", + "accent": "#6699cc", + "selection": { + "fg": "#c0c5ce", + "bg": "#4f5b66" + }, + "match": "#fac863", + "border": "#343d46", + "panel": { + "bg": "#65737e" + }, + "error": "#ec5f67", + "warning": "#fce094", + "info": "#6699cc", + "success": "#99c794" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#6699cc", + "heading.1": "#6699cc", + "heading.2": "#6699cc", + "heading.3": "#6699cc", + "heading.4": "#6699cc", + "heading.5": "#6699cc", + "heading.6": "#6699cc", + "quote": { + "fg": "#cdd3de", + "italic": true + }, + "math": "#62b3b2", + "link": "#ec5f67", + "link.label": "#ec5f67", + "link.url": { + "fg": "#ec5f67", + "underline": true + }, + "raw": "#99c794", + "raw.block": "#99c794", + "list": "#62b3b2", + "list.checked": "#99c794", + "list.unchecked": "#65737e" + }, + "syntax": { + "comment": "#65737e", + "string": "#99c794", + "number": "#f99157", + "constant": "#62b3b2", + "parameter": "#cdd3de", + "function": "#6699cc", + "keyword": "#c594c5", + "type": "#fac863", + "operator": "#f99157", + "punctuation": "#62b3b2", + "attribute": "#62b3b2", + "variable": "#c0c5ce", + "tag": "#5fb3b3", + "variable.builtin": { + "fg": "#ec5f67", + "italic": true + }, + "variable.parameter": "#cdd3de", + "variable.member": "#6699cc", + "constant.builtin": { + "fg": "#62b3b2", + "bold": true + }, + "constant.macro": "#fac863", + "module": "#fac863", + "module.builtin": "#ec5f67", + "label": "#ec5f67", + "string.documentation": { + "fg": "#99c794", + "italic": true + }, + "string.regexp": "#5fb3b3", + "string.escape": { + "fg": "#5fb3b3", + "bold": true + }, + "string.special": "#ec5f67", + "string.special.symbol": "#6699cc", + "string.special.url": { + "fg": "#ec5f67", + "underline": true + }, + "character": "#99c794", + "character.special": "#ec5f67", + "boolean": { + "fg": "#62b3b2", + "bold": true + }, + "number.float": "#f99157", + "type.builtin": { + "fg": "#fac863", + "italic": true + }, + "type.definition": "#fac863", + "attribute.builtin": "#ec5f67", + "property": "#6699cc", + "function.builtin": { + "fg": "#6699cc", + "italic": true + }, + "function.call": "#6699cc", + "function.macro": "#fac863", + "function.method": "#6699cc", + "function.method.call": "#6699cc", + "constructor": "#ec5f67", + "constructor.lua": "#c594c5", + "keyword.coroutine": { + "fg": "#c594c5", + "italic": true + }, + "keyword.function": "#c594c5", + "keyword.operator": { + "fg": "#f99157", + "bold": true + }, + "keyword.import": "#fac863", + "keyword.type": "#fac863", + "keyword.modifier": "#fac863", + "keyword.repeat": "#ec5f67", + "keyword.return": "#5fb3b3", + "keyword.debug": "#fce094", + "keyword.exception": "#5fb3b3", + "keyword.conditional": "#ec5f67", + "keyword.conditional.ternary": "#f99157", + "keyword.directive": "#fac863", + "keyword.directive.define": "#fac863", + "punctuation.delimiter": "#62b3b2", + "punctuation.bracket": "#62b3b2", + "punctuation.special": "#ec5f67", + "comment.documentation": "#65737e", + "comment.error": { + "fg": "#c0c5ce", + "bg": "#ec5f67", + "bold": true + }, + "comment.warning": { + "fg": "#162c35", + "bg": "#fce094", + "bold": true + }, + "comment.todo": { + "fg": "#162c35", + "bg": "#a6dbff", + "bold": true + }, + "comment.note": { + "fg": "#162c35", + "bg": "#6699cc", + "bold": true + }, + "diff.plus": "#99c794", + "diff.minus": "#ec5f67", + "diff.delta": "#fac863", + "tag.builtin": "#5fb3b3", + "tag.attribute": "#6699cc", + "tag.delimiter": "#62b3b2" + } +} diff --git a/themes/popping-and-locking/tui-theme.json b/themes/popping-and-locking/tui-theme.json new file mode 100644 index 0000000..12ae6fb --- /dev/null +++ b/themes/popping-and-locking/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#ebdbb2", + "muted": "#a89984", + "accent": "#458588", + "selection": { + "fg": "#928374", + "bg": "#383637" + }, + "match": "#d79921", + "border": "#ebdbb2", + "panel": { + "bg": "#252631" + }, + "error": "#cc5351", + "warning": "#e1656a", + "info": "#689d6a", + "success": "#7fc678" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#fabd2f", + "heading.1": "#fabd2f", + "heading.2": "#fabd2f", + "heading.3": "#fabd2f", + "heading.4": "#fabd2f", + "heading.5": "#fabd2f", + "heading.6": "#fabd2f", + "quote": { + "fg": "#99c6ca", + "italic": true + }, + "math": "#d3869b", + "link": "#f2883f", + "link.label": "#f2883f", + "link.url": { + "fg": "#f2883f", + "underline": true + }, + "raw": "#92d3a3", + "raw.block": "#92d3a3", + "list": "#c59d5d", + "list.checked": "#7fc678", + "list.unchecked": "#928374" + }, + "syntax": { + "comment": "#7a7064", + "string": "#92d3a3", + "number": "#d3869b", + "constant": "#d3869b", + "parameter": "#99c6ca", + "function": "#fabd2f", + "keyword": "#e1656a", + "type": "#f2883f", + "operator": "#a89984", + "punctuation": "#c59d5d", + "attribute": "#d3869b", + "variable": "#ebdbb2", + "tag": "#e1656a", + "variable.builtin": { + "fg": "#d3869b", + "italic": true + }, + "variable.parameter": "#99c6ca", + "variable.member": "#4fa1a5", + "constant.builtin": { + "fg": "#d3869b", + "bold": true + }, + "constant.macro": "#e1656a", + "module": "#f2883f", + "module.builtin": "#f2883f", + "label": "#e1656a", + "string.documentation": { + "fg": "#92d3a3", + "italic": true + }, + "string.regexp": "#f2883f", + "string.escape": { + "fg": "#f2883f", + "bold": true + }, + "string.special": "#f2883f", + "string.special.symbol": "#4fa1a5", + "string.special.url": { + "fg": "#f2883f", + "underline": true + }, + "character": "#92d3a3", + "character.special": "#f2883f", + "boolean": { + "fg": "#d3869b", + "bold": true + }, + "number.float": "#d3869b", + "type.builtin": { + "fg": "#f2883f", + "italic": true + }, + "type.definition": "#f2883f", + "attribute.builtin": "#f2883f", + "property": "#4fa1a5", + "function.builtin": { + "fg": "#fabd2f", + "italic": true + }, + "function.call": "#fabd2f", + "function.macro": "#e1656a", + "function.method": "#fabd2f", + "function.method.call": "#fabd2f", + "constructor": "#f2883f", + "constructor.lua": "#e1656a", + "keyword.coroutine": { + "fg": "#e1656a", + "italic": true + }, + "keyword.function": "#e1656a", + "keyword.operator": { + "fg": "#a89984", + "bold": true + }, + "keyword.import": "#e1656a", + "keyword.type": "#f2883f", + "keyword.modifier": "#f2883f", + "keyword.repeat": "#e1656a", + "keyword.return": "#e1656a", + "keyword.debug": "#e1656a", + "keyword.exception": "#e1656a", + "keyword.conditional": "#e1656a", + "keyword.conditional.ternary": "#a89984", + "keyword.directive": "#e1656a", + "keyword.directive.define": "#e1656a", + "punctuation.delimiter": "#c59d5d", + "punctuation.bracket": "#c59d5d", + "punctuation.special": "#f2883f", + "comment.documentation": "#7a7064", + "comment.error": { + "fg": "#ebdbb2", + "bg": "#cc5351", + "bold": true + }, + "comment.warning": { + "fg": "#181921", + "bg": "#e1656a", + "bold": true + }, + "comment.todo": { + "fg": "#181921", + "bg": "#689d6a", + "bold": true + }, + "comment.note": { + "fg": "#181921", + "bg": "#689d6a", + "bold": true + }, + "diff.plus": "#63ac6f", + "diff.minus": "#cc5351", + "diff.delta": "#d79921", + "tag.builtin": "#e1656a", + "tag.attribute": "#4fa1a5", + "tag.delimiter": "#c59d5d" + } +} diff --git a/themes/retrobox/tui-theme.json b/themes/retrobox/tui-theme.json new file mode 100644 index 0000000..810eb53 --- /dev/null +++ b/themes/retrobox/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#ebdbb2", + "muted": "#a89984", + "accent": "#83a598", + "selection": { + "fg": "#ebdbb2", + "bg": "#504945" + }, + "match": "#fabd2f", + "border": "#504945", + "panel": { + "bg": "#3c3836" + }, + "error": "#fb4934", + "warning": "#fabd2f", + "info": "#83a598", + "success": "#b8bb26" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#b8bb26", + "heading.1": "#b8bb26", + "heading.2": "#b8bb26", + "heading.3": "#b8bb26", + "heading.4": "#b8bb26", + "heading.5": "#b8bb26", + "heading.6": "#b8bb26", + "quote": { + "fg": "#83a598", + "italic": true + }, + "math": "#fe8019", + "link": "#fe8019", + "link.label": "#fe8019", + "link.url": { + "fg": "#fe8019", + "underline": true + }, + "raw": "#b8bb26", + "raw.block": "#b8bb26", + "list": "#fe8019", + "list.checked": "#b8bb26", + "list.unchecked": "#928374" + }, + "syntax": { + "comment": "#928374", + "string": "#b8bb26", + "number": "#d3869b", + "constant": "#fe8019", + "parameter": "#83a598", + "function": "#b8bb26", + "keyword": "#fb4934", + "type": "#fabd2f", + "operator": "#8ec07c", + "punctuation": "#fe8019", + "attribute": "#fe8019", + "variable": "#ebdbb2", + "tag": "#8ec07c", + "variable.builtin": { + "fg": "#fb4934", + "italic": true + }, + "variable.parameter": "#83a598", + "variable.member": "#83a598", + "constant.builtin": { + "fg": "#fe8019", + "bold": true + }, + "constant.macro": "#8ec07c", + "module": "#fabd2f", + "module.builtin": "#fe8019", + "label": "#fb4934", + "string.documentation": { + "fg": "#b8bb26", + "italic": true + }, + "string.regexp": "#8ec07c", + "string.escape": { + "fg": "#8ec07c", + "bold": true + }, + "string.special": "#fe8019", + "string.special.symbol": "#83a598", + "string.special.url": { + "fg": "#fe8019", + "underline": true + }, + "character": "#b8bb26", + "character.special": "#fe8019", + "boolean": { + "fg": "#fe8019", + "bold": true + }, + "number.float": "#d3869b", + "type.builtin": { + "fg": "#fabd2f", + "italic": true + }, + "type.definition": "#fabd2f", + "attribute.builtin": "#fe8019", + "property": "#83a598", + "function.builtin": { + "fg": "#b8bb26", + "italic": true + }, + "function.call": "#b8bb26", + "function.macro": "#8ec07c", + "function.method": "#b8bb26", + "function.method.call": "#b8bb26", + "constructor": "#fe8019", + "constructor.lua": "#fb4934", + "keyword.coroutine": { + "fg": "#fb4934", + "italic": true + }, + "keyword.function": "#fb4934", + "keyword.operator": { + "fg": "#8ec07c", + "bold": true + }, + "keyword.import": "#8ec07c", + "keyword.type": "#fabd2f", + "keyword.modifier": "#fabd2f", + "keyword.repeat": "#fb4934", + "keyword.return": "#8ec07c", + "keyword.debug": "#fabd2f", + "keyword.exception": "#8ec07c", + "keyword.conditional": "#fb4934", + "keyword.conditional.ternary": "#8ec07c", + "keyword.directive": "#8ec07c", + "keyword.directive.define": "#8ec07c", + "punctuation.delimiter": "#fe8019", + "punctuation.bracket": "#fe8019", + "punctuation.special": "#fe8019", + "comment.documentation": "#928374", + "comment.error": { + "fg": "#ebdbb2", + "bg": "#fb4934", + "bold": true + }, + "comment.warning": { + "fg": "#1c1c1c", + "bg": "#fabd2f", + "bold": true + }, + "comment.todo": { + "fg": "#1c1c1c", + "bg": "#8ec07c", + "bold": true + }, + "comment.note": { + "fg": "#1c1c1c", + "bg": "#83a598", + "bold": true + }, + "diff.plus": "#b8bb26", + "diff.minus": "#fb4934", + "diff.delta": "#fabd2f", + "tag.builtin": "#8ec07c", + "tag.attribute": "#83a598", + "tag.delimiter": "#fe8019" + } +} diff --git a/themes/rose-pine/tui-theme.json b/themes/rose-pine/tui-theme.json new file mode 100644 index 0000000..237d399 --- /dev/null +++ b/themes/rose-pine/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#e0def4", + "muted": "#908caa", + "accent": "#c4a7e7", + "selection": { + "fg": "#e0def4", + "bg": "#403d52" + }, + "match": "#f6c177", + "border": "#26233a", + "panel": { + "bg": "#1f1d2e" + }, + "error": "#eb6f92", + "warning": "#f6c177", + "info": "#9ccfd8", + "success": "#95b1ac" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#ebbcba", + "heading.1": "#ebbcba", + "heading.2": "#ebbcba", + "heading.3": "#ebbcba", + "heading.4": "#ebbcba", + "heading.5": "#ebbcba", + "heading.6": "#ebbcba", + "quote": { + "fg": "#c4a7e7", + "italic": true + }, + "math": "#f6c177", + "link": "#f6c177", + "link.label": "#f6c177", + "link.url": { + "fg": "#f6c177", + "underline": true + }, + "raw": "#f6c177", + "raw.block": "#f6c177", + "list": "#908caa", + "list.checked": "#95b1ac", + "list.unchecked": "#6e6a86" + }, + "syntax": { + "comment": "#908caa", + "string": "#f6c177", + "number": "#f6c177", + "constant": "#f6c177", + "parameter": "#c4a7e7", + "function": "#ebbcba", + "keyword": "#31748f", + "type": "#9ccfd8", + "operator": "#908caa", + "punctuation": "#908caa", + "attribute": "#f6c177", + "variable": "#e0def4", + "tag": "#9ccfd8", + "variable.builtin": { + "fg": "#eb6f92", + "italic": true + }, + "variable.parameter": "#c4a7e7", + "variable.member": "#c4a7e7", + "constant.builtin": { + "fg": "#f6c177", + "bold": true + }, + "constant.macro": "#c4a7e7", + "module": "#9ccfd8", + "module.builtin": "#f6c177", + "label": "#eb6f92", + "string.documentation": { + "fg": "#f6c177", + "italic": true + }, + "string.regexp": "#9ccfd8", + "string.escape": { + "fg": "#9ccfd8", + "bold": true + }, + "string.special": "#f6c177", + "string.special.symbol": "#c4a7e7", + "string.special.url": { + "fg": "#f6c177", + "underline": true + }, + "character": "#f6c177", + "character.special": "#f6c177", + "boolean": { + "fg": "#f6c177", + "bold": true + }, + "number.float": "#f6c177", + "type.builtin": { + "fg": "#9ccfd8", + "italic": true + }, + "type.definition": "#9ccfd8", + "attribute.builtin": "#f6c177", + "property": "#c4a7e7", + "function.builtin": { + "fg": "#ebbcba", + "italic": true + }, + "function.call": "#ebbcba", + "function.macro": "#c4a7e7", + "function.method": "#ebbcba", + "function.method.call": "#ebbcba", + "constructor": "#f6c177", + "constructor.lua": "#31748f", + "keyword.coroutine": { + "fg": "#31748f", + "italic": true + }, + "keyword.function": "#31748f", + "keyword.operator": { + "fg": "#908caa", + "bold": true + }, + "keyword.import": "#c4a7e7", + "keyword.type": "#9ccfd8", + "keyword.modifier": "#9ccfd8", + "keyword.repeat": "#eb6f92", + "keyword.return": "#9ccfd8", + "keyword.debug": "#f6c177", + "keyword.exception": "#9ccfd8", + "keyword.conditional": "#eb6f92", + "keyword.conditional.ternary": "#908caa", + "keyword.directive": "#c4a7e7", + "keyword.directive.define": "#c4a7e7", + "punctuation.delimiter": "#908caa", + "punctuation.bracket": "#908caa", + "punctuation.special": "#f6c177", + "comment.documentation": "#908caa", + "comment.error": { + "fg": "#e0def4", + "bg": "#eb6f92", + "bold": true + }, + "comment.warning": { + "fg": "#191724", + "bg": "#f6c177", + "bold": true + }, + "comment.todo": { + "fg": "#191724", + "bg": "#c4a7e7", + "bold": true + }, + "comment.note": { + "fg": "#191724", + "bg": "#9ccfd8", + "bold": true + }, + "diff.plus": "#31748f", + "diff.minus": "#eb6f92", + "diff.delta": "#f6c177", + "tag.builtin": "#9ccfd8", + "tag.attribute": "#c4a7e7", + "tag.delimiter": "#908caa" + } +} diff --git a/themes/solarized-osaka/tui-theme.json b/themes/solarized-osaka/tui-theme.json new file mode 100644 index 0000000..2fff3cf --- /dev/null +++ b/themes/solarized-osaka/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#839395", + "muted": "#657b83", + "accent": "#268bd3", + "selection": { + "fg": "#839395", + "bg": "#073642" + }, + "match": "#b28500", + "border": "#073642", + "panel": { + "bg": "#001419" + }, + "error": "#db302d", + "warning": "#b28500", + "info": "#268bd3", + "success": "#859900" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#268bd3", + "heading.1": "#268bd3", + "heading.2": "#268bd3", + "heading.3": "#268bd3", + "heading.4": "#268bd3", + "heading.5": "#268bd3", + "heading.6": "#268bd3", + "quote": { + "fg": "#c94c16", + "italic": true + }, + "math": "#c94c16", + "link": "#c94c16", + "link.label": "#c94c16", + "link.url": { + "fg": "#c94c16", + "underline": true + }, + "raw": "#29a298", + "raw.block": "#29a298", + "list": "#849900", + "list.checked": "#859900", + "list.unchecked": "#586e75" + }, + "syntax": { + "comment": "#576d74", + "string": "#29a298", + "number": "#29a298", + "constant": "#c94c16", + "parameter": "#c94c16", + "function": "#268bd3", + "keyword": "#849900", + "type": "#b28500", + "operator": "#849900", + "punctuation": "#849900", + "attribute": "#c94c16", + "variable": "#839395", + "tag": "#29a298", + "variable.builtin": { + "fg": "#db302d", + "italic": true + }, + "variable.parameter": "#c94c16", + "variable.member": "#268bd3", + "constant.builtin": { + "fg": "#c94c16", + "bold": true + }, + "constant.macro": "#db302d", + "module": "#b28500", + "module.builtin": "#c94c16", + "label": "#db302d", + "string.documentation": { + "fg": "#29a298", + "italic": true + }, + "string.regexp": "#29a298", + "string.escape": { + "fg": "#29a298", + "bold": true + }, + "string.special": "#c94c16", + "string.special.symbol": "#268bd3", + "string.special.url": { + "fg": "#c94c16", + "underline": true + }, + "character": "#29a298", + "character.special": "#c94c16", + "boolean": { + "fg": "#c94c16", + "bold": true + }, + "number.float": "#29a298", + "type.builtin": { + "fg": "#b28500", + "italic": true + }, + "type.definition": "#b28500", + "attribute.builtin": "#c94c16", + "property": "#268bd3", + "function.builtin": { + "fg": "#268bd3", + "italic": true + }, + "function.call": "#268bd3", + "function.macro": "#db302d", + "function.method": "#268bd3", + "function.method.call": "#268bd3", + "constructor": "#c94c16", + "constructor.lua": "#849900", + "keyword.coroutine": { + "fg": "#849900", + "italic": true + }, + "keyword.function": "#849900", + "keyword.operator": { + "fg": "#849900", + "bold": true + }, + "keyword.import": "#db302d", + "keyword.type": "#b28500", + "keyword.modifier": "#b28500", + "keyword.repeat": "#db302d", + "keyword.return": "#29a298", + "keyword.debug": "#b28500", + "keyword.exception": "#29a298", + "keyword.conditional": "#db302d", + "keyword.conditional.ternary": "#849900", + "keyword.directive": "#db302d", + "keyword.directive.define": "#db302d", + "punctuation.delimiter": "#849900", + "punctuation.bracket": "#849900", + "punctuation.special": "#c94c16", + "comment.documentation": "#576d74", + "comment.error": { + "fg": "#839395", + "bg": "#db302d", + "bold": true + }, + "comment.warning": { + "fg": "#001419", + "bg": "#b28500", + "bold": true + }, + "comment.todo": { + "fg": "#001419", + "bg": "#29a298", + "bold": true + }, + "comment.note": { + "fg": "#001419", + "bg": "#268bd3", + "bold": true + }, + "diff.plus": "#849900", + "diff.minus": "#db302d", + "diff.delta": "#b28500", + "tag.builtin": "#29a298", + "tag.attribute": "#268bd3", + "tag.delimiter": "#849900" + } +} diff --git a/themes/sora/tui-theme.json b/themes/sora/tui-theme.json new file mode 100644 index 0000000..233bd9a --- /dev/null +++ b/themes/sora/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#c8d0e0", + "muted": "#9aa4b8", + "accent": "#80c8e0", + "selection": { + "fg": "#dce4f0", + "bg": "#1e2430" + }, + "match": "#d4b878", + "border": "#222838", + "panel": { + "bg": "#0a0c12" + }, + "error": "#c46c78", + "warning": "#c8a860", + "info": "#5ca8c8", + "success": "#68a888" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#80c8e0", + "heading.1": "#80c8e0", + "heading.2": "#80c8e0", + "heading.3": "#80c8e0", + "heading.4": "#80c8e0", + "heading.5": "#80c8e0", + "heading.6": "#80c8e0", + "quote": { + "fg": "#d0a888", + "italic": true + }, + "math": "#d4b878", + "link": "#d0a888", + "link.label": "#d0a888", + "link.url": { + "fg": "#d0a888", + "underline": true + }, + "raw": "#90c8a0", + "raw.block": "#90c8a0", + "list": "#9aa4b8", + "list.checked": "#68a888", + "list.unchecked": "#586478" + }, + "syntax": { + "comment": "#586478", + "string": "#90c8a0", + "number": "#d4b878", + "constant": "#d4b878", + "parameter": "#d0a888", + "function": "#80c8e0", + "keyword": "#b0a0d8", + "type": "#d0a888", + "operator": "#8898b8", + "punctuation": "#9aa4b8", + "attribute": "#d4b878", + "variable": "#c8d0e0", + "tag": "#78b8b0", + "variable.builtin": { + "fg": "#d0909c", + "italic": true + }, + "variable.parameter": "#d0a888", + "variable.member": "#80c8e0", + "constant.builtin": { + "fg": "#d4b878", + "bold": true + }, + "constant.macro": "#b0a0d8", + "module": "#d0a888", + "module.builtin": "#d0a888", + "label": "#d0909c", + "string.documentation": { + "fg": "#90c8a0", + "italic": true + }, + "string.regexp": "#78b8b0", + "string.escape": { + "fg": "#78b8b0", + "bold": true + }, + "string.special": "#d0a888", + "string.special.symbol": "#80c8e0", + "string.special.url": { + "fg": "#d0a888", + "underline": true + }, + "character": "#90c8a0", + "character.special": "#d0a888", + "boolean": { + "fg": "#d4b878", + "bold": true + }, + "number.float": "#d4b878", + "type.builtin": { + "fg": "#d0a888", + "italic": true + }, + "type.definition": "#d0a888", + "attribute.builtin": "#d0a888", + "property": "#80c8e0", + "function.builtin": { + "fg": "#80c8e0", + "italic": true + }, + "function.call": "#80c8e0", + "function.macro": "#b0a0d8", + "function.method": "#80c8e0", + "function.method.call": "#80c8e0", + "constructor": "#d0a888", + "constructor.lua": "#b0a0d8", + "keyword.coroutine": { + "fg": "#b0a0d8", + "italic": true + }, + "keyword.function": "#b0a0d8", + "keyword.operator": { + "fg": "#8898b8", + "bold": true + }, + "keyword.import": "#b0a0d8", + "keyword.type": "#d0a888", + "keyword.modifier": "#d0a888", + "keyword.repeat": "#d0909c", + "keyword.return": "#78b8b0", + "keyword.debug": "#c8a860", + "keyword.exception": "#78b8b0", + "keyword.conditional": "#d0909c", + "keyword.conditional.ternary": "#8898b8", + "keyword.directive": "#b0a0d8", + "keyword.directive.define": "#b0a0d8", + "punctuation.delimiter": "#9aa4b8", + "punctuation.bracket": "#9aa4b8", + "punctuation.special": "#d0a888", + "comment.documentation": "#586478", + "comment.error": { + "fg": "#c8d0e0", + "bg": "#c46c78", + "bold": true + }, + "comment.warning": { + "fg": "#0e1018", + "bg": "#c8a860", + "bold": true + }, + "comment.todo": { + "fg": "#0e1018", + "bg": "#78b0a0", + "bold": true + }, + "comment.note": { + "fg": "#0e1018", + "bg": "#5ca8c8", + "bold": true + }, + "diff.plus": "#68b080", + "diff.minus": "#b86068", + "diff.delta": "#6898b8", + "tag.builtin": "#78b8b0", + "tag.attribute": "#80c8e0", + "tag.delimiter": "#9aa4b8" + } +} diff --git a/themes/terafox/tui-theme.json b/themes/terafox/tui-theme.json new file mode 100644 index 0000000..67e6d30 --- /dev/null +++ b/themes/terafox/tui-theme.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://raw.githubusercontent.com/datapointchris/gotermstyle/main/tuitheme/schema/v1.json", + "ui": { + "text": "#e6eaea", + "muted": "#587b7b", + "accent": "#5a93aa", + "selection": { + "fg": "#e6eaea", + "bg": "#293e40" + }, + "match": "#fda47f", + "border": "#2d4f56", + "panel": { + "bg": "#0f1c1e" + }, + "error": "#e85c51", + "warning": "#fda47f", + "info": "#5a93aa", + "success": "#7aa4a1" + }, + "markdown": { + "strong": { + "bold": true + }, + "italic": { + "italic": true + }, + "strikethrough": { + "strikethrough": true + }, + "underline": { + "underline": true + }, + "heading": "#73a3b7", + "heading.1": "#73a3b7", + "heading.2": "#73a3b7", + "heading.3": "#73a3b7", + "heading.4": "#73a3b7", + "heading.5": "#73a3b7", + "heading.6": "#73a3b7", + "quote": { + "fg": "#afd4de", + "italic": true + }, + "math": "#ff9664", + "link": "#ff8349", + "link.label": "#ff8349", + "link.url": { + "fg": "#ff8349", + "underline": true + }, + "raw": "#7aa4a1", + "raw.block": "#7aa4a1", + "list": "#cbd9d8", + "list.checked": "#7aa4a1", + "list.unchecked": "#6d7f8b" + }, + "syntax": { + "comment": "#6d7f8b", + "string": "#7aa4a1", + "number": "#ff8349", + "constant": "#ff9664", + "parameter": "#afd4de", + "function": "#73a3b7", + "keyword": "#ad5c7c", + "type": "#fda47f", + "operator": "#cbd9d8", + "punctuation": "#cbd9d8", + "attribute": "#ff9664", + "variable": "#e6eaea", + "tag": "#a1cdd8", + "variable.builtin": { + "fg": "#e85c51", + "italic": true + }, + "variable.parameter": "#afd4de", + "variable.member": "#5a93aa", + "constant.builtin": { + "fg": "#ff9664", + "bold": true + }, + "constant.macro": "#d38d97", + "module": "#fda47f", + "module.builtin": "#ff8349", + "label": "#e85c51", + "string.documentation": { + "fg": "#7aa4a1", + "italic": true + }, + "string.regexp": "#fdb292", + "string.escape": { + "fg": "#fdb292", + "bold": true + }, + "string.special": "#ff8349", + "string.special.symbol": "#5a93aa", + "string.special.url": { + "fg": "#ff8349", + "underline": true + }, + "character": "#7aa4a1", + "character.special": "#ff8349", + "boolean": { + "fg": "#ff9664", + "bold": true + }, + "number.float": "#ff8349", + "type.builtin": { + "fg": "#fda47f", + "italic": true + }, + "type.definition": "#fda47f", + "attribute.builtin": "#ff8349", + "property": "#5a93aa", + "function.builtin": { + "fg": "#73a3b7", + "italic": true + }, + "function.call": "#73a3b7", + "function.macro": "#d38d97", + "function.method": "#73a3b7", + "function.method.call": "#73a3b7", + "constructor": "#ff8349", + "constructor.lua": "#ad5c7c", + "keyword.coroutine": { + "fg": "#ad5c7c", + "italic": true + }, + "keyword.function": "#ad5c7c", + "keyword.operator": { + "fg": "#cbd9d8", + "bold": true + }, + "keyword.import": "#d38d97", + "keyword.type": "#fda47f", + "keyword.modifier": "#fda47f", + "keyword.repeat": "#e85c51", + "keyword.return": "#a1cdd8", + "keyword.debug": "#fda47f", + "keyword.exception": "#a1cdd8", + "keyword.conditional": "#e85c51", + "keyword.conditional.ternary": "#cbd9d8", + "keyword.directive": "#d38d97", + "keyword.directive.define": "#d38d97", + "punctuation.delimiter": "#cbd9d8", + "punctuation.bracket": "#cbd9d8", + "punctuation.special": "#ff8349", + "comment.documentation": "#6d7f8b", + "comment.error": { + "fg": "#e6eaea", + "bg": "#e85c51", + "bold": true + }, + "comment.warning": { + "fg": "#152528", + "bg": "#fda47f", + "bold": true + }, + "comment.todo": { + "fg": "#152528", + "bg": "#7aa4a1", + "bold": true + }, + "comment.note": { + "fg": "#152528", + "bg": "#5a93aa", + "bold": true + }, + "diff.plus": "#7aa4a1", + "diff.minus": "#e85c51", + "diff.delta": "#fda47f", + "tag.builtin": "#a1cdd8", + "tag.attribute": "#5a93aa", + "tag.delimiter": "#cbd9d8" + } +} From 716e0075ae2c936c95a42f39d8f487a0561e9640 Mon Sep 17 00:00:00 2001 From: Chris Birch Date: Sun, 8 Nov 2026 01:46:27 -0500 Subject: [PATCH 3/4] fix(tui-theme): install where the reader looks when XDG_CONFIG_HOME is relative gotermstyle's reader ignores a relative XDG_CONFIG_HOME, as the XDG spec asks, and falls back to ~/.config. The install used it raw, so the two named different files and every reader stayed on its built-in colors. Agent-Name: claude-code-unattended Agent-Session: 4773265d-bd77-424c-b9db-836de857b797 Agent-Run: 01a1b9cf-f0a1-76ce-a000-cdf27a041ee5 Worklog: 2555.1 --- lib/lib.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/lib.sh b/lib/lib.sh index 6a11207..93a29a6 100755 --- a/lib/lib.sh +++ b/lib/lib.sh @@ -503,9 +503,10 @@ apply_abtop() { install_themed_artifact "$lib_path/abtop.theme" "$abtop_theme_dir" "$theme.theme" "current.theme" } -# tui-theme/current.json is where gotermstyle's tuitheme looks with no path -# given, so no reader's config needs a line for it. The directory holds only -# theme files, so each theme sits beside the pointer rather than in a themes/. +# tui-theme/current.json is where gotermstyle's tuitheme looks unless +# TUI_THEME_FILE names another file, so no reader's config needs a line for it. +# The directory holds only theme files, so each theme sits beside the pointer +# rather than in a themes/. apply_tui_theme() { local theme="$1" local lib_path @@ -515,8 +516,11 @@ apply_tui_theme() { return 1 fi - local tui_theme_dir="${XDG_CONFIG_HOME:-$HOME/.config}/tui-theme" - install_themed_artifact "$lib_path/tui-theme.json" "$tui_theme_dir" "$theme.json" "current.json" + # The reader ignores a relative XDG_CONFIG_HOME, as the XDG spec asks, so the + # install does too, or the two would name different files. + local config_home="${XDG_CONFIG_HOME:-}" + [[ $config_home == /* ]] || config_home="$HOME/.config" + install_themed_artifact "$lib_path/tui-theme.json" "$config_home/tui-theme" "$theme.json" "current.json" } # Apply JankyBorders theme (macOS) From 65de5a7ae59d640a8748d2a536962556ec14698a Mon Sep 17 00:00:00 2001 From: Chris Birch Date: Sun, 8 Nov 2026 01:46:56 -0500 Subject: [PATCH 4/4] test(tui-theme): check every theme's roles against the schema the files name tui-theme.py types the schema's ui, markdown and base syntax keys out again, and nothing held the copy level. A role the reader's schema gains and the generator misses would draw in the 16-color default in every theme with both suites green. The test fetches the schema at each file's $schema URL, and skips when it cannot reach it. Agent-Name: claude-code-unattended Agent-Session: 4773265d-bd77-424c-b9db-836de857b797 Agent-Run: 01a1b9cf-f0a1-76ce-a000-cdf27a041ee5 Worklog: 2555.1 --- tests/generators.bats | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/generators.bats b/tests/generators.bats index f02d390..52a968a 100755 --- a/tests/generators.bats +++ b/tests/generators.bats @@ -312,6 +312,33 @@ count_theme_artifacts() { assert_output "-- hand written" } +@test "every TUI theme writes the roles its schema declares" { + # The schema belongs to gotermstyle, which reads the file, and tui-theme.py types + # its keys out again. A role added there and missed here draws in the reader's + # 16-color default in every theme, and a role it does not declare fails an + # editor's validation. The schema is the one the files name, so a test with no + # network skips rather than checks a stale copy. + local files=("$THEME_ROOT"/themes/*/tui-theme.json) + local url schema="$BATS_TEST_TMPDIR/schema.json" + url=$(jq -r '."$schema"' "${files[0]}") + curl -fsSL --max-time 10 "$url" -o "$schema" || skip "no schema at $url" + + local group file declared + for group in ui markdown; do + declared=$(jq -r --arg g "$group" '.properties[$g].properties | keys[]' "$schema") + for file in "${files[@]}"; do + run jq -r --arg g "$group" '.[$g] | keys[]' "$file" + assert_output "$declared" + done + done + + declared=$(jq -r '.properties.syntax.properties | keys[]' "$schema") + for file in "${files[@]}"; do + run bash -c 'LC_ALL=C comm -23 <(printf "%s\n" "$1") <(jq -r ".syntax | keys[]" "$2")' _ "$declared" "$file" + assert_output "" + done +} + #============================================================================== # REPO-WIDE ARTIFACT UNIFORMITY #==============================================================================