Yevgnen / ivy-rich

More friendly interface for ivy.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ivy-switch-buffer-faces-alist isn't applied when ivy-rich is enabled

lmintmate opened this issue · comments

Since at least yesterday (but might have been happening for a bit longer, I just noticed it then) the buffer names in ivy-switch-buffer aren't fontified according to the value of ivy-switch-buffer-faces-alist, but instead remain plain when ivy-rich is enabled. However, when ivy-rich and all related settings are disabled (e.g. via commenting out the relevant section of the init file) the buffer names are fontified correctly - the same is true when using ivy by itself on an otherwise 'emacs -q' config as done by the 'make plain' recipe for reproducing bugs given on the ivy/counsel/swiper repository. Since there was a slew of commits in the ivy/counsel/swiper repository in the past few days, while the state of the code of ivy-rich hasn't changed recently, I suspect that one of the changes in upstream changed the way the default candidate is fontified at least for ivy-switch-buffer, and thus ivy-rich-candidate/identity receives a non-fontified version. I'm not sure which exact commit introduced the problem, but I supect the culprit is to be found among the commits that took place on April 24th, since those modified ivy-switch-buffer-transformer.
Thanks in advance for your understanding.
system details: emacs 26.3, Windows 10, latest versions of ivy/counsel/swiper and ivy-rich as provided from MELPA.

Thanks for reporting! I will look into it as soon as I have time.

After a quick look at the ivy changes, it seems that ivy moved its face applied logic into its original transformer, i.e. ivy-switch-buffer-transofrmer, while in the old days, faces were applied when constructing buffer list (outside ivy-switch-buffer-transofrmer). Since ivy-rich replaces its original transformer, one will not get faces applied in the original transformer.

A solution to this is to replace ivy-rich-candidate/identity with ivy-switch-buffer-transformer in your ivy-switch-buffer-faces-alist. Just like the default value of ivy-switch-buffer-transformer,

counsel-M-x
(:columns
 ((counsel-M-x-transformer (:width 40)) ;  <---------- call original transformer
  (ivy-rich-counsel-function-docstring (:face font-lock-doc-face))))

call the original transformer to get better experiences.

Hope that help.

I have various functions added to ivy-rich-display-transformers-list in my init file using plist-put, so I ended up adding the ivy-rich declaration for ivy-switch-buffer in my init, replacing ivy-rich-candidate/identity with ivy-switch-buffer-transformer, like so:

  (plist-put ivy-rich-display-transformers-list
  'ivy-switch-buffer
    '(:columns
     ((ivy-switch-buffer-transformer (:width 30))  ; return the candidate itself
      (ivy-rich-switch-buffer-size (:width 7))  ; return the buffer size
      (ivy-rich-switch-buffer-indicators (:width 4 :face error :align right)); return the buffer indicators
      (ivy-rich-switch-buffer-major-mode (:width 12 :face warning))          ; return the major mode info
      (ivy-rich-switch-buffer-project (:width 15 :face success))             ; return project name using `projectile'
      (ivy-rich-switch-buffer-path (:width (lambda (x) (ivy-rich-switch-buffer-shorten-path x (ivy-rich-minibuffer-width 0.3))))))  ; return file path relative to project root or `default-directory' if project is nil
     :predicate
     (lambda (cand) (get-buffer cand))))

This fontified again the buffer names that are fontified by ivy-switch-buffer-faces-alist both in ivy-switch-buffer itself and also in counsel-switch-buffer, which somehow inherited the properties of ivy-switch-buffer (which is for the better, as I used to have an ivy-rich declaration for that, as the first time I tried ivy-rich it didn't apply for counsel-switch-buffer).
I had added however some additional properties to ivy-switch-buffer-faces-alist (which, in case it isn't clear, is a variable that determines which types of buffers will be fontified by which faces when ivy-switch-buffer-transformer is applied. The default is to apply the ivy-subdir face to dired buffers and the ivy-org face to org buffers). In my config, I also added elisp, helpful and ivy-occur buffers, like so:

(add-to-list 'ivy-switch-buffer-faces-alist '(emacs-lisp-mode . font-lock-keyword-face))
(add-to-list 'ivy-switch-buffer-faces-alist '(helpful-mode . font-lock-comment-face))
(add-to-list 'ivy-switch-buffer-faces-alist '(ivy-occur-mode . font-lock-comment-face))

From these, only the emacs-lisp-mode face got applied now, for some reason, while before the change in ivy all of them were applied to the respective buffers. This might have to do with the fact that this code is loaded before ivy-rich and before helpful, but I'll have to investigate further.
Still, the fact that this worked, even partially, means that replacing ivy-rich-candidate with ivy-switch-buffer-transformer in the ivy-switch-buffer definition made in ivy-rich is a valid solution for this problem, and making this modification in the code of ivy-rich would mean that one wouldn't need to copy the whole snippet of ivy-switch-buffer in their init in order to have colored buffer names working.

Looking into here, if you eval things like (buffer-modified-p (get-buffer "*helpful macro: defun*")), it will return t and thus the helpful buffer will get a ivy-modified-buffer face. So your setting

(add-to-list 'ivy-switch-buffer-faces-alist '(helpful-mode . font-lock-comment-face))

has no effect. This is an upstream change, and even you disable ivy-rich, you won't get a font-lock-comment-face for helpful-mode buffers.

Looking into here, if you eval things like (buffer-modified-p (get-buffer "*helpful macro: defun*")), it will return t and thus the helpful buffer will get a ivy-modified-buffer face. So your setting

(add-to-list 'ivy-switch-buffer-faces-alist '(helpful-mode . font-lock-comment-face))

has no effect. This is an upstream change, and even you disable ivy-rich, you won't get a font-lock-comment-face for helpful-mode buffers.

Thanks for this pointer. Just tried to check ivy-occur buffers too, and this type of buffer is also detected as "modified" - such a pity, as I really wanted to be able to make these less prominent in the buffer list. I could change the ivy-modified-buffer face (because as it turns out, it's just plain text in the theme I use), but since it's supposed to be for modified buffers in general (and thus also ones where I might not want a less prominent color), I'm not sure what color I'd choose. At any rate, with the newest version of ivy-rich from MELPA as of the time of this writing (commit 3f818b2) this problem is solved, and since I can live without helpful and ivy-occur buffers being colored, I'm closing the issue. Thanks again for all your help.

You're welcome. You might want to implement you own ivy-switch-buffer-transformer and ivy-modified-buffer is not really necessary or just use ivy-rich-switch-buffer-indicators when it is.