aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-18 16:56:22 -0500
committerCraig Jennings <c@cjennings.net>2026-07-18 16:56:22 -0500
commit11de26eb9ac5d79ac1303ff89dfd995fd18cd0ed (patch)
tree4b5c5b3da9cefe6b570f86fad0106f5d153c6a11 /modules
parent4e63f665bf153203377f58161aa782a25ffd5e9f (diff)
downloaddotemacs-11de26eb9ac5d79ac1303ff89dfd995fd18cd0ed.tar.gz
dotemacs-11de26eb9ac5d79ac1303ff89dfd995fd18cd0ed.zip
feat(completion): right-align custom category annotations
marginalia-align has been right for months, but annotations from the custom completion categories (radio stations, music files, and everything built through the system-lib table helpers) never went through marginalia. They rendered unaligned. A registration helper adds a builtin registry entry per category at table construction, which routes the table's own annotation function through marginalia's aligned field. The radio table converts from an affixation function with hand-rolled padding to a plain annotation, since marginalia now owns the alignment. Self-maintaining: any future custom category built through the helpers registers itself.
Diffstat (limited to 'modules')
-rw-r--r--modules/music-config.el36
-rw-r--r--modules/system-lib.el20
2 files changed, 33 insertions, 23 deletions
diff --git a/modules/music-config.el b/modules/music-config.el
index e9095838..a70516e2 100644
--- a/modules/music-config.el
+++ b/modules/music-config.el
@@ -306,7 +306,9 @@ Directories are suffixed with /; files are plain. Hidden dirs/files skipped."
"Completion table for CANDIDATES preserving order and case-insensitive match.
Tags the `cj-music-file' category and annotates each candidate (a path relative
to `cj/music-root', with a trailing slash for directories) with its size and
-modification date so marginalia can show them."
+modification date so marginalia can show them. The category is registered
+with marginalia (builtin) so the annotations render right-aligned."
+ (cj/completion-ensure-marginalia-align 'cj-music-file)
(let ((annotate (cj/completion-file-annotator
(lambda (c)
(expand-file-name
@@ -1790,32 +1792,22 @@ to one station. Pure helper."
(puthash disp t seen)
(push (cons disp st) out)))))
-(defun cj/music-radio--affixate (cands candidates)
- "Affixation triples for CANDS with annotations aligned to one column.
-CANDIDATES is the (DISPLAY . STATION) alist. Station names vary in width,
-so each suffix pads out to the widest candidate plus a gutter; with the
-fixed-width fields in `cj/music-radio--format-candidate' the listing reads
-as aligned columns. The \"[done]\" sentinel has no station and gets no
-annotation rather than a bogus zero row."
- (let ((width (apply #'max 0 (mapcar #'string-width cands))))
- (mapcar (lambda (c)
- (let ((st (cdr (assoc c candidates))))
- (list c ""
- (if st
- (concat (make-string (+ 3 (- width (string-width c))) ?\s)
- (propertize (cj/music-radio--format-candidate st)
- 'face 'completions-annotations))
- ""))))
- cands)))
-
(defun cj/music-radio--completion-table (candidates)
- "Completion table over CANDIDATES carrying the Variant-B marginalia affix."
+ "Completion table over CANDIDATES carrying the Variant-B annotation.
+Tagged `cj-radio-station' and registered with marginalia (builtin), so the
+codec/bitrate/country/votes/tags annotation renders right-aligned like the
+stock categories. The \"[done]\" sentinel has no station and annotates as
+nil rather than a bogus zero row."
+ (cj/completion-ensure-marginalia-align 'cj-radio-station)
(lambda (string pred action)
(if (eq action 'metadata)
`(metadata
(category . cj-radio-station)
- (affixation-function
- . ,(lambda (cands) (cj/music-radio--affixate cands candidates))))
+ (annotation-function
+ . ,(lambda (c)
+ (when-let ((st (cdr (assoc c candidates))))
+ (concat " " (propertize (cj/music-radio--format-candidate st)
+ 'face 'completions-annotations))))))
(complete-with-action action (mapcar #'car candidates) string pred))))
(defun cj/music-radio--pick-loop (candidates)
diff --git a/modules/system-lib.el b/modules/system-lib.el
index f1049c02..54e20b74 100644
--- a/modules/system-lib.el
+++ b/modules/system-lib.el
@@ -164,6 +164,22 @@ contributes its own modes regardless of load order."
(setq font-lock-global-modes
(cj/--font-lock-global-modes-excluding font-lock-global-modes mode))))
+;; Declared special here for the compiler; marginalia owns the defvar.
+(defvar marginalia-annotator-registry)
+
+(defun cj/completion-ensure-marginalia-align (category)
+ "Register CATEGORY with marginalia as builtin-annotated, once.
+A custom completion category bypasses marginalia entirely, so the table's
+own annotation function renders unaligned even with `marginalia-align'
+set. A builtin registry entry tells marginalia to use the table's
+annotation function inside its aligned field, so custom annotations line
+up like every stock category. A category that already has an entry is
+left alone (someone chose its annotators deliberately). Silent no-op
+when marginalia isn't loaded."
+ (when (and (boundp 'marginalia-annotator-registry)
+ (not (assq category marginalia-annotator-registry)))
+ (push (list category 'builtin 'none) marginalia-annotator-registry)))
+
(defun cj/completion-table (category collection)
"Return a completion table over COLLECTION tagged with completion CATEGORY.
COLLECTION is anything `completing-read' accepts (list, alist, obarray, hash
@@ -180,7 +196,9 @@ the candidates match one; marginalia then annotates them with no further work."
"Like `cj/completion-table' but also attach ANNOTATE as the annotation function.
ANNOTATE is called with a candidate string and returns its annotation suffix, or
nil. Use this for a custom CATEGORY that marginalia has no built-in annotator
-for: marginalia falls back to the table's own annotation function."
+for; the category is registered with marginalia (builtin) so ANNOTATE's output
+renders right-aligned like stock annotations."
+ (cj/completion-ensure-marginalia-align category)
(lambda (string predicate action)
(if (eq action 'metadata)
`(metadata (category . ,category)