Tweaking Vertico candidates

One of the Emacs packages I do not seem to get used to is Marginalia.1 There is nothing wrong with it and since Daniel Mendler is involved the ELisp underneath is great. However, to me it’s just too much information where I rarely want it. When I need that sort of documentation it’s always a quick key binding away.

Given the author it should not come as a surprise that Marginalia works rather smoothly with Vertico.2 In fact, it works so well that I only see a “problem” when I use it without Marginalia. Months ago I reported this minor glitch to Daniel,3 but to cut a long story short, at the end of the current selected item vertico--format-candidate adds a newline escape sequence to which the vertico-current face is applied as well.

I know, it’s a minor thing that should not stop me from using Vertico. Still, it can be fixed quite easily. I suggested an advice in the aforementioned report, but since vertico--format-candidate is implemented as a cl-defgeneric I can do better:

(with-eval-after-load 'vertico
  (set-face-attribute 'vertico-current nil :extend nil)
  (cl-defmethod vertico--format-candidate (cnd pref suf idx _start)
    "Format CND given PREF, SUF, and IDX."
    (setq cnd (vertico--display-string (concat pref cnd suf "\n")))
    (when (= idx vertico--index)
      (add-face-text-property 0 (1- (length cnd)) 'vertico-current 'append cnd))

Beside ensuring that vertico-current does not extend beyond the selected candidate, I use the lovely named 1- function to avoid applying this face to \n as well.

Note that something like fido-vertical-mode does not need a hack like this. Yet I simply cannot resist tinkering with my favourite packages.

  1. See: Marginalia

  2. See: Vertico

  3. See: vertico#269