To install this package, run in Emacs:
M-x package-install RET marginalia RET
This package provides
marginalia-mode which adds marginalia to the
Marginalia are marks or
annotations placed at the margin of the page of a book or in this case
helpful colorful annotations placed at the margin of the minibuffer for
your completion candidates. Marginalia can only add annotations to be
displayed with the completion candidates. It cannot modify the
appearance of the candidates themselves, which are shown as supplied by
the original commands.
The annotations are added based on the completion category. For example
find-file reports the
file category and
M-x reports the
command category. You
can cycle between more or less detailed annotators or even disable the annotator
It is recommended to use Marginalia together with either the Selectrum, Vertico or the Icomplete-vertical completion system. Furthermore Marginalia can be combined with Embark for action support and Consult, which provides many useful commands.
;; Enable richer annotations using the Marginalia package (use-package marginalia ;; Either bind `marginalia-cycle` globally or only in the minibuffer :bind (("M-A" . marginalia-cycle) :map minibuffer-local-map ("M-A" . marginalia-cycle)) ;; The :init configuration is always executed (Not lazy!) :init ;; Must be in the :init section of use-package such that the mode gets ;; enabled right away. Note that this forces loading the package. (marginalia-mode))
In general, to learn more about what different annotations mean, a good starting
point is to look at
marginalia-annotator-registry, and follow up to the
annotation function of the category you are interested in.
For example the annotations for elisp symbols include their symbol class - v for
variable, f for function, c for command, etc. For more information on what the
different classifications mean, see the docstring of
Commands that support minibuffer completion use a completion table of all the
available candidates. Candidates are associated with a category such as
variable depending on what the candidates are. Based on the
category of the candidates, Marginalia selects an annotator to generate
annotations for display for each candidate.
Unfortunately, not all commands (including Emacs' builtin ones) specify the
category of their candidates. To compensate for this shortcoming, Marginalia
hooks into the emacs completion framework and runs the classifiers listed in the
marginalia-classifiers, which use the command's prompt or other
properties of the candidates to specify the completion category.
For example, the
marginalia-classify-by-prompt classifier checks the minibuffer
prompt against regexps listed in the
marginalia-prompt-categories alist to
determine a category. The following is already included but would be a way to
assign the category
face to all candidates from commands with prompts that
include the word "face".
(add-to-list 'marginalia-prompt-categories '("\\<face\\>" . face))
marginalia-classify-by-command-name classifier uses the alist
marginalia-command-categories to specify the completion category based on the
command name. This is particularily useful if the prompt classifier yields a
Completion categories are also important for Embark, which associates actions based on the completion category and benefits from Marginalia's classifiers.
Once the category of the candidates is known, Marginalia looks in the
marginalia-annotator-registry to find the associated annotator to use. An
annotator is a function that takes a completion candidate string as an argument
and returns an annotation string to be displayed after the candidate in the
minibuffer. More than one annotator can be assigned to each each category,
displaying more, less or different information. Use the
to cycle between the annotations of different annotators defined for the current
Here's an example of a basic face annotator:
(defun my-face-annotator (cand) (when-let (sym (intern-soft cand)) (concat (propertize " " 'display '(space :align-to center)) (propertize "The quick brown fox jumps over the lazy dog" 'face sym))))
Look at Marginalia's various annotators for examples of formating annotations.
In particular, the helper function
marginalia--fields can be used to format
information into columns.
After defining a new annotator, associate it with a category in the annotator registry as follows:
(add-to-list 'marginalia-annotator-registry '(face my-face-annotator marginalia-annotate-face builtin none))
This makes the
my-face-annotator the first of four annotators for the face
category. The others are the annotator provided by Marginalia
builtin annotator as defined by Emacs and the
none annotator, which disables the annotations. With this setting, after
M-x describe-face RET you can cycle between all of these annotators
Marginalia activates rich annotators by default. Depending on your preference
you may want to use the builtin annotators or even no annotators by default and
only activate the annotators on demand by invoking
In order to use the builtin annotators by default, you can use the following
none to disable annotators by default.
(defun marginalia-use-builtin () (interactive) (mapc (lambda (x) (setcdr x (cons 'builtin (remq 'builtin (cdr x))))) marginalia-annotator-registry))
If a completion category supports two annotators, you can toggle between those using this command.
(defun marginalia-toggle () (interactive) (mapc (lambda (x) (setcdr x (append (reverse (remq 'none (remq 'builtin (cdr x)))) '(builtin none)))) marginalia-annotator-registry))
After cycling the annotators you may want to automatically save the
configuration. This can be achieved using an advice which calls
(advice-add #'marginalia-cycle :after (lambda () (let ((inhibit-message t)) (customize-save-variable 'marginalia-annotator-registry marginalia-annotator-registry))))
In order to disable an annotator permanently, the
can be modified. For example if you prefer to never see file annotations, you
can delete all file annotators from the registry.
(setq marginalia-annotator-registry (assq-delete-all 'file marginalia-annotator-registry))
Since this package is part of GNU ELPA contributions require a copyright assignment to the FSF.