aboutsummaryrefslogtreecommitdiff
path: root/scripts/theme-studio/app_inventory.py
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-13 15:17:59 -0500
committerCraig Jennings <c@cjennings.net>2026-06-13 15:17:59 -0500
commitedeeb29c6bd7457eb4b43a9767373f94ee036814 (patch)
treeecb0732394d8f9938b2953786cf6de6af3570c99 /scripts/theme-studio/app_inventory.py
parentb76521ffff0ed53b05817878bf51e04db9f837c4 (diff)
downloaddotemacs-edeeb29c6bd7457eb4b43a9767373f94ee036814.tar.gz
dotemacs-edeeb29c6bd7457eb4b43a9767373f94ee036814.zip
Refactor theme studio face assembly
Diffstat (limited to 'scripts/theme-studio/app_inventory.py')
-rw-r--r--scripts/theme-studio/app_inventory.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/scripts/theme-studio/app_inventory.py b/scripts/theme-studio/app_inventory.py
new file mode 100644
index 00000000..0c55a5d4
--- /dev/null
+++ b/scripts/theme-studio/app_inventory.py
@@ -0,0 +1,76 @@
+"""Theme-studio package/app face inventory assembly helpers."""
+
+from __future__ import annotations
+
+import json
+import os
+from typing import Any
+
+
+BESPOKE_APPS = {
+ "magit",
+ "elfeed",
+ "org",
+ "org-mode",
+ "mu4e",
+ "ghostel",
+ "dashboard",
+ "lsp-mode",
+ "git-gutter",
+ "flycheck",
+ "dired",
+ "dirvish",
+ "calibredb",
+ "erc",
+ "org-drill",
+ "org-noter",
+ "signel",
+ "pearl",
+ "slack",
+ "telega",
+ "shr",
+}
+
+
+def face_label(face: str, prefix: str) -> str:
+ label = face[len(prefix) :] if face.startswith(prefix) else face
+ return label.replace("-face", "").replace("-", " ")
+
+
+def face_rows(names: list[str], prefix: str, seed: dict[str, dict[str, Any]]) -> list[list[Any]]:
+ return [[face, face_label(face, prefix), seed.get(face, {})] for face in names]
+
+
+def add_inventory_apps(apps: dict[str, Any], inventory_path: str) -> dict[str, Any]:
+ """Add generic editable apps for installed packages not covered by bespoke previews."""
+ if not os.path.exists(inventory_path):
+ return apps
+ inventory = json.load(open(inventory_path))
+ for pkg in sorted(inventory):
+ if pkg in BESPOKE_APPS or pkg in apps:
+ continue
+ apps[pkg] = {
+ "label": pkg,
+ "preview": "generic",
+ "faces": [[face, face_label(face, pkg + "-"), {}] for face in inventory[pkg]],
+ }
+ return apps
+
+
+def apply_default_face_seeds(apps: dict[str, Any], defaults: Any) -> None:
+ if not defaults.available:
+ return
+ for app in apps.values():
+ for row in app["faces"]:
+ row[2] = defaults.seed(row[0], False)
+
+
+def apply_package_overrides(apps: dict[str, Any], packages: dict[str, Any] | None) -> None:
+ if not packages:
+ return
+ for app, package_faces in packages.items():
+ if app not in apps:
+ continue
+ for row in apps[app]["faces"]:
+ if row[0] in package_faces:
+ row[2] = package_faces[row[0]]