abo-abo / swiper

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

Highlighting not adjustable to custom matcher #1177

Open erlendfu opened 7 years ago

erlendfu commented 7 years ago

I use a custom matcher (and display transformer) with ivy-read. The matcher excludes a portion of the candidate strings from matching, just like counsel-git-grep-matcher excludes the filename and line number. However, the excluded part of the candidate string is still highlighted (if it contains some text I searched for), even though it was actually ignored by the matcher.

In ivy--highlight-default, there is an exception made for certain callers, to exclude the filename and line number from highlighting. There seems to be no way I can achieve the same for my custom matcher/caller. Is this true, or am I overlooking something?

abo-abo commented 7 years ago

I think you might have to customize ivy-highlight-functions-alist as well.

erlendfu commented 7 years ago

Thanks for the feedback! I think what you suggested can be used to achieve my goal, however in a somewhat cumbersome way. I will explain what I mean:

ivy-highlight-functions-alist ties highlighting functions to re-builders, and not to matching functions. I don't wish to interfere with the user's choice of re-builder -- I just want to have a custom matcher that excludes part of the strings in my collection from search. Equivalent to how e.g. counsel-git-grep excludes filename and line numbers.

The counsel functions get special treatment in ivy--highlight-default, where the start of the string is excluded from highlighting:

(let ((start
         (if (and (memq (ivy-state-caller ivy-last)
                        '(counsel-git-grep counsel-ag counsel-rg counsel-pt))
                  (string-match "^[^:]+:[^:]+:" str))
             (match-end 0)
           0)))

This exclusion corresponds to the exclusion that happens in counsel-git-grep-matcher, and is independent of the choice of re-builder. So while I am easily able to create my own matcher similar to counsel-git-grep-matcher, I am not able to change the highlighting to correspond to my matcher.

I think I could make my own re-builder (wrapping around one of ivy's re-builders), and then add my own highlighting function to ivy-highlight-functions-alist. This custom highlighting function would be an excact copy of ivy--highlight-default, except with a different regex for exclusion. If I want the re-builder to be customizable, I need to wrap all the different re-builders provided by ivy, and copy more of the highlighting functions.

Conceptually, I think it would make more sense to have some sort of customizable entry point into ivy--highlight-default, to set the highlighting start point like counsel-git-grep etc. are able to do.