Fundamentally, this is a thin wrapper around the standard emacs
completing-read facility, with a more ergonomic (lisp) interface. It shares a
lot with consult--read, but it’s very lightweight, and works well with vertico
(and other minibuffer completion interfaces), marginalia, and embark (and
related tooling).
The annotated-completing-read function has intuitive, easy to read semantics:
keyword arguments for all optional arguments, selection options are a mapping
(hashmap or alist) of options-to-annotations. There are some (bonsu) helpers for
selecting a directory from a list of likely options and selecting input from a
list of thing-at-point, kill-ring (and other likely) possibilities.
Requires Emacs 29.1+. Run once to clone and register the package:
(package-vc-install '(annotated-completing-read
:url "https://github.com/tychoish/annotated-completing-read.el"))Requires Emacs 30+. Installs on first load if not already present:
(use-package annotated-completing-read
:vc (:url "https://github.com/tychoish/annotated-completing-read.el"))git clone https://github.com/tychoish/annotated-completing-read.el ~/path/to/annotated-completing-read.el(use-package annotated-completing-read
:load-path "~/path/to/annotated-completing-read.el")git clone https://github.com/tychoish/annotated-completing-read.el ~/path/to/annotated-completing-read.el(add-to-list 'load-path "~/path/to/annotated-completing-read.el")
(require 'annotated-completing-read)(fn TABLE &key (PROMPT "=> ") REQUIRE-MATCH CATEGORY HISTORY GROUP-NAME GROUP-DISPLAY INITIAL-INPUT SORT-FN DEFAULT OR-NIL)
Read a candidate from TABLE with aligned per-candidate annotations. TABLE is any Emacs hash table ‘make-hash-table’ mapping candidate strings to annotation strings. Column alignment is computed automatically; callers need not pad candidates or annotations.
PROMPT is the minibuffer prompt (default “=> “); a trailing space is appended automatically if absent.
REQUIRE-MATCH, when non-nil, forces the user to select an existing candidate. When nil (the default), arbitrary input not present in TABLE is accepted and returned verbatim.
CATEGORY is an optional completion-category symbol surfaced as table metadata. Completion UIs (vertico, embark, marginalia) use it to select annotations, keybindings, and actions. Common values:
‘file’ – file-name actions, path display via marginalia ‘buffer’ – buffer switching and embark buffer actions ‘command’ – M-x style command dispatch ‘symbol’ – Lisp symbol lookup and eldoc integration ‘bookmark’ – bookmark-jump actions ‘consult-grep’ – consult grep result actions (jump to line, etc.) ‘consult-mu’ – consult-mu mail account entries
HISTORY is a symbol key into ‘annotated-completing-read-history’ (a hash table of per-command history lists). Defaults to ‘this-command’ captured at call time, giving each command its own isolated history automatically. Pass an explicit symbol to share history across several call sites.
GROUP-NAME is a function (CANDIDATE) => group-name-string that returns which group a candidate belongs to, or a plain string for a single constant group. When nil, no grouping metadata is emitted.
GROUP-DISPLAY is an optional function (CANDIDATE) => display-string that controls how a candidate is rendered within its group. Defaults to identity (candidate displayed verbatim). Only meaningful when GROUP-NAME is set.
Together GROUP-NAME and GROUP-DISPLAY are assembled into the ‘group-function’ completion metadata entry expected by vertico and other UIs.
INITIAL-INPUT is an optional string pre-filled into the minibuffer.
SORT-FN is an optional function (LIST-OF-STRINGS) => LIST-OF-STRINGS that reorders candidates before display. Surfaced as ‘display-sort-function’ in completion metadata, so vertico and other UIs apply it before rendering.
DEFAULT is a string returned when TABLE is empty (no prompt is shown), the user accepts empty input, or the user quits with C-g. When non-nil it is also passed to ‘completing-read’ as its DEF argument so completion UIs can display it in the prompt.
OR-NIL, when non-nil, silences C-g and empty input by returning nil instead. Useful when the caller treats nil as “nothing selected” without needing a specific fallback string. Takes effect only when DEFAULT is nil; DEFAULT takes precedence.
TABLE may be a hash table, a dotted alist ((CANDIDATE . ANNOTATION) …), or a list-form alist ((CANDIDATE ANNOTATION) …). ANNOTATION may be nil to suppress the annotation for that candidate. Signals ‘user-error’ for any other type.
(fn &optional &key PROMPT SEED INITIAL-INPUT HISTORY)
Select a string from context-aware candidates with PROMPT. Candidates are drawn from thing-at-point, the active region, the current line, the kill ring, and any explicit SEED strings. SEED may be a string or a list of strings.
HISTORY is a symbol passed to ‘annotated-completing-read’ to scope the per-command history; defaults to ‘this-command’, giving each calling command its own isolated history.
(fn &optional &key CANDIDATES PROMPT REQUIRE-MATCH)
Select a directory with annotated completion. CANDIDATES is an explicit list of directory paths; if nil, a context-aware list is computed from the project root, open buffers, and ‘thing-at-point’. PROMPT defaults to “directory: “. REQUIRE-MATCH is passed through to ‘annotated-completing-read’.
With 8 or fewer candidates the annotation shows the directory’s relationship to the current directory (“parent”, “project root”, etc.). With more than 8 candidates candidates are grouped by that relationship label and the annotation shows entry counts instead.
Persist ACR history across sessions via savehist and desktop. Call this once after enabling ‘savehist-mode’ or ‘desktop-save-mode’. ‘annotated-completing-read-history’ is a hash table; both mechanisms can serialize it in Emacs 28+.
Copyright (C) tychoish. GPL-3.0 or later. See the source file header for the full license text.