20 Jul 2019
Ivy is a completion method that's
Ido, but with emphasis on simplicity and customizability.
The current release constitutes of 398 commits and 6 months of
0.11.0. Many issues ranging from
#2151 were fixed.
The number of people who contributed code as grown to
Details on changes
Changelog.org has been a part of the repository since
can get the details of the current and past changes:
Many improvements are incremental and don't require any extra code to
enable. I'll go over a few selected features that require a bit of
information to make a good use of them.
- M-o c copy file.
- ` bookmarks: efficiently jump between recent directories.
- $ directories stored in environment variables.
- C-DEL go up directory. Customize:
- RET open file. Customize:
- // when on remote, cd to remote root.
- / C-j select local root.
- ~ when on remote, cd to remote home.
- / C-j ~ cd to local home from remote.
- M-o v open the current commit in
- C-x C-d change the current directory for grep.
- C-v to scroll down.
- M-v to scroll up.
- m mark and move down.
- u unmark and move down.
- DEL move up and unmark.
- t toggle marks.
- d perform the action on all marked elements.
- C-k kill buffer.
- M-o x open buffer file externally.
- C-k remove item from the history.
New Commands extensions
These commands are new variants and adaptations of existing commands.
Thing at point variants:
Search variants that go backwards:
A variant of
ivy-switch-buffer with live preview:
counsel-dired - like
counsel-find-file, but open
swiper-isearch-toggle - toggle between
I have put these separately so they don't get lost in the crowd. Be sure to try them out.
counsel-compile - completion for
counsel-register - completion for registers.
counsel-minor - completion for minor modes.
swiper-isearch - a faster
swiper that's not line-based.
Again, thanks to all the contributors. Happy hacking!
09 Jul 2019
I'm sure many are aware of the C-r functionality in bash (a whole lot of Emacs
bindings are valid in bash and do the same thing). I also like the quirky Emacs-style prompt, that
uses a backquote to open and a straight quote to close a your quoted input:
So when you want to
cd to somewhere where you were before you do C-r
cd. And then the
C-r "roulette" begins: you keep pressing C-r over and over, in the hopes to find
what you were looking for.
Getting better history completion with Ivy
Ivy improves the "roulette" situation in two ways:
- You get an overview of the matching candidates and their count,
- You can quickly narrow down the candidates with fuzzy matching.
Here's the basic setup to enable C-r completion using ivy:
(kbd "C-r") 'counsel-minibuffer-history)
(kbd "C-r") 'counsel-shell-history)
The first key binding is also part of
counsel-mode, while the second needs to be set up separately,
shell-mode was loaded.
And here's how
counsel-shell-history looks like:
The cool thing is that
ivy-reverse-i-search applies to any Ivy command, not just for shell
command completion. I find it especially useful for:
Recent improvement: delete history items
While searching with regexes is great, it's not so great when the old stuff that we won't ever need
gets in the way. So now you can delete it with C-k. Since C-k also has to
ivy-kill-line, the history deleting behavior will only come into effect when the point is
at the end of the line (so that
ivy-kill-line does not make sense anyway).
This way, your typos don't stay around to haunt you.
I hope you'll find
ivy-reverse-i-search a useful boost to your completion needs. Happy hacking!
27 Jun 2019
When Ivy just started out as a completion framework, the
functionality was supposed to be simple: select one string from a list of strings. The UI is simple
- Show the list of strings that match the entered text,
- Use C-n and C-p to navigate them,
- Use C-m or C-j to submit.
Emacs has three key bindings that mean "Enter": RET, C-m, and
C-j. But in terminal mode,
emacs -nw, RET and C-m are the same
binding: Emacs can't distinguish them. So we have at most two bindings. Fortunately, the world of
completion is simple at the moment, and we only need one binding.
File name completion
Enter file name completion. When you're completing file names, you are selecting not one string, but
many strings in succession while moving from one directory to the next. So we need at least two key
- Use C-m (
ivy-done) to select the current candidate and exit completion.
- Use C-j (
ivy-alt-done) to change the current directory to the current candidate without exiting completion.
What to do when C-j is used on a file and not on a directory? Might as well open the
file: same action as C-m. OK, we had two key bindings, and we have used them. Hopefully
nothing else comes up.
Enter creating a new file, i.e. selecting something that's not on the list of strings.
Suppose I call
find-file, enter "do", and the only match is a directory named "doc":
- Pressing C-m will end completion with the "doc" directory selected.
- Pressing C-j will continue completion inside the "doc" directory.
So creating a file named "do" is the third action. Our two "Enter" keybindings are already taken by
the first two different useful actions. So we need a third key binding. The one I chose is
ivy-immediate-done). It means: I don't care that the current input is not on
the list of candidate strings, submit it anyway.
Enter directory creation:
make-directory. These built-in Emacs
commands request file name completion, but what they tell Ivy is no different from what
tells: "I want to select a file". However, for these commands, the C-M-j action is the
one that makes most sense. Here it would be nice for Ivy to take the back seat and just act like an
ls, since the user will enter a completely new string that's not on the list of
For a long time, you still had to use C-M-j with those commands, to much frustration of
new but also existing users, including myself. But a few days ago, I looked at the prompt that
dired-create-directory uses: "Create directory: ". That prompt is passed to Ivy. Using the prompt
to detect the intention of the command is a bit of a hack, but I think in this case it's
justifiable. So now Ivy will recognize that the intention commands that request file name completion
and pass the "Create directory: " prompt is to create a directory, and all key bindings will do just
that: C-m, C-j, and C-M-j will behave the same in this case.
An alternative key binding scheme
Note that C-m and C-j behave differently only for directories. But thanks to
the fact that "." is always the first candidate, C-m for directories is equivalent to
C-j C-j. So we can get away with just using
ivy-alt-done, and bind C-m to
ivy-immediate-done. Or swap the two meanings:
(define-key ivy-minibuffer-map (kbd "C-j") 'ivy-immediate-done)
(define-key ivy-minibuffer-map (kbd "C-m") 'ivy-alt-done)
The price to pay here is the extra context switch when we simply want to select a directory. We
could the bind
ivy-done to C-M-j and avoid the context switch, but then we're back to
three bindings once more. Still, I thought that swapping the bindings is an interesting idea worth
dired-dwim-target is a nice productivity boost. It allows to use Emacs in a similar way to
a two-pane file explorer, like mc(1). But it was really annoying when I was in
dir-1 with the
intention to copy a file to a different name in
dir-1 (e.g. create a backup, or copy a template),
but the current directory was set to
dir-2 because of a random
dired window I had open. In that
case, I had to call
delete-other-windows, perform the copy, and then restore the window
I did the above many times over many years, until I finally dug into the code of
dired.el to see
dired-dwim-target worked. Turns out it was storing
dir-1 in the
variable. So now Ivy will use that variable when I press M-n. All in all, it was a five
minute fix. But rather than regret that I didn't do it years ago, I'm glad I did it now. It only
remains to build some muscle memory to press M-n in that situation.
I'm guesstimating that
dired-dwim-target works to my advantage 90% of the time when I press
dired. For the other 10% of the times, I can now press M-n.
I hope you find the new functionality useful. I'm always open to new ideas and pull
requests. Happy hacking!
18 May 2019
This release consists of 45 commits done over the course of the last 2 years. With this version, I
have introduced a
similar to what ivy and
Display hints using posframe
A new defcustom
hydra-hint-display-type was introduced that can be either
lv (the default),
Posframe is a package that leverages a new feature in Emacs
26.1: the ability to display child frames. The advantage of using child frames is that you can
easily position them anywhere within your frame area. For example, the default setting is to put it
in the center of the current window, which is closer to where your eyes are focused than the
minibuffer. Child frames don't interfere with the content of the buffers which they
overlap. Finally, you can select a different font for the child frame.
Less boilerplate in defhydra
You no longer have to add
:hint nil, and you can skip the docstring as well:
(defhydra hydra-clock (:exit t)
("q" nil "quit" :column "Clock")
("c" org-clock-cancel "cancel" :column "Do" :exit nil)
("d" org-clock-display "display")
("e" org-clock-modify-effort-estimate "effort")
("i" org-clock-in "in")
("j" org-clock-goto "jump")
("o" org-clock-out "out")
("r" org-clock-report "report"))
Add heads to an existing hydra
You can now add heads to an existing hydra like this:
(defhydra hydra-extendable ()
("j" next-line "down"))
(defhydra+ hydra-extendable ()
("k" previous-line "up"))
The new macro
defhydra+ takes the same arguments as
defhydra, so it's quite easy to split up or
join your hydras.
The use case of
defhydra+ is when you have many packages that want to add heads to an existing
hydra. Some of them may be optional or loaded lazily.
You can now have a base
defhydra, and then use
defhydra+ to add heads to it when a new package
is loaded. Example:
(defhydra hydra-toggle ()
("q" nil "quit" :column "Exit")
(format "whitespace-mode: %S" whitespace-mode)
(defhydra+ hydra-toggle ()
(format "org link display: %S" org-descriptive-links))))
Big thanks to all contributors, and I hope you enjoy the new release. Happy hacking!
PS. Thanks to everyone who supports me on Liberapay and
11 May 2019
This release consists of 109 commits done over the course of the last 3 years by me and many
contributors. Similarly to the
release, the release notes are in
Changelog.org. I recommend
reading them inside Emacs.
A lot of new code is just straight upgrades, you don't need to do
anything extra to use them. Below, I'll describe the other part of the
new code, which is new commands and custom vars.
New API functions
New functions have been added as drop-in replacements of double-dash (private) Avy functions that
were used in other packages and configs. Please replace the references to the obsolete functions.
avy-jump is a drop-in replacement of
avy-process is a drop-in replacement of
New dispatch actions
The concept of dispatch actions was introduced in 0.4.0.
Suppose you have bound:
(global-set-key (kbd "M-t") 'avy-goto-word-1)
and a word that starts with a "w" and is select-able with "a". Here's what you can do now:
- M-t w a to jump there
- M-t w x a -
avy-action-kill-move: kill the word and move there,
- M-t w X a -
avy-action-kill-stay: kill the word without moving the point,
- M-t w i a -
avy-action-ispell: use ispell/flyspell to correct the word,
- M-t w y a -
avy-action-yank: yank the word at point,
- M-t w t a -
avy-action-teleport: kill the word and yank it at point,
- M-t w z a -
avy-action-zap-to-char: kill from point up to selected point.
You can customize
avy-dispatch-alist to modify these actions, and also ensure that there's no
overlap with your
avy-keys, if you customized them.
avy-style setting: 'words
You can now customize:
And you'll see overlays like "by", "if", "is", "it", "my" for 2-letter sequences, and "can", "car",
"cog" for 3-letter sequences. You might find them easier to type than "hla", "lls" and "jhl". But
you will have to adjust your
avy-dispatch-alist, e.g. to use only upper case characters.
This is feature is a mix of
ace-window-display-mode. You'll see the overlays when
you enable this mode, so that there's less context switch when you call
Suppose you jumped to a word that starts with "a". Now you want to jump to a different word that
also starts with "a". You can use
avy-resume for this.
Additionally, you can use
avy-prev to cycle between the last
candidates. Here's an example hydra to facilitate it:
(defhydra hydra-avy-cycle ()
("j" avy-next "next")
("k" avy-prev "prev")
("q" nil "quit"))
(global-set-key (kbd "C-M-'") 'hydra-avy-cycle/body)
Big thanks to all contributors, and I hope you enjoy the new release. Happy hacking!