diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-18 20:42:29 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-18 20:42:29 -0500 |
| commit | cac380cf2a2960c97274c6ce3cc8b4ae3feb62d8 (patch) | |
| tree | cc452ae0ba94584ea8025fa1433feda70fa39622 | |
| parent | 61d68eae4a6184cfd241f4c25f55598843604183 (diff) | |
| download | dotemacs-cac380cf2a2960c97274c6ce3cc8b4ae3feb62d8.tar.gz dotemacs-cac380cf2a2960c97274c6ce3cc8b4ae3feb62d8.zip | |
feat(theme-studio): bucket unrecognized faces by their defface source
A newly-loaded package (or a new built-in face) used to fall into emacs-core because grouping is by name-prefix and an unknown prefix matched nothing. Now the fallback routes by where the defface lives: an elpa face becomes its own package bucket, a built-in face a new emacs-general child. So loading a package and running make face-coverage surfaces it as a fresh TODO bucket instead of an orphan in core. Recognized faces still match their family first, and faces.el/frame.el faces stay in emacs-core.
| -rw-r--r-- | scripts/theme-studio/face_coverage.py | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/scripts/theme-studio/face_coverage.py b/scripts/theme-studio/face_coverage.py index 99a4e01fc..ba761230b 100644 --- a/scripts/theme-studio/face_coverage.py +++ b/scripts/theme-studio/face_coverage.py @@ -109,7 +109,31 @@ def load_managed(): return managed, fontlock, ui, pkg, inv -def make_group_of(families): +# Built-in source files whose faces are core display faces, not a subsystem; +# an unrecognized face from one of these stays in emacs-core rather than +# spawning an odd subsystem bucket under emacs-general. +CORE_FILES = {'faces', 'frame'} + + +def bucket_from_source(path): + """Derive a bucket name from a face's defface file, for faces that match no + known family. elpa -> the package dir name (version stripped); built-in -> + the source file basename; otherwise emacs-core (can't tell).""" + if not path: + return 'emacs-core' + if '/elpa/' in path: + pkgdir = path.split('/elpa/', 1)[1].split('/', 1)[0] + return re.sub(r'-[0-9].*$', '', pkgdir) or 'emacs-core' + if '/.emacs.d/modules' in path: + return 'user-config' + if path.startswith('/usr/share/emacs') or path.startswith('/usr/lib/emacs'): + base = os.path.basename(path) + base = base[:-3] if base.endswith('.el') else base + return 'emacs-core' if base in CORE_FILES else base + return 'emacs-core' + + +def make_group_of(families, src): fams = sorted(families, key=len, reverse=True) def group_of(f): @@ -124,7 +148,9 @@ def make_group_of(families): return p if f.lower().startswith('info-'): return 'info' - return 'emacs-core' + # Unrecognized: route by where the defface lives so a newly-loaded + # package buckets itself instead of falling into emacs-core. + return bucket_from_source(src.get(f, '')) return group_of @@ -189,7 +215,7 @@ def build(data, today): universe = sorted(set(docs.keys()) | managed) families = set(inv.keys()) | EXTRA_FAMILIES - group_of = make_group_of(families) + group_of = make_group_of(families, src) groups = collections.defaultdict(list) for f in universe: groups[group_of(f)].append(f) |
