aboutsummaryrefslogtreecommitdiff
path: root/scripts/theme-selector/build-inventory.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-08 02:32:45 -0500
committerCraig Jennings <c@cjennings.net>2026-06-08 02:32:45 -0500
commitc05364951bf59edde7d0d0eb35013dfc077d40cf (patch)
tree6bef8d59e31f68b81dc4517d5393f10aeb328eab /scripts/theme-selector/build-inventory.el
parente622f65fd61e260f36a62250b8894f555b8680dc (diff)
downloaddotemacs-c05364951bf59edde7d0d0eb35013dfc077d40cf.tar.gz
dotemacs-c05364951bf59edde7d0d0eb35013dfc077d40cf.zip
feat(theme-selector): generated all-package inventory (tier-3 phase 6)
I added the hybrid inventory. build-inventory.el, loaded into a running Emacs, queries every installed package's faces grouped by the package that defines them and writes package-inventory.json. generate.py embeds that file and merges each package into the app dropdown as an editable generic app, leaving the bespoke org, magit, and elfeed untouched. The dropdown now reaches 40 apps: the three bespoke plus 37 inventory packages (643 faces), so any installed package can be themed against the palette with the generic preview. The inventory is a committed data artifact refreshed by reloading the .el, never browser-side discovery, matching the spec's hybrid-and-split decision.
Diffstat (limited to 'scripts/theme-selector/build-inventory.el')
-rw-r--r--scripts/theme-selector/build-inventory.el31
1 files changed, 31 insertions, 0 deletions
diff --git a/scripts/theme-selector/build-inventory.el b/scripts/theme-selector/build-inventory.el
new file mode 100644
index 00000000..52e14baa
--- /dev/null
+++ b/scripts/theme-selector/build-inventory.el
@@ -0,0 +1,31 @@
+;;; build-inventory.el --- emit package->faces inventory for theme-selector -*- lexical-binding: t -*-
+;;; Commentary:
+;; Loaded into a running Emacs (emacsclient -e '(load ".../build-inventory.el")')
+;; to write package-inventory.json next to itself: a JSON object mapping each
+;; installed (elpa/straight) package to the faces it defines, grouped by the
+;; package that owns the face's definition file. Built-in faces are skipped.
+;; generate.py embeds the JSON so the theme-selector dropdown can reach every
+;; installed package (tier-3 phase 6, the "theme every package" path).
+;;; Code:
+
+(require 'json)
+
+(let ((h (make-hash-table :test 'equal)))
+ (dolist (f (face-list))
+ (let* ((file (ignore-errors (symbol-file f 'defface)))
+ (pkg (and (stringp file)
+ (string-match "/\\(?:elpa\\|straight/build\\|site-lisp\\)/\\([a-zA-Z0-9._-]+?\\)-[0-9][^/]*/" file)
+ (match-string 1 file))))
+ (when pkg (push (symbol-name f) (gethash pkg h)))))
+ (let (al)
+ (maphash (lambda (k v) (push (cons (intern k) (sort v #'string<)) al)) h)
+ (setq al (sort al (lambda (a b) (string< (symbol-name (car a)) (symbol-name (car b))))))
+ (with-temp-file (expand-file-name
+ "package-inventory.json"
+ (file-name-directory (or load-file-name buffer-file-name
+ "~/.emacs.d/scripts/theme-selector/")))
+ (let ((json-encoding-pretty-print t))
+ (insert (json-encode al) "\n")))))
+
+(provide 'build-inventory)
+;;; build-inventory.el ends here