#!/usr/bin/env python3 # Regenerate gruvbox-dark.tmTheme. Edit the palette or the rules below, # then run: ./regen-tmtheme.py import plistlib, uuid BG0, BG1, BG2, BG3, BG4 = "#282828", "#3c3836", "#504945", "#665c54", "#7c6f64" GRAY = "#928374" FG0, FG1, FG2, FG4 = "#fbf1c7", "#ebdbb2", "#d5c4a1", "#a89984" RED, GREEN, YELLOW, BLUE = "#fb4934", "#b8bb26", "#fabd2f", "#83a598" PURPLE, AQUA, ORANGE = "#d3869b", "#8ec07c", "#fe8019" PURPLE_DIM = "#b16286" def rule(name, scope, fg=None, bg=None, style=None): s = {} if fg: s["foreground"] = fg if bg: s["background"] = bg if style is not None: s["fontStyle"] = style return {"name": name, "scope": scope, "settings": s} # Scope -> colour follows morhetz/gruvbox's vim highlight links: # Comment=gray italic, String=green, Constant/Number/Boolean=purple, # Statement/Keyword=red, Identifier=blue, Function=green bold, # Type=yellow, StorageClass=orange, PreProc/Structure=aqua, # Special=orange, Operator=Normal. settings = [ {"settings": { "background": BG0, "foreground": FG1, "caret": FG1, "lineHighlight": BG1, "selection": BG2, "invisibles": BG2, "findHighlight": YELLOW, "findHighlightForeground": BG0, "gutterForeground": BG4, "guide": BG1, "activeGuide": BG2, "stackGuide": BG1, }}, rule("Comment", "comment, punctuation.definition.comment", GRAY, style="italic"), rule("Comment tag", "comment.notation, keyword.codetag", RED, style="bold italic"), rule("String", "string, punctuation.definition.string", GREEN), rule("Regular expression", "string.regexp", AQUA), rule("Escape sequence", "constant.character.escape, constant.other.placeholder", ORANGE), rule("Number, boolean, constant", "constant.numeric, constant.language, constant.character, constant.other", PURPLE), rule("Built-in constant", "support.constant", PURPLE), rule("Variable", "variable, variable.other, variable.parameter", BLUE), rule("Language variable", "variable.language", ORANGE, style="italic"), rule("Keyword", "keyword, keyword.control", RED), rule("Operator", "keyword.operator", FG1), rule("Preprocessor, import", "meta.preprocessor, keyword.control.import, keyword.control.export, keyword.other.import, keyword.other.using, punctuation.definition.preprocessor, entity.name.function.preprocessor", AQUA), rule("Storage", "storage", RED), rule("Storage type", "storage.type", YELLOW), rule("Storage modifier", "storage.modifier", ORANGE), rule("Function", "entity.name.function, meta.function-call entity.name.function, support.function.any-method", GREEN, style="bold"), rule("Built-in function", "support.function", AQUA), rule("Macro", "support.macro, entity.name.function.macro", AQUA), rule("Class, type, namespace", "entity.name.class, entity.name.type, entity.name.struct, entity.name.enum, entity.name.trait, entity.name.namespace, support.class, support.type", YELLOW), rule("Inherited class", "entity.other.inherited-class", YELLOW, style="italic"), rule("Tag", "entity.name.tag", AQUA), rule("Tag punctuation", "punctuation.definition.tag", FG4), rule("Attribute", "entity.other.attribute-name", YELLOW), rule("Key, property name", "support.type.property-name, entity.name.tag.yaml, meta.mapping.key string, meta.object-literal.key", BLUE), rule("CSS property", "support.type.property-name.css, meta.property-name.css", AQUA), rule("Punctuation", "punctuation, punctuation.separator, punctuation.terminator, punctuation.accessor, meta.brace", FG4), rule("Invalid", "invalid, invalid.illegal", FG0, bg=RED), rule("Invalid deprecated", "invalid.deprecated", FG0, bg=PURPLE_DIM), rule("Markup heading", "markup.heading, entity.name.section", GREEN, style="bold"), rule("Markup bold", "markup.bold", ORANGE, style="bold"), rule("Markup italic", "markup.italic", ORANGE, style="italic"), rule("Markup link", "markup.underline.link, markup.underline", PURPLE, style="underline"), rule("Markup quote", "markup.quote", GRAY, style="italic"), rule("Markup list", "markup.list, punctuation.definition.list", BLUE), rule("Markup code", "markup.raw, markup.inline.raw, markup.fenced_code", AQUA), rule("Markup inserted", "markup.inserted", GREEN), rule("Markup deleted", "markup.deleted", RED), rule("Markup changed", "markup.changed", YELLOW), rule("Diff header", "meta.diff.header, meta.diff.range, meta.diff.index", BLUE), ] theme = { "name": "Gruvbox Dark", "author": "Thomas Kopp", "semanticClass": "theme.dark.gruvbox_dark", "colorSpaceName": "sRGB", "uuid": str(uuid.uuid5(uuid.NAMESPACE_DNS, "yazi-gruvbox.opennerds.org")), "settings": settings, } out = "gruvbox-dark.tmTheme" with open(out, "wb") as f: plistlib.dump(theme, f, sort_keys=False) print("wrote", out) print("rules:", len(settings) - 1)