The code in this answer is now part of Ivy: https://github.com/abo-abo/swiper/commit/ae438ff62fa3d9b98d899afc0e97c13be2148725
Within ivy-hydra
, the m
key is bound to the command ivy-toggle-fuzzy
, which is hard-coded to toggle the variable ivy--regex-function
between the regexp-building functions ivy--regex-fuzzy
and ivy--regex-plus
.
The ivy-hydra
panel is similarly limited by the function ivy--matcher-desc
to describing ivy--regex-fuzzy
as "fuzzy" and all other values as "ivy".
I am not familiar with hydra
and whether it facilitates hot-swapping key bindings and commands, so my only suggestion (other than possibly submitting a feature request to the ivy
project) is to override the aforementioned functions to exhibit the desired behaviour:
(defvar my-ivy-builders '(ivy--regex-plus
ivy--regex-ignore-order
ivy--regex-fuzzy)
"Preferred values for `ivy--regex-function'.")
(define-advice ivy--matcher-desc (:override () my-expand-matchers)
"Return a brief description of `ivy--regex-function'."
(pcase ivy--regex-function
('ivy--regex-fuzzy "fuzzy")
('ivy--regex-ignore-order "order")
('ivy--regex-plus "plus")
(_ "other")))
(define-advice ivy-toggle-fuzzy (:override () my-rotate-builders)
"Slide `ivy--regex-function' across `my-ivy-builders'."
(when my-ivy-builders
(setq ivy--old-re nil)
(setq ivy--regex-function
(or (cadr (memq ivy--regex-function my-ivy-builders))
(car my-ivy-builders)))))
Here, my-ivy-builders
holds all preferred regexp building functions which are suitable as values of the variable ivy--regex-function
. The ivy--matcher-desc
advice simply adds support for describing more such functions with a human-readable name. You can name them whatever you like, but make sure they fit within 5 columns, otherwise the ivy-hydra
panel's formatting will become distorted. Finally, the ivy-toggle-fuzzy
advice slides ivy--regex-function
across its permitted values as listed in my-ivy-builders
. You can change the initial order of my-ivy-builders
to match both your taste and your default value for ivy--regex-function
.
I use :override
advice instead of redefining the functions with defun
because the former gets reported by the help system (i.e. describe-function
). Note that define-advice
was only added in Emacs 25.1; under Emacs 24 the advice should be written more like
(defvar my-ivy-builders '(ivy--regex-plus
ivy--regex-ignore-order
ivy--regex-fuzzy)
"Preferred values for `ivy--regex-function'.")
(defun my-ivy-matcher-descs ()
"Return a brief description of `ivy--regex-function'."
(pcase ivy--regex-function
('ivy--regex-fuzzy "fuzzy")
('ivy--regex-ignore-order "order")
('ivy--regex-plus "plus")
(_ "other")))
(advice-add 'ivy--matcher-desc :override #'my-ivy-matcher-descs)
(defun my-ivy-rotate-builders ()
"Slide `ivy--regex-function' across `my-ivy-builders'."
(when my-ivy-builders
(setq ivy--old-re nil)
(setq ivy--regex-function
(or (cadr (memq ivy--regex-function my-ivy-builders))
(car my-ivy-builders)))))
(advice-add 'ivy-toggle-fuzzy :override #'my-rotate-builders)
I think plain (') quotes were also not always supported by pcase
, so you may need to change them to backquotes (`).
Update
Further to the helpful comments by glucas below, you can forgo advising the function ivy-toggle-fuzzy
and instead replace it with an adjusted my-ivy-rotate-builders
in the hydra
keymap under the default keybinding of m
:
(defvar my-ivy-builders '(ivy--regex-plus
ivy--regex-ignore-order
ivy--regex-fuzzy)
"Preferred values for `ivy--regex-function'.")
(define-advice ivy--matcher-desc (:override () my-expand-matchers)
"Return a brief description of `ivy--regex-function'."
(pcase ivy--regex-function
('ivy--regex-fuzzy "fuzzy")
('ivy--regex-ignore-order "order")
('ivy--regex-plus "plus")
(_ "other")))
(defun my-ivy-rotate-builders ()
"Slide `ivy--regex-function' across `my-ivy-builders'."
(interactive)
(when my-ivy-builders
(setq ivy--old-re nil)
(setq ivy--regex-function
(or (cadr (memq ivy--regex-function my-ivy-builders))
(car my-ivy-builders)))))
(with-eval-after-load 'ivy-hydra
(define-key hydra-ivy/keymap "m" #'my-ivy-rotate-builders))
Perhaps someone more familiar with hydra
can also suggest an easy way to modify the hydra-ivy
hint/panel in-place instead of advising ivy--matcher-desc
.
m
(ivy-toggle-fuzzy
) to rotate between them all?C-h f
and search for eitherspell
or^ spell
-- that is, delete the leading^
or add a space after it. That said, I think your suggestion to be able to toggle matching styles is a good one and perhaps should be a feature request for ivy.