aboutsummaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/udt-accent38
-rwxr-xr-xbin/udt-palette52
2 files changed, 90 insertions, 0 deletions
diff --git a/bin/udt-accent b/bin/udt-accent
index 75058df..1a542a6 100755
--- a/bin/udt-accent
+++ b/bin/udt-accent
@@ -32,6 +32,8 @@ MIN_CHROMA = 10.0
OUTPUT = Path.home() / ".cache" / "wal" / "udt-accent.rasi"
BORDER_OUTPUT = Path.home() / ".cache" / "wal" / "udt-border.lua"
DUNSTRC = Path.home() / ".cache" / "wal" / "dunstrc"
+SUBLIME = (Path.home() / ".config" / "sublime-text" / "Packages" / "User"
+ / "udt.sublime-color-scheme")
QML_OUTPUT = Path.home() / ".cache" / "wal" / "udt-palette.qml"
# The installed rofi palette, itself generated by udt-palette. Read rather than
@@ -280,6 +282,29 @@ def write_dunst(name):
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+def write_sublime(name):
+ """Substitute the accent into the Sublime colour scheme install.sh copied.
+
+ In place, like dunst: Sublime colour schemes do not cascade, so the accent
+ cannot arrive as a second file. Sublime watches Packages/User and reloads a
+ scheme when its file changes, so no signal is needed. A missing file is not
+ an error, Sublime simply may not be installed here.
+
+ Unlike dunst, this reads the installed copy and has nowhere to recover
+ @ACCENT@ from once substituted, so the previous accent is replaced by
+ matching the variable line rather than a placeholder.
+ """
+ try:
+ text = SUBLIME.read_text()
+ except FileNotFoundError:
+ return
+
+ new, count = re.subn(r'("accent":\s*)"[^"]*"',
+ lambda m: f'{m.group(1)}"{ACCENTS[name]}"', text, count=1)
+ if count and new != text:
+ write_atomic(SUBLIME, new)
+
+
def main(image):
try:
name = snap(signature_color(image))
@@ -292,6 +317,7 @@ def main(image):
write_border(name)
write_qml(name)
write_dunst(name)
+ write_sublime(name)
write_colors_json(name, image)
# Hyprland only rereads its config on request, and may not be running.
@@ -316,6 +342,18 @@ def selftest():
delta = min(delta, 2 * math.pi - delta)
assert delta < 0.6, f"{probe} snapped to {got}, {delta:.2f} rad away"
+ # The Sublime accent is replaced by matching its current value, not a
+ # placeholder, so it has to survive being run twice: once over the freshly
+ # installed @ACCENT@, and again over the accent it wrote last time.
+ probe = '{\n "variables":\n {\n "accent": "@ACCENT@",\n'
+ first, n1 = re.subn(r'("accent":\s*)"[^"]*"', r'\1"#f5a97f"', probe, count=1)
+ second, n2 = re.subn(r'("accent":\s*)"[^"]*"', r'\1"#8bd5ca"', first, count=1)
+ third, n3 = re.subn(r'("accent":\s*)"[^"]*"', r'\1"#8bd5ca"', second, count=1)
+ assert (n1, n2, n3) == (1, 1, 1), (n1, n2, n3)
+ assert "@ACCENT@" not in first and '"#f5a97f"' in first
+ assert '"#f5a97f"' not in second and '"#8bd5ca"' in second
+ assert third == second, "accent substitution is not idempotent"
+
# A near-grey has an unstable hue angle and must take the fallback.
assert snap("#888888") == FALLBACK, snap("#888888")
assert FALLBACK in ACCENTS, FALLBACK
diff --git a/bin/udt-palette b/bin/udt-palette
index a746766..ceed64d 100755
--- a/bin/udt-palette
+++ b/bin/udt-palette
@@ -106,6 +106,12 @@ def hex8(c):
return f"#{r:02x}{g:02x}{b:02x}{round(a * 255 / 100):02x}"
+def rgb_array(c):
+ """[r, g, b], which is how a .sublime-theme writes a colour."""
+ r, g, b, _ = c
+ return f"[{r}, {g}, {b}]"
+
+
def rgba(c):
r, g, b, a = c
return f"rgb({r},{g},{b})" if a == 100 else f"rgba({r},{g},{b},{a / 100:.2f})"
@@ -422,6 +428,48 @@ def gen_dunst(res, scheme, palette, template):
return out
+def gen_sublime(res, scheme, palette, template):
+ """Sublime Text: substitute the palette into the colour scheme.
+
+ Scopes map onto the terminal roles rather than onto syntax roles of their
+ own. A scheme already declares all sixteen ANSI slots, so a syntax theme
+ costs no new roles and every shipped scheme satisfies it without touching
+ nine role maps.
+
+ @ACCENT@ is left alone for udt-accent, exactly as in the dunst template:
+ Sublime colour schemes do not cascade, so the accent cannot arrive as a
+ second file and has to be substituted into this one.
+ """
+ out = template.replace("@SCHEME@", scheme)
+ for role in ("bg", "bg_alt", "bg_deep", "surface", "surface_alt",
+ "fg", "fg_dim", "fg_faint",
+ "red", "green", "yellow", "blue", "magenta", "cyan",
+ "critical", "warning", "success", "info"):
+ out = out.replace(f"@{role.upper()}@", hex6(res[role]))
+ # The selection has to be translucent or it hides the text under it, and
+ # selection_bg resolves opaque because the terminal wants it that way.
+ out = out.replace("@SELECTION_BG@", hex8((*res["selection_bg"][:3], 35)))
+ return out
+
+
+def gen_sublime_theme(res, scheme, palette, template):
+ """Sublime Text: the UI chrome, as an override layered over Material Behave.
+
+ A .sublime-theme writes colours as [r, g, b] arrays rather than hex, so this
+ substitutes a different syntax from the colour scheme next door out of the
+ same roles.
+
+ The accent is the scheme's fixed one, not the wallpaper's: Sublime reads a
+ theme once per window, so a moving accent would leave open windows
+ disagreeing with new ones. Same reasoning as conky, Qt, GTK and waybar.
+ """
+ out = template.replace("@SCHEME@", scheme)
+ for role in ("bg", "bg_alt", "bg_deep", "fg", "fg_dim", "fg_faint",
+ "accent"):
+ out = out.replace(f"@{role.upper()}@", rgb_array(res[role]))
+ return out
+
+
def gen_conky(res, scheme, palette, template):
"""conky: substitute into the shipped template.
@@ -539,6 +587,10 @@ TARGETS = [
("templates/typora/udt.css", gen_typora, "templates/typora/udt.css.in"),
("templates/kvantum/theme.kvconfig", gen_kvantum, "templates/kvantum/theme.kvconfig.in"),
("templates/kvantum/theme.svg", gen_kvantum, "templates/kvantum/theme.svg.in"),
+ ("templates/sublime/udt.sublime-color-scheme", gen_sublime,
+ "templates/sublime/udt.sublime-color-scheme.in"),
+ ("templates/sublime/udt.sublime-theme", gen_sublime_theme,
+ "templates/sublime/udt.sublime-theme.in"),
]