7

I find ivy's virtual buffers feature ((setq ivy-use-virtual-buffers t)) very handy for navigating to files whose buffers have been closed. Like ido's virtual buffers,it uses recentf to present those files as if their buffers were still open when switching buffers.

However, occasionally I want to remove clutter from ivy-switch-buffer by removing 'virtual buffers'. ido has C-k, which does what I want. I've found that ivy's kill action does not always work for this purpose.

How can I reliably remove virtual buffers from the ivy-switch-buffer list, preferably using ivy itself?

3
  • Are you looking to toggle virtual buffers on and off? Or for a way to exclude specific files from appearing as virtual buffers even if they were recently visited?
    – glucas
    Commented Nov 13, 2017 at 18:12
  • @glucas A way to do whatever C-k does in ido I guess :-) I'm not 100% sure exactly what that is because I'm not 100% sure I know all of the state it uses: certainly recentf is part of that state, so I'm guessing that it just removes that file from the recentf history. Commented Dec 5, 2017 at 17:03
  • Ah, ok. That maps to ido-kill-buffer-at-head which will kill the buffer or, in the case of virtual buffers, delete it from recentf-list.
    – glucas
    Commented Dec 5, 2017 at 18:02

3 Answers 3

5

Ivy already has an action bound to "k" for ivy-switch-buffer, but it just calls kill-buffer so it does not work on virtual buffers.

Based on what ido is doing, here's some code to replace the default ivy kill action with one that also handles virtual buffers by dropping them from the recentf list:

(defun my-ivy-kill-buffer (buf)
  (interactive)
  (if (get-buffer buf)
      (kill-buffer buf)
    (setq recentf-list (delete (cdr (assoc buf ivy--virtual-buffers)) recentf-list))))

(ivy-set-actions
 'ivy-switch-buffer
 '(("k"
    (lambda (x)
      (my-ivy-kill-buffer x)
      (ivy--reset-state ivy-last))
    "kill"
    )))

With this configuration you can use the various ivy action dispatch mechanisms depending on what you want to do:

  • Choose a candidate and hit M-o k to kill it and exit.
  • Choose a candidate and hit C-M-o k to kill it and then select another candidate.

This seems pretty useful, I may submit it as a pull request to ivy.

5
  • Added a setq to that delete, which makes this work for me. I'm not sure why I found that necessary given the docs for delete, because recentf-list is a list. Commented Dec 8, 2017 at 0:04
  • Odd, the original code works fine for me without the setq. Glad you got it working though!
    – glucas
    Commented Dec 9, 2017 at 19:19
  • @glucas is there a way to do this but not have it close the mini buffer so instead of using kill-buffer using the function ivy-switch-buffer-kill so the ivy session can stay active.
    – J Spen
    Commented Jan 11, 2019 at 8:35
  • Nevermind figured out that is what C-M-o k is for. But can you override the default binding C-c C-k to do this without going into the candidate menu to select items. Then it removes the list for me so the workflow is a little odd.
    – J Spen
    Commented Jan 11, 2019 at 8:38
  • Ivy has been updated to handle this now, github.com/abo-abo/swiper/issues/1888.
    – glucas
    Commented Jan 24, 2019 at 15:14
1

I have this in my init file:

;; Bind C-k to kill buffer from `ivy-switch-buffer'
(defun mu-ivy-kill-buffer ()
  (interactive)
  (ivy-set-action 'kill-buffer)
  (ivy-done))

(define-key ivy-switch-buffer-map (kbd "C-k") 'mu-ivy-kill-buffer)

Note that the latest release of ivy on MELPA, added a new binding C-c C-k which removes to buffer from ivy-switch-buffer.

2
  • That looks like it just kills the buffer rather than removing it from the virtual buffers (i.e., I guess removing it from recentf)? Commented Dec 5, 2017 at 17:04
  • Yes, unfortunately it still needs some working because the buffer gets killer but the candidate list is closed as well. Commented Dec 6, 2017 at 6:36
0

You can configure recentf-exclude to a regexp or predicate to filter out files from the recentf-list. For example, I have set it to (setq recentf-exclude '("\.gpg$")) so that GPG files once open aren't accidentally opened through virutal buffers selection prompt.

After setting recent-exclude, a call to the command recentf-cleanup applies the changes to the variable and removes entries from recentf-list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.