(or emacs irrelevant)

Introducing ivy-mode

Today I'd like to introduce a function that has completely replaced ido-mode for me: ivy-mode. It comes with the swiper package, available both in MELPA and GNU ELPA. The latter is a bit slower to update, so the version there can be a bit outdated sometimes.

The quick video demo

If you prefer listening and watching to reading, check out the video demo here. It repeats most of the stuff written down below.

Generic completion

ivy-mode is simply a minor mode that changes completing-read-function to ivy-completing-read while it's active. This function is used in most of the places where Emacs requires completion, like:

  • M-x execute-extended-command
  • C-h f describe-function
  • C-h v describe-variable
  • package-install
  • C-x b switch-to-buffer
  • C-x C-f find-file

So, while ivy-mode is on, all these functions and more will use ivy completion.

Package-specific completion

org-mode

With the most recent master version, org-mode will obey completing-read-function, so it should work by default. If you try it for refiling to headings with similar names, you'll really notice how much better ivy-mode is at it. helm-mode also does well, if you don't mind the large window.

magit

This setting is needed to use ivy completion:

(setq magit-completing-read-function 'ivy-completing-read)

find-file-in-project

find-file-in-project will use ivy by default if it's available.

projectile

You can set this to make it work:

(setq projectile-completion-system 'ivy)

smex

Yes, it's also possible, since today. Although you'll have to use my fork of smex if you want to try it. I've sent a pull request, it's all backwards-compatible, so hopefully it'll get merged.

The nice thing is that smex can take care of the sorting all by itself, since ivy doesn't do that yet.

my packages

lispy and function-args use ivy by default. You can also enable it for helm-make, for which the default is obviously helm.

File name completion

When ivy-mode is on, find-file will also use it. The completion is considerably different from all other cases, since it's done in stages, just like ido-find-file does it.

The key bindings are:

  • RET will select the current candidate and finish.
  • C-j will try to continue the completion, i.e. if the current candidate is a directory, move to that directory. But if the current candidate is a file or ./, then finish.
  • / will switch to completing the sub-directories of /, but if the candidate is a perfect match, it will act like C-j.
  • ~ will switch to completing the sub-directories of ~/.
  • C-n and C-p naturally select the next and the previous candidate.

What's it all for?

Well, for me the advantage is obvious: I get my completion just the way I like it. You can use it as well if you find that you like it more than ido. I'll just list a list of features that I like:

  • The current number of candidates is robustly displayed and updated after each key stroke.
  • The minibuffer is an actual editing area, where the bindings like C-a, M-DEL and C-k etc. work just as you expect. Once you internalize the way that the regex is built, you can get your match very quickly and intuitively.
  • The actual regular expressions constructs like \\b or $ and ^ work. The only thing that works differently is the space: you can't match a single space because any amount of spaces translates into the .* wild card. But you can use it to your advantage and use the space instead of all the various symbol joining constructs out there, like snake_case, or kebab-case (yeah, it's totally called that, check the wiki), or whatever/this/is/case.
  • The familiar M-< and M-> key bindings also work as expected, navigating you to the first and last candidate respectively. When you press C-p on the first match or C-n on the last match, the match will not change, unlike the behavior of ido that has annoyed me a lot.
  • The minibuffer key bindings can actually be properly customized: just set ivy-minibuffer-map to whatever you like, it won't be changed. Even in Emacs 24.5, if you customize ido-completion-map, the change will be reset. That was fixed only in the current master.
  • You don't have to rely on flx or flx-ido to save you from the overwhelming number of matches. Instead, you type maybe a bit more, but in return you get a very consistent and predictable result. No black boxes or hidden variables that dramatically change the order of candidates from time to time.

Outro

Check it out, I hope you like it. And a big thanks to all who contributed code or bug reports.

Display the initial Hydra hint with a delay

More hydra goodness incoming, this time thanks to @joedicastro. Firstly, he contributed this awesome-looking twittering-mode hydra to the wiki:

hydra-twittering.png

And a similarly nice one for helm:

hydra-helm-2.png

You can look up the code for both hydras by following the above two links.

Secondly, he gave me a nice idea in #108:

A nice thing that guide-key has is that you can set an idle time to wait until you press a key to activate any head before show the hydra hints buffer (explained in hydra terms). This is very helpful when you know the key bindings by memory and you do not need to see the hints buffer, but if you forget how to activate any head, you simple press the hydra binding and wait the "idle time" and the hints buffer is shown to help you to choose the right next binding.

So this option is now also possible. Here's an example, using hydra-toggle from hydra-examples.el:

(defhydra hydra-toggle (:color blue
                        :idle 1.0)
  "toggle"
  ("a" abbrev-mode "abbrev")
  ("d" toggle-debug-on-error "debug")
  ("f" auto-fill-mode "fill")
  ("t" toggle-truncate-lines "truncate")
  ("q" nil "cancel"))
(global-set-key (kbd "C-c C-v") 'hydra-toggle/body)

So the single change from the old code is :idle 1.0, which means:

After a call to hydra-toggle/body, instead of displaying the hint as usual, start a timer for 1.0 seconds. Once the timer runs out, display the hint. But if the hydra has exited before that time, cancel the timer.

Typically, I'm not a huge fan of timers, but it's nice to have the option. And indeed, I've been noticing that I could do without a hint for some simple and more often used hydras. But a command can go from often to barely used quickly, and disabling the hint altogether seems too harsh. A timer could be a nice middle ground, especially since I can decide whether to use it or not and the interval for each specific hydra.

Anyway, thanks for the contributions. Enjoy the new feature, and keep those good ideas coming!

Org-mode Hydras incoming!

A hydra for org-mode time/clock/capture

This is a categorized version of the hydra that @WorldsEndless contributed today to the wiki.

(defhydra hydra-global-org (:color blue
                            :hint nil)
  "
Timer^^        ^Clock^         ^Capture^
--------------------------------------------------
s_t_art        _w_ clock in    _c_apture
 _s_top        _o_ clock out   _l_ast capture
_r_eset        _j_ clock goto
_p_rint
"
  ("t" org-timer-start)
  ("s" org-timer-stop)
  ;; Need to be at timer
  ("r" org-timer-set-timer)
  ;; Print timer value to buffer
  ("p" org-timer)
  ("w" (org-clock-in '(4)))
  ("o" org-clock-out)
  ;; Visit the clocked task from any buffer
  ("j" org-clock-goto)
  ("c" org-capture)
  ("l" org-capture-goto-last-stored))

I've bound it like this:

(global-set-key [f11] 'hydra-global-org/body)

Previously, I had f11 bound to org-clock-goto, thanks to the Org Mode - Organize Your Life In Plain Text! post. I kind of recommend that post, as it has a tonne of useful stuff. At the same time, it resulted in me copying too much stuff that I didn't understand into my config, ultimately discouraging me from using org-mode. YMMV.

Screenshot:

hydra-org-global.png

A hydra for refile/archive

Inspired by the previous one, I wanted to write a hydra of my own. As it happened, I was just about to clean up my git notes. So I wanted a nice refile hydra to speed up the process.

Here's the hydra's code, which is now part of worf. Worf is a package for quickly navigating around an org-mode buffer, you can get it from MELPA.

(defhydra hydra-refile (:hint nil
                        :color teal)
  "
Refile:^^   _k_eep: %`org-refile-keep
----------------------------------
_l_ast      _a_rchive
_o_ther
_t_his

"
  ("t" worf-refile-this)
  ("o" worf-refile-other)
  ("l" worf-refile-last)
  ("k" (setq org-refile-keep (not org-refile-keep))
       :exit nil)
  ("a" (org-archive-subtree))
  ("q" nil "quit"))

Some explanations:

  • worf-refile-this will give you a choice of this file's headings for refiling.
  • worf-refile-other will give you a choice of your org-refile-targets except the current file.
  • worf-refile-last will refile to the last refile location without prompting.
  • k will toggle org-refile-keep, which decides if refiling moves or copies the text.

And here's how it looks like:

hydra-refile.png

Outro

Thanks for the contribution, enjoy the new stuff. Also, if you ever want to dig around someone's git notes, you can read mine, courtesy of org-mode export.

Hydra 0.13.0 is out

A lot of the changes for this release aren't very user-visible, although they are important in improving the usability. The main change is the move from the standard set-transient-map to my own hydra-set-transient-map.

This change has allowed to remove the part where the amaranth and pink hydras intercept a binding which doesn't belong to them and then try to forward it back to Emacs. It was done in this way, which might be interesting for people who write Elisp:

(define-key hydra-keymap t 'hydra-intercept)

Binding t means that when the keymap is active, any binding which doesn't belong to the keymap will be interpreted as t. Then, I would use lookup-key and this-command-keys and try to call the result. That method was quite fragile:

  • It didn't work for prefix keys while a pink hydra was active.
  • It didn't work for some keys in the terminal because of input-decode-map.

The new method solves the mentioned issues by not using t and instead running this function in the pre-command-hook:

(defun hydra--clearfun ()
  "Disable the current Hydra unless `this-command' is a head."
  (if (memq this-command '(handle-switch-frame
                           keyboard-quit))
      (hydra-disable)
    (unless (eq this-command
                (lookup-key hydra-curr-map
                            (this-single-command-keys)))
      (unless (cl-case hydra-curr-foreign-keys
                (warn
                 (setq this-command 'hydra-amaranth-warn))
                (run
                 t)
                (t nil))
        (hydra-disable)))))

This approach is actually very similar to what the built-in set-transient-map does from Emacs 24.4 onward. Of course, changing the a large cog in the Hydra mechanism can lead to some new bugs, or even old bugs to re-surface. So I really appreciate the help from @jhonnyseven in testing the new code.

As always, if you find something very broken, you can roll back to the GNU ELPA version and raise an issue.

Fixes

single command red/blue issue

Fix the uniqueness issue, when a single command is assigned to both a red and a blue head.

Here's an example:

(defhydra hydra-zoom (global-map "<f2>")
  "zoom"
  ("g" text-scale-increase "in")
  ("l" text-scale-decrease "out")
  ("r" (text-scale-set 0) "reset")
  ("0" (text-scale-set 0) :bind nil :exit t)
  ("1" (text-scale-set 0) nil :bind nil :exit t))

Here, three heads are assigned (text-scale-set 0), however their behavior is different:

  • r doesn't exit and has a string hint.
  • 0 exits and has an empty hint (so only the key is in the docstring).
  • 1 exits and has a nil hint (will not be displayed in the docstring).

The latter two call hydra-zoom/lambda-0-and-exit, while r calls hydra-zoom/lambda-r.

Don't default hydra-repeast--prefix-arg to 1

See #61 for more info.

Allow hydra-repeat to take a numeric arg

For hydra-vi, it's now possible to do this 4j.2... The line will be forwarded:

  • 4 times by 4j
  • 4 times by .
  • 2 times by 2.
  • 2 times by .

See #92 for more info.

Key chord will be disabled for the duration of a hydra

This means that hydras have become much more easy to use with key chords. For instance, if dj key chord calls a hydra or is part of the hydra, you won't call the jj key chord by accident with djj.

See #97 for more info.

New Features

Variable as a string docstring spec

You can now use this form in your hydras:

(defvar foo "a b c")
(defhydra bar ()
  "
  bar %s`foo
"
  ("a" 't)
  ("q" nil))

Previously, it would only work for %s(foo) forms.

:bind property can also be a keymap

If you remember, you can set :bind in the body to define in which way the heads should be bound outside the Hydra. You also assign/override :bind for each head. This is especially useful to set :bind to nil for a few heads that you don't want to bind outside.

Previously, :bind could be either a lambda or nil. Now a keymap is also accepted.

Integration tests

In addition to the abundant macro-expansion tests, integration tests are now also running, both for emacs24 and for emacs-snapshot. This means that hydra should be a lot more stable now.

Here's an example test:

(defhydra hydra-simple-1 (global-map "C-c")
  ("a" (insert "j"))
  ("b" (insert "k"))
  ("q" nil))

(ert-deftest hydra-integration-1 ()
  (should (string= (hydra-with "|"
                               (execute-kbd-macro
                                (kbd "C-c aabbaaqaabbaa")))
                   "jjkkjjaabbaa|"))
  (should (string= (hydra-with "|"
                               (condition-case nil
                                   (execute-kbd-macro
                                    (kbd "C-c aabb C-g"))
                                 (quit nil))
                               (execute-kbd-macro "aaqaabbaa"))
                   "jjkkaaqaabbaa|")))

In the tests above, hydra-simple is a defined and bound hydra. "|" represents the buffer text (empty), where | is the point position. And (kbd "C-c aabbaaqaabbaa") represents the key sequence that you can normally press by hand. Finally, "jjkkjjaabbaa|" is what the buffer and the point position should look like afterwards. If you find a hydra bug, it would be really cool to submit a new integration test to make sure that this bug doesn't happen in the future.

Basic error handling

I really like the use-package feature where it catches load-time errors and issues a message instead of bringing up the debugger. This is really useful, since it's hard to fix the bug with a mostly broken Emacs, in the case when the error happened early in the load process. So the same behavior now happens with defhydra. In case of an error, defhydra will be equivalent to a no-op, and the error message will be written to the *Messages* buffer.

Use a variable instead of a function for the hint

This leads up to the yet unresolved #86, which asks for heads to be activated conditionally.

For now, you can modify the docstring on your own if you wish. Here's some code from the expansion of hydra-zoom to explain what I mean:

(set
 (defvar hydra-zoom/hint nil
   "Dynamic hint for hydra-zoom.")
 '(format
   #("zoom: [g]: in, [l]: out."
     7 8 (face hydra-face-red)
     16 17 (face hydra-face-red))))
;; in head body:
(when hydra-is-helpful
  (if hydra-lv
      (lv-message
       (eval hydra-zoom/hint))
    (message
     (eval hydra-zoom/hint))))

Eventually, I'll add some automatic stuff to fix #86. But for now, you can experiment with modifying e.g. hydra-zoom/hint inside heads, if you want.

Multiple inheritance for Hydra heads

Each hydra, e.g. hydra-foo will now declare its own heads as a variable hydra-foo/heads. It's possible to inherit them like this:

(defhydra hydra-zoom (global-map "<f2>")
  "zoom"
  ("g" text-scale-increase "in")
  ("s" text-scale-decrease "out"))

(defhydra hydra-arrows ()
  ("h" backward-char "left")
  ("j" next-line "down")
  ("k" previous-line "up")
  ("l" forward-char "right"))

(defhydra hydra-zoom-child (:inherit (hydra-zoom/heads
                                      hydra-arrows/heads)
                            :color amaranth)
  "zoom"
  ("q" nil))

Here, hydra-zoom-child inherits the heads of hydra-zoom and hydra-arrows. It adds one more head q to quit. Also, it changes the color to amaranth, which means that it's only possible to exit it with q or C-g. This hydra's parents remain at their original (red) color.

See #57 for more info.

Outro

A big thanks to all who contributed towards this release and to the wiki. If you have an idea that would be cool in Hydra, do raise an issue. And if you written some cool code that uses the already available Hydra features, please share it on the wiki. It's also a good way to protect your code against regressions (although the best one would be an integration test).

Finally, check out the new version of pandoc-mode which is one of the coolest and most elaborate uses of Hydra yet.

Complete stuff with Counsel

Intro

If you like my package swiper, I'm sure you'll also like counsel. It lives in the same repository, but you can install it separately from MELPA.

Counsel uses ivy - the same method as swiper to:

  • Complete Elisp at point with counsel-el.
  • Complete Clojure at point with counsel-clj.
  • Open a git-managed file with counsel-git.
  • Describe an Elisp variable with counsel-describe-variable.
  • Describe an Elisp function with counsel-describe-function.
  • Look up an Elisp symbol in the info with counsel-info-lookup-symbol.
  • Insert a Unicode character at point with counsel-unicode-char.

Below, I'll describe the functions that I added just today.

counsel-describe-function

This is just a replacement for describe-function:

counsel-describe-function.png

As you can see, regular expressions work here as well. The space-splitting behavior is the same as in swiper, so don't expect to be able to match a single space: spaces are wild.

counsel-describe-variable

This is just a replacement for describe-variable:

counsel-describe-variable.png

Well, actually I've used ido-mode with flx matching for these two functions before. In my experience, ivy handles much better:

  • you are in charge of which regex you're searching for
  • you see the candidate count
  • no crazy wrap-around candidate cycling

And it works faster, too.

Here are my bindings:

(global-set-key (kbd "<f1> f") 'counsel-describe-function)
(global-set-key (kbd "<f1> v") 'counsel-describe-variable)

counsel-info-lookup-symbol

counsel-info-lookup-symbol.png

I don't use this one too often, but it's nice to have the option:

(global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)

counsel-unicode-char

counsel-unicode-char.png

At around 40000 candidates, ivy starts to feel clunky (around 0.1s display delay). Unfortunately, I don't really see a way around this, except using tricks like while-no-input, which didn't work right when I tried it earlier. It would be really cool to do the completion in another thread, but alas.

Outro

Give the new functions a try. I think ivy can become a viable ido replacement, at least it has done so for me: the only ido functions that I'm still using are ido-switch-buffer and ido-find-file.

Also, if you're using projectile, you can use ivy completion for it:

(setq projectile-completion-system 'ivy)