(or emacs irrelevant)

Ivy-mode 0.4.0 is out

This is a feature-packed release with a lot of cool things like:

  • Partial completion on TAB
  • Resume the last completion session with ivy-resume
  • Multi-tier regex matching

The detailed release notes follow.

Fixes

Glob expansion in rgrep

While completing file names, ivy expands the file name to full. Unfortunately, rgrep uses read-file-name-internal and isn't receptive to globs being expanded with the current directory. A work-around this is to use the generic strategy when ivy is in trouble:

  • enter the input text as if there was no completion.
  • exit with C-u C-j (forwards to ivy-immediate-done).

ivy-immediate-done is currently unbound by default. If you want, you can bind it in your config like this:

(define-key ivy-minibuffer-map (kbd "C-c C-d") 'ivy-immediate-done)

Exclude a couple more modes from font-lock

This time, they are jabber-chat-mode and elfeed-search-mode.

Fix a flag in swiper-query-replace

You can launch a query replace with M-q from swiper.

Avoid sorting org-refile candidates

By default, ivy completion candidates are sorted with string-lessp. The sorting can be customized with ivy-sort-functions-alist. While refiling, the natural order is actually best, so the sorting is turned off in that case.

Reset to the first candidate when switching directories

With ivy-mode you can select a file anywhere on your file system by switching directories repeatedly with C-j (ivy-alt-done). After moving to a new directory, the point should be on the first candidate.

Fixup the face order

All this time there was an issue with the face order swapping between 1 and 2 groups. This is now fixed. Also, I've made swiper-match-face-4 inherit from isearch-fail. It's important to have all 4 faces be different.

Don't error on bad regex

When the current input is a bad regex, just display no candidates and continue. Don't throw an error.

New Features

Use // instead of / to move to root

While completing file names, you can enter // to move to the root directory. This change was necessary in order to make it possible to enter e.g. /sudo: or /ssh:.

Host completion for /sudo: and /ssh:

This feature is a bit flaky for now. But it works well on my machine. It should get better after a few bug reports. You can start the completion right after the method, e.g. /ssh: RET, or after method+user, e.g. /ssh:oleh@ RET.

Respect confirm-nonexistent-file-or-buffer

If you set confirm-nonexistent-file-or-buffer to t (it's nil by default), you'll have to confirm when you create a new file or buffer with ivy.

confirm.png

Highlight remote buffers with ivy-remote face

Just some extra polish to make things look nicer. The buffers to which you're connected through TRAMP will be highlighted with the new ivy-remote face.

Change the prompt for match-required interactions

Sometimes, the Emacs functions that call completion specify to it that a match is required, i.e. you can't just type in some random stuff - you have to select one of the candidates given to you. In that case ivy will appropriately change the prompt like this:

match-required.png

Improve the candidate selection while using history

While completing, you press M-p to select the previous input. This update tries to select not just the first candidates that matches, but the actual previous candidate that you selected before.

Use alpha compositing to add ivy-current-match-face

This is only relevant for when the completion candidates have custom face backgrounds. But in that case, the minibuffer looks a lot nicer.

Add partial completion

Press TAB to do call ivy-partial-or-done to complete the current thing to the largest possible prefix. When called twice in a row, it's the same as C-j, i.e. it will finish the completion.

Improve completion of hidden buffers

In Emacs, hidden buffer names start with a space. To see them all, press a single space while completing buffers in ivy-mode. You can toggle between hidden and non-hidden buffers by editing the first space in your input query. Remember that with ivy-mode the minibuffer is a proper editable area, so C-a works properly (unlike in isearch or ido-mode).

Allow to quote spaces while matching

Spaces are wild while matching - they serve as group boundaries. However, sometimes it would be useful to quote them. From now on, you can quote N consecutive spaces by inputting N+1 consecutive spaces.

Add multi-tier regex matching

This is actually a really cool feature, so if you're paying attention to any section, let it be this one.

User side

For example, I cloned boost-1.58.0 and called counsel-git, which is like a find-file for all files in a git repository at once.

  • Initially, it gives 45919 candidate files.
  • With input "utility", there are 234 candidates.
  • With input "utility hpp", there are 139 candidates.

Now, the interesting part. If I want to exclude anything with "hpp" in it, I change the input to "utility !hpp" (with M-b !) to get 95 candidates (95=234-139, it checks out). I could exclude some more:

  • with input "utility !hpp cpp" there are 57 candidates.
  • with input "utility !hpp cpp ipp" there are 46 candidates.
  • I can unify the regex to "utility ![hic]pp" and also get 46 candidates.
  • exclude htm with "utility ![hic]pp htm" to get only 17 candidates.

You can use this strategy anywhere, not just for git file. For example, in describe-function or swiper.

Elisp side

You can customize ivy-re-builders-alist to make ivy-mode complete in the way that you like. The alist dispatches on the collection type, so you can have one completion strategy for buffers, another for files and still another for everything else.

Each function on the alist should turn the string input into a string regex. So the simplest one would be regexp-quote. If you want to use multi-tier matching, the function should instead return a list of regexps of two types:

  • the ones that should match (will be joined by and).
  • the ones that should not match (will be joined by or).

Add ivy-resume

This feature is still a bit of a work-in-progress. But it allows you to resume the last completion to the point before you entered RET or C-g etc. It only works for features that specifically passed :action to ivy-read. You could resume other features, but nothing would be done when you select the candidate, since ivy-completing-read has no idea what the function that called it was going to do with the result.

Currently, you can resume:

  • counsel-describe-variable
  • counsel-describe-function
  • lispy-goto
  • swiper

Here's how I've bound it in my config:

(global-set-key (kbd "C-c C-r") 'ivy-resume)
(global-set-key [f6] 'ivy-resume)

The ivy-resume feature adds occur-like functionality to swiper. Calling ivy-resume is like switching to the *Occur* buffer.

Outro

Big thanks to all who contributed, especially @tsdh and @zhaojiangbin.

If you're considering to switch from ido-mode to ivy-mode, now is a good time, since the most glaring gaps have now been filled. You can find some up-to-date info on the swiper wiki. I switched the page syntax from markdown to org-mode, but Github makes the headings way to big. So it might be easier to clone the wiki and view the org files in Emacs:

git clone https://github.com/abo-abo/swiper.wiki.git