abo-abo / swiper

Ivy - a generic completion frontend for Emacs, Swiper - isearch with an overview, and more. Oh, man!
https://oremacs.com/swiper/
2.32k stars 339 forks source link

ivy current match's and other matches' background colors #2907

Open ville-h opened 3 years ago

ville-h commented 3 years ago

I do not understand at all which face attribute affects what exactly and how they do it. It is confusing because it's not just the face named ivy-current-match, or group of such faces, that affects how the current match is drawn. Apparently the ivy-minibuffer-match-face-1, -2, -3 and -4 affect it as well:

emacs_ivy_colors_0

(set-face-attribute 'ivy-current-match nil :foreground "black" :background "orange" :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-1 nil :foreground "orange" :background "#202020" :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-2 nil :foreground "orange" :background "#202020" :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-3 nil :foreground "orange" :background "#202020" :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-4 nil :foreground "orange" :background "#202020" :weight 'normal)

Then with some :background changes:

emacs_ivy_colors_1

(set-face-attribute 'ivy-current-match nil :foreground "black" :background "orange" :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-1 nil :foreground "orange" :background "#ff2020" :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-2 nil :foreground "orange" :background "#20ff20" :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-3 nil :foreground "orange" :background "#2020ff" :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-4 nil :foreground "orange" :background "#ffffff" :weight 'normal)

It's clear that the ivy-minibuffer-match-face-# have an effect on how the current match is drawn, but it is unclear to me what the exact mixing operation used is? how do the :background attributes get mixed from ivy-current-match and the various ivy-minibuffer-match-face-#?

And setting the :background to nil: emacs_ivy_colors_2

(set-face-attribute 'ivy-current-match nil :foreground "black" :background "orange" :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-1 nil :foreground "orange" :background nil :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-2 nil :foreground "orange" :background nil :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-3 nil :foreground "orange" :background nil :weight 'normal)
(set-face-attribute 'ivy-minibuffer-match-face-4 nil :foreground "orange" :background nil :weight 'normal)

Some "mysterious" colors appear none the less on the others.

It would be clearer if there were separate faces for the current match and the non-current match, rather than this situation where the ivy-minibuffer-match-face-# affect the current match through some undocumented(?) mixing operation.

Personnally I don't care to see the various matches in separate colors. I just want a solid background color for the current match and no funny colors on the others. So far I've not found a combination to achieve this.

basil-conto commented 3 years ago

FWIW, the colours are a bit clearer in my config with

(setq ivy-re-builders-alist '((t . ivy--regex-ignore-order)))

ignore


Each regexp builder has its own highlighting function by default, see ivy-highlight-functions-alist.

From your screenshots I can't tell which regexp builder you're using. Is it ivy--regex-fuzzy? If so, maybe ivy--highlight-fuzzy has room for improvement; patches welcome (I don't use it and am not familiar with it, sorry).


In order to limit the angry fruit salad to a smaller number of faces, you can customise ivy-minibuffer-faces. For example:

(setq ivy-minibuffer-faces '(ivy-minibuffer-match-face-1
                             ivy-minibuffer-match-face-2))

list


See also the user option ivy-use-group-face-if-no-groups.


Personnally I don't care to see the various matches in separate colors. I just want a solid background color for the current match and no funny colors on the others. So far I've not found a combination to achieve this.

Have you tried setting ivy-display-style to nil? Here's what that looks like for me:

plain

ville-h commented 3 years ago

I am using ivy--regex-plus as the re-builder.

Limiting ivy-minibuffer-faces does work as a way to limit what sort of colors get shown. It still exhibits the unexpected mixing of the :background between the current match face and the the chosen minibuffer face.

Setting ivy-display-style to nil does accomplish the solitary solid-color current match.

If you look at my first screenshot where and how is that dark "orange" background on the current match for ".co" coming from? There appears to be no direct way to control what that color is. It seems to be derived from the current match's background color and from one of the minibuffer face's background colors. It is unclear what this derivation is. It would be better to have direct control over this/these colors.

basil-conto commented 3 years ago

It would be better to have direct control over this/these colors.

Indeed. Help/patches welcome.