Ivy-mode 0.6.0 is out
05 Aug 2015For those who don't keep up,
ivy-mode is a completion method
that's similar to ido
, but with emphasis on simplicity and
customizability. Currently, there are two related packages on MELPA:
swiper
and counsel
:
swiper
provides anisearch
replacement, usingivy-read
for completion, as well as the basicivy-mode
.counsel
provides some extra commands, like-M-x
,-ag
,-load-theme
etc.
The reasoning behind the split into two packages is that there's less update overhead if only one of them is updated.
completing-read-function
conundrum
This is to explain a bit the presence of the counsel
package. Initially, I hoped that ivy-mode
could do most of the work,
via the Emacs' completing-read-function
interface. How it works:
most built-in packages will call completing-read
when they require
completion. That function will forward the completion to
completing-read-function
if it's set. This is the way how things
like icomplete-mode
or ivy-mode
or helm-mode
work.
Unfortunately, the interface rather limits what you can do in
completing-read-function
. Essentially, you're given a list of
strings and you have to return a string. You have no idea which
function called you, so you can't do any fancy stuff depending on the
caller, short of examining this-command
which isn't very reliable.
You have no idea what will be done with the one string that you
return, so you can't do something fancy like select two or three
strings and perform that action for each of them.
The result is that sometimes I have to replace the built-in functions,
instead of re-using them. So instead of re-using find-file
, I wrote
my own counsel-find-file
that looks like this:
(defun counsel-find-file ()
"Forward to `find-file'."
(interactive)
(ivy-read "Find file: " 'read-file-name-internal
:matcher #'counsel--find-file-matcher
:action
(lambda (x)
(with-ivy-window
(find-file (expand-file-name x ivy--directory))))
:preselect (when counsel-find-file-at-point
(require 'ffap)
(ffap-guesser))
:require-match 'confirm-after-completion
:history 'file-name-history
:keymap counsel-find-file-map))
It's still possible to call the original find-file
, and you'll get
ivy-read
completion for it, but:
ivy-resume
won't work, sinceivy-read
doesn't know what to do with the string that you select.- C-M-n (
ivy-next-line-and-call
) won't work to select another file within the same completion session, for the same reason. - M-o (
ivy-dispatching-done
) may work with some customization, but since it dispatches onthis-command
to get the extra actions, it can cause a problem if the command wasn't called directly.
I think it would be cool to extend the built-in
completing-read-function
interface in the future Emacs
versions. Both Ivy and Helm (which uses the same strategy of passing
the action to the completion) would benefit from this.
Release summary and highlights
It's been two months and 150 commits since the last version. The full release notes can be found inside the repository in Changelog.org or at Github's release tab.
I recommend to look through the whole list to see if anything catches your attention. I'll highlight a few things that I think the users might be interested in most.
Fuzzy completion
This is off by default, since I think having less candidates is better than having more. You can customize this for all commands or per-command. For example:
(setq ivy-re-builders-alist
'((t . ivy--regex-fuzzy)))
swiper
has a case-fold-search
optimization
Binds case-fold-search to t when the input is all lower-case:
- input "the" matches both "the" and "The".
- input "The" matches only "The".
Anzu things
To see not only the number of matched candidates, but also the index of the current one, set this:
(setq ivy-count-format "(%d/%d) ")
Customize additional exit points for any command
For any command that uses ivy-read
that is. Example for ivy-switch-to-buffer
:
(ivy-set-actions
'ivy-switch-buffer
'(("k"
(lambda (x)
(kill-buffer x)
(ivy--reset-state ivy-last))
"kill")
("j"
ivy--switch-buffer-other-window-action
"other")))
After this:
- Use M-o k to kill a buffer.
- Use M-o j to switch to a buffer in other window.
You can always use M-o o to access the default action. When there is only one action, M-o does the same as C-m.
More descriptions with a built-in Hydra
Toggle C-o in any completion session to get an overview of the things that you can do.
Many commands that interface with shell calls
The following commands will call the appropriate shell tool to give you a list of candidates:
counsel-git-grep
counsel-ag
counsel-locate
counsel-recoll
These commands will refresh after each new letter entered, and they account for the fact that the shell call will usually take more time than the time it takes to input a new letter. So the process will be killed and restarted, resulting in virtually no keyboard delay and no downtime.
Many commands that offer more options than the built-in counterparts
This list includes:
counsel-find-file
,counsel-M-x
,counsel-load-theme
,counsel-org-tag
andcounsel-org-tag-agenda
.
Most extra things that you can do are:
- Doing stuff with multiple candidates through C-M-n like in this video.
- Using
ivy-resume
to resume the last completion session.
Make sure to try counsel-org-tag
, this one is a bit tricky for
completion, since it requires to return multiple candidates at once.
So you can toggle each tag with C-M-m (ivy-call
) and then
exit with C-m (ivy-done
). The currently selected tags
will be displayed in the prompt.
Outro
A big thanks to all people who contributed code and issues towards this release. I'm really happy that you're helping me to refine this nice package.