203 lines
7.3 KiB
Python
203 lines
7.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""从 gpui-component 默认主题生成 Linear 风格主题 linear-theme.json。
|
|
映射规则见各表;未列出的键(chart/base 等)保留默认值。"""
|
|
import json, sys, collections
|
|
|
|
SRC = sys.argv[1]
|
|
DST = sys.argv[2]
|
|
|
|
with open(SRC, "r", encoding="utf-8") as f:
|
|
base = json.load(f)
|
|
|
|
# ── Linear Dark ────────────────────────────────────────────────────────────
|
|
DARK = {
|
|
"background": "#08090a",
|
|
"foreground": "#f7f8f8",
|
|
"accordion.background": "#101012",
|
|
"border": "#2b2c31",
|
|
"group_box.background": "#08090a",
|
|
"group_box.foreground": "#f7f8f8",
|
|
"caret": "#f7f8f8",
|
|
"accent.background": "#1c1d1f",
|
|
"accent.foreground": "#f7f8f8",
|
|
"danger.background": "#e5484d",
|
|
"danger.foreground": "#ffe9e9",
|
|
"description_list_label.background": "#101012",
|
|
"description_list_label.foreground": "#8a8f98",
|
|
"drag_border": "#5e6ad2",
|
|
"drop_target.background": "#5e6ad219",
|
|
"input.border": "#2b2c31",
|
|
"link.foreground": "#f7f8f8",
|
|
"link.active.foreground": "#d5d7de",
|
|
"link.hover.foreground": "#ffffff",
|
|
"list.background": "#08090a",
|
|
"list.active.background": "#5e6ad233",
|
|
"list.active.border": "#5e6ad2",
|
|
"list.even.background": "#10101266",
|
|
"list.head.background": "#10101266",
|
|
"muted.background": "#1d1e22",
|
|
"muted.foreground": "#8a8f98",
|
|
"popover.background": "#101012",
|
|
"popover.foreground": "#f7f8f8",
|
|
"primary.background": "#5e6ad2",
|
|
"primary.hover.background": "#6e79d6",
|
|
"primary.active.background": "#5661c4",
|
|
"primary.foreground": "#ffffff",
|
|
"progress_bar.background": "#5e6ad2",
|
|
"ring": "#5e6ad2",
|
|
"scrollbar.background": "#08090a00",
|
|
"scrollbar.thumb.background": "#3a3b42e6",
|
|
"scrollbar.thumb.hover.background": "#4a4b54",
|
|
"secondary.background": "#101012",
|
|
"secondary.hover.background": "#1c1d1f",
|
|
"secondary.active.background": "#232429",
|
|
"secondary.foreground": "#f7f8f8",
|
|
"selection.background": "#5e6ad2",
|
|
"sidebar.background": "#08090a",
|
|
"sidebar.accent.background": "#1c1d1f",
|
|
"sidebar.accent.foreground": "#f7f8f8",
|
|
"sidebar.border": "#1f2024",
|
|
"sidebar.foreground": "#f7f8f8",
|
|
"sidebar.primary.background": "#f7f8f8",
|
|
"sidebar.primary.foreground": "#08090a",
|
|
"skeleton.background": "#1c1d1f",
|
|
"slider.bar.background": "#f7f8f8",
|
|
"slider.thumb.background": "#08090a",
|
|
"success.background": "#4cb782",
|
|
"success.foreground": "#0b3a26",
|
|
"switch.background": "#2b2c31",
|
|
"tab.background": "#00000000",
|
|
"tab.active.background": "#101012",
|
|
"tab.active.foreground": "#f7f8f8",
|
|
"tab.foreground": "#8a8f98",
|
|
"tab_bar.background": "#08090a",
|
|
"tab_bar.segmented.background": "#101012",
|
|
"table.background": "#08090a",
|
|
"table.head.foreground": "#8a8f98",
|
|
"table.row.border": "#1f2024b3",
|
|
"title_bar.background": "#08090a",
|
|
"title_bar.border": "#1f2024",
|
|
"status_bar.background": "#08090a",
|
|
"status_bar.border": "#1f2024",
|
|
"warning.background": "#f2a93b",
|
|
"warning.foreground": "#3a2504",
|
|
"info.background": "#5e6ad2",
|
|
"info.foreground": "#e0e3ff",
|
|
"overlay": "#00000066",
|
|
"window.border": "#1f2024",
|
|
}
|
|
|
|
# ── Linear Light ───────────────────────────────────────────────────────────
|
|
LIGHT = {
|
|
"background": "#ffffff",
|
|
"foreground": "#0d0e10",
|
|
"accordion.background": "#f7f7f8",
|
|
"border": "#e5e5e7",
|
|
"group_box.background": "#ffffff",
|
|
"group_box.foreground": "#0d0e10",
|
|
"caret": "#0d0e10",
|
|
"accent.background": "#eeeef0",
|
|
"accent.foreground": "#0d0e10",
|
|
"danger.background": "#e5484d",
|
|
"danger.foreground": "#ffffff",
|
|
"description_list_label.background": "#f7f7f8",
|
|
"description_list_label.foreground": "#6f7076",
|
|
"drag_border": "#5e6ad2",
|
|
"drop_target.background": "#5e6ad219",
|
|
"input.border": "#e5e5e7",
|
|
"link.foreground": "#0d0e10",
|
|
"link.active.foreground": "#3d3e44",
|
|
"link.hover.foreground": "#000000",
|
|
"list.background": "#ffffff",
|
|
"list.active.background": "#5e6ad233",
|
|
"list.active.border": "#5e6ad2",
|
|
"list.even.background": "#f1f1f266",
|
|
"list.head.background": "#f1f1f266",
|
|
"muted.background": "#f1f1f2",
|
|
"muted.foreground": "#6f7076",
|
|
"popover.background": "#ffffff",
|
|
"popover.foreground": "#0d0e10",
|
|
"primary.background": "#5e6ad2",
|
|
"primary.hover.background": "#6b76d4",
|
|
"primary.active.background": "#5661c4",
|
|
"primary.foreground": "#ffffff",
|
|
"progress_bar.background": "#5e6ad2",
|
|
"ring": "#5e6ad2",
|
|
"scrollbar.background": "#ffffff00",
|
|
"scrollbar.thumb.background": "#c9c9cee6",
|
|
"scrollbar.thumb.hover.background": "#b5b5bb",
|
|
"secondary.background": "#f7f7f8",
|
|
"secondary.hover.background": "#eeeef0",
|
|
"secondary.active.background": "#e7e7e9",
|
|
"secondary.foreground": "#0d0e10",
|
|
"selection.background": "#5e6ad2",
|
|
"sidebar.background": "#fbfbfb",
|
|
"sidebar.accent.background": "#eeeef0",
|
|
"sidebar.accent.foreground": "#0d0e10",
|
|
"sidebar.border": "#e5e5e7",
|
|
"sidebar.foreground": "#0d0e10",
|
|
"sidebar.primary.background": "#0d0e10",
|
|
"sidebar.primary.foreground": "#ffffff",
|
|
"skeleton.background": "#eeeef0",
|
|
"slider.bar.background": "#0d0e10",
|
|
"slider.thumb.background": "#ffffff",
|
|
"success.background": "#4cb782",
|
|
"success.foreground": "#ffffff",
|
|
"switch.background": "#d7d7db",
|
|
"tab.background": "#00000000",
|
|
"tab.active.background": "#ffffff",
|
|
"tab.active.foreground": "#0d0e10",
|
|
"tab.foreground": "#6f7076",
|
|
"tab_bar.background": "#ffffff",
|
|
"tab_bar.segmented.background": "#f1f1f2",
|
|
"table.background": "#ffffff",
|
|
"table.head.foreground": "#6f7076",
|
|
"table.row.border": "#ebebed",
|
|
"title_bar.background": "#ffffff",
|
|
"title_bar.border": "#e5e5e7",
|
|
"status_bar.background": "#ffffff",
|
|
"status_bar.border": "#e5e5e7",
|
|
"warning.background": "#f2a93b",
|
|
"warning.foreground": "#3a2504",
|
|
"info.background": "#5e6ad2",
|
|
"info.foreground": "#ffffff",
|
|
"overlay": "#00000033",
|
|
"window.border": "#e5e5e7",
|
|
}
|
|
|
|
|
|
def build(theme, overrides, name):
|
|
colors = dict(theme.get("colors") or {})
|
|
missing = [k for k in overrides if k not in colors]
|
|
if missing:
|
|
print(f"WARN {name}: 目标主题缺少键 {missing}", file=sys.stderr)
|
|
colors.update(overrides)
|
|
out = collections.OrderedDict()
|
|
# 键序跟随默认主题,新键追加
|
|
for k in (theme.get("colors") or {}):
|
|
out[k] = colors[k]
|
|
for k in overrides:
|
|
if k not in out:
|
|
out[k] = overrides[k]
|
|
cfg = collections.OrderedDict()
|
|
cfg["name"] = name
|
|
cfg["mode"] = theme["mode"]
|
|
cfg["font_size"] = 14
|
|
cfg["radius"] = 6
|
|
cfg["radius_lg"] = 10
|
|
cfg["colors"] = out
|
|
if theme.get("highlight"):
|
|
cfg["highlight"] = theme["highlight"]
|
|
return cfg
|
|
|
|
|
|
by_mode = {t["mode"]: t for t in base["themes"]}
|
|
themes = [
|
|
build(by_mode["light"], LIGHT, "Linear Light"),
|
|
build(by_mode["dark"], DARK, "Linear Dark"),
|
|
]
|
|
doc = {"themes": themes}
|
|
with open(DST, "w", encoding="utf-8") as f:
|
|
json.dump(doc, f, ensure_ascii=False, indent=2)
|
|
print(f"OK -> {DST} ({len(themes)} themes)")
|