diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-29 08:42:10 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-29 08:42:10 -0400 |
| commit | 4d64437433ed221a08a5258243c01e3a05980db9 (patch) | |
| tree | 5fe8b4ebe02310d33890545bc020b2c163141d40 /modules/system-lib.el | |
| parent | 2cec4136bcef7d984ecbafe95ad5280d7fa463f0 (diff) | |
| download | dotemacs-4d64437433ed221a08a5258243c01e3a05980db9.tar.gz dotemacs-4d64437433ed221a08a5258243c01e3a05980db9.zip | |
feat(completion): annotate the file-basename pickers with size and date
Eight completing-read pickers listed bare file basenames, so marginalia had no directory to resolve and couldn't annotate them. Add cj/completion-file-annotator to system-lib — an annotation-function factory that takes a candidate->path resolver and yields a size + modification-date suffix (or "dir" for directories, nil for missing files). Wire each picker through cj/completion-table-annotated with a per-site category and resolver: timer sounds, drill flashcards, Info files, the test-runner focus add/remove, vc clone dirs, hugo drafts, and agenda projects (the project's todo.org mtime). music-config's existing completion table gains the category and annotator inline, keeping its sort metadata.
The candidate strings and every return value are unchanged — this only adds completion metadata — so all downstream logic is untouched. The six modules that didn't already pull in system-lib now require it.
Tests: cj/completion-file-annotator gets Normal/Boundary/Error coverage (file, directory, nil path, missing file). Full suite green at 5394.
Claude-Session: https://claude.ai/code/session_014fyKMTTqLrZpL3rDF3dYc3
Diffstat (limited to 'modules/system-lib.el')
| -rw-r--r-- | modules/system-lib.el | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/modules/system-lib.el b/modules/system-lib.el index 8b954c6a9..f1049c021 100644 --- a/modules/system-lib.el +++ b/modules/system-lib.el @@ -187,6 +187,27 @@ for: marginalia falls back to the table's own annotation function." (annotation-function . ,annotate)) (complete-with-action action collection string predicate)))) +(defun cj/completion-file-annotator (candidate->path) + "Return an annotation function for completion candidates backed by files. +CANDIDATE->PATH maps a candidate string to its absolute file path, or nil when +the candidate has no backing file. The returned function, suitable as a +completion table's annotation function (see `cj/completion-table-annotated'), +yields a suffix with the file size and modification date for a regular file, +the marker \"dir\" plus the date for a directory, or nil when the path is nil +or the file is missing -- so marginalia then shows no suffix for that +candidate." + (lambda (cand) + (let ((path (funcall candidate->path cand))) + (when (and path (file-exists-p path)) + (let* ((attrs (file-attributes path)) + (dirp (eq t (file-attribute-type attrs))) + (size (if dirp "dir" + (file-size-human-readable (file-attribute-size attrs)))) + (date (format-time-string + "%Y-%m-%d" + (file-attribute-modification-time attrs)))) + (format " %8s %s" size date)))))) + (defun cj/format-region-with-program (program &rest args) "Replace the current buffer with PROGRAM ARGS run over its contents, via argv. Runs PROGRAM (with ARGS) on the whole buffer through `call-process-region' |
