3

I have installed Ivy (along with Swiper and Counsel) as part of Prelude by doing a (require 'prelude-ivy) in my prelude-modules.el file.

It seems to work, but I am not able to figure out how to do some basic things. In particular, I would like to open multiple files "at once".

Suppose I do a C-xC-f and enter the path to a folder with a bunch of files (let's use ~/.emacs.d/core/ as an example). I can easily open any one of the files by doing a C-n down the list and hitting enter. Emacs will then open whichever file is selected, or open Dired if I select a directory such as ./ or ../.

C-xC-f

I can also start typing a substring of a filename and the matches to that substring are filtered as expected:

fragment

But how, exactly, do I select all or some of the files in the minibuffer for opening? Suppose I want to open BOTH prelude-core.el and prelude-custom.el. How do I do that?

There's some information in the Ivy User Manual about "key bindings for multiple selections" but I can't get it to work, or I don't understand the instructions. Can someone walk me through the explicit key bindings to:

  1. Select/open all of the filtered files in the minibuffer.
  2. Select/open some of the filtered files in the minibuffer.
  3. If possible, do the same things in a Dired window (not sure if Ivy applies there?).
Angelo
  • 271
  • 2
  • 9

1 Answers1

3

Can some one walk me through the explicit key chords to:

  1. Select/open all of the filtered files in the minibuffer.

Ivy does not provide a built-in way to act on all completion candidates at once.

The closest you can come in general is by enabling "calling" via C-oc (requires the ivy-hydra package; see (ivy) Hydra in the minibuffer). When "calling" is enabled, merely navigating to a candidate (e.g. via C-n/C-p) automatically selects that candidate as well. The effect is a bit like scrolling through the list of candidates with an automatically updated preview.

Otherwise, you will have to write your own command. Here is an example of how you could open all current file/directory candidates:

(defun my-ivy-find-files ()
  "Visit all current completion candidates as files.
Switch to the buffer visiting the first candidate."
  (interactive)
  (let ((files (all-completions "" (ivy-state-collection ivy-last))))
    (mapc #'find-file-noselect (cdr files))
    (find-file (car files)))
  (minibuffer-keyboard-quit))

You can, of course, modify the logic (e.g. filter by regular file/directory) and key binding:

(with-eval-after-load 'ivy
  (define-key ivy-minibuffer-map (kbd "C-c f") #'my-ivy-find-files))
  1. Select/open some of the filtered files in the minibuffer.

(ivy) Key bindings for single selection action then exit minibuffer describes how to act on only a single candidate:

  • C-m/RET Exits with the currently selected file/directory.
  • C-j Same as C-m, but will descend into directories instead of opening them in Dired.

(ivy) Key bindings for multiple selections and actions keep minibuffer open describes how to act on multiple candidates without exiting the completion session:

  • C-M-m Opens the currently selected file/directory but keeps the completion session active.
  • C-M-n Same as C-nC-M-m.
  • C-M-p Same as C-pC-M-m.

So, if, for example, you wanted to open the 1st, 3rd and 4th candidates, you could type:

C-M-mM-2C-M-nC-M-nRET

  1. If possible, do the same things in a Dired window (not sure if Ivy applies there?).

Ivy applies wherever completion does. For example, when ivy-mode is enabled, typing j (dired-goto-file) in a Dired buffer will complete the file/directory to jump to with Ivy completion.

Otherwise, Dired and Dired-X provide various ways to operate on subsets of the current directory listing.

The simplest way to open multiple files at once is probably by using the command dired-do-find-marked-files from Dired-X, which is bound to F by default; see (dired-x) Advanced Mark Commands for information on this command and (dired-x) Installation for how to enable the built-in Dired-X extensions to Dired.

When Dired-X is loaded, you just need to mark the files you're interested in before typing F. See (dired) Flagging Many Files, (dired) Marks vs Flags and (dired-x) Special Marking Function for information on the various available types of marking commands.

See also https://stackoverflow.com/q/1110118/3084001.

Basil
  • 12,019
  • 43
  • 69
  • I see that ivy-hydra isn't installed by default with prelude-ivy. But after installing the ivy-hydra package, I get an error with C-o: "symbol's value as variable is void: ivy-preferred-re-builders" That's fodder for another question! – Angelo Feb 13 '18 at 21:37
  • @Angelo Yes, `ivy-hydra` is an optional extension. I'll update the answer accordingly. Re: the void variable - try updating your packages. `ivy--preferred-re-builders` was recently renamed to `ivy-preferred-re-builders`, so you may be stuck in a weird combination of an older `ivy.el` and newer `ivy-hydra.el`. – Basil Feb 13 '18 at 21:47
  • thanks for your lucid answer, I appreciate it. I will keep trying! – Angelo Feb 13 '18 at 21:52
  • you're right, I was able to get hydra working by a package-delete of Ivy (all it's dependencies first, followed by ivy itself). I then performed a manual update of prelude's packages and finally did a package-install of ivy-hydra. I now get a display of hydra stuff when I do C-o. Unfortunately, hydra seems very disorienting. Will need to train my motor skills to avoid hitting the wrong key and painting myself into a corner. Probably easier to go through the custom elisp route for now ! – Angelo Feb 14 '18 at 13:21
  • @Angelo Glad it's working. I, too, am not entirely sold on the hydra interface, but popping it open once in a blue moon to toggle calling or case folding works for me. Happy hacking! – Basil Feb 14 '18 at 13:39