I'm trying to write a command that I would call while using ido-switch-buffer or ido-kill-buffer to open the current candidate in another window. Ideally it would be able to open virtual buffers as well.

One thing it seems I've got right is that I need to bind it in ido-buffer-completion-map:

(define-key ido-buffer-completion-map "\C-n" #'ido-visit-buffer-other-window)

But I can't make a function that works. I've given up at

(defun ido-visit-buffer-other-window (candidate)
  "Visit the buffer at the head of ‘ido-matches’ in its window or
in a new one if no one is displaying it."
  (interactive (list (car ido-matches)))
  (let ((buffer (or (get-buffer candidate)
                    ;; Check for a virtual buffer reference.
                    (find-file-noselect (cdr (assoc candidate ido-virtual-buffers))))))
    (switch-to-buffer-other-window buffer)))

Whatever I do the Ido prompt remains lingering in the minibuffer. Every way of getting out of the minibuffer that I've tried breaks the function:

  • (exit-minibuffer) or (ido-exit-minibuffer) switch to the candidate buffer (in the current window) if I had called ido-switch-buffer or they kill it if I had called ido-kill-buffer;
  • with (minibuffer-keyboard-quit) and (abort-recursive-edit) (thanks Drew for the tip!) the command does nothing.
  • Can you be more specific? What does "breaks the function" mean here? Have you tried (abort-recursive-edit) instead of (exit-minibuffer)? How does Ido normally end its minibuffer interaction - is it with exit-minibuffer?
    – Drew
    Commented Jan 8, 2022 at 2:28
  • Hi @Drew :-) see the updated question. Commented Jan 8, 2022 at 9:09

1 Answer 1


You are unfortunately going to have to use two functions: one that does the work and one that exits Ido.

(defun ido-visit-buffer-other-window ()
  (let ((buf (car ido-matches))
     ((get-buffer buf)
      (add-to-history 'buffer-name-history buf)
      (ido-visit-buffer buf 'other-window t))
     ((and ido-enable-virtual-buffers
           (setq entry (assoc buf ido-virtual-buffers)))
      (ido-visit-buffer (find-file-noselect (cdr entry)) 'other-window t))
      (user-error "No match")))))

(defun ido-run-visit-buffer-other-window ()
  (setq ido-exit 'fallback)
  (setq ido-fallback 'ido-visit-buffer-other-window)

Now you can bind ido-run-visit-buffer-other-window in ido-buffer-completion-map to whatever key sequence you like.

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.