ivy, say I want the current match to be red when calling
counsel-M-x, but blue when calling
Is there a simple way of changing
ivy-current-match depending on the function calling it?
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.Sign up to join this community
AFAIK, there is no built-in support for this, but Ivy provides various hooks that you can plug your own logic into. Here is one way to achieve what you want, using the
ivy-hooks-alist user option:
(defvar my-ivy-match-faces '((counsel-M-x (:background "red"))) "Alist mapping Ivy callers to a list of face specs. Used by `my-ivy-remap-match-face', which see.") (defun my-ivy-remap-match-face () "Locally remap `ivy-current-match' to caller-specific face specs. Which face specs to apply for each caller is determined by `my-ivy-match-faces'. If the current caller is unknown, or if there is no entry for it, no remapping is applied." (when-let* ((caller (ivy-state-caller ivy-last)) (specs (alist-get caller my-ivy-match-faces))) (apply #'face-remap-add-relative 'ivy-current-match specs))) (with-eval-after-load 'ivy ;; Remap the current match face as the default Ivy hook. Note that specifying ;; a different hook for a particular caller will override this setting. (setf (alist-get t ivy-hooks-alist) #'my-ivy-remap-match-face))
The idea here is to look up the current Ivy caller (e.g.
counsel-M-x) right after Ivy has set up the minibuffer, and then locally remap the
ivy-current-match face to a list of face specs of your choosing. In the sample code above, I have remapped the background to be red for
counsel-M-x (see the variable
Note that the way I modify
ivy-hooks-alist, namely by setting
my-ivy-remap-match-face as the default fallback hook, is kind of brittle. This is because any subsequent addition to this alist may override
my-ivy-remap-match-face. Vanilla Ivy does not modify
ivy-hooks-alist, so this is not an issue at the moment, but it may become one in the future or if you use other packages which modify this user option.
A more robust solution would then be to submit a feature request or PR to make
ivy-hooks-alist more flexible, e.g. by supporting multiple hooks per caller, and always running the default fallback hooks.
If that is not an option, you can advise specific entries in
ivy-hooks-alist to do your bidding. I will be happy to provide a sample implementation of this if asked.