I want C-x b (i.e. switch-to-buffer) to ignore some buffers. For example, I want to ignore *Ibuffer*. In other words, when I press C-x b, I should not see Switch to buffer (default *Ibuffer*): . *Ibuffer* should be skipped. Is there a way to make C-x b ignore particular buffers?


1 Answer 1


Command switch-to-buffer is designed to do just what it does. You can advise it to do something different, but typically if you want different behavior for a given key sequence then you are better off using a different command.

(This is all the more true in the case of switch-to-buffer, which is used not only as a command, i.e., interactively, but from Lisp code in many places, including in the core Emacs code.)

What you're interested in is the interactive part: the part that reads a buffer name from you. That's realized for switch-to-buffer by function read-buffer-to-switch. But that function is hard-coded to exclude only the current buffer. That function in turn is defined using function read-buffer, which, fortunately, offers more possibilities.

You can define a command that uses read-buffer in a way that provides only the buffer-name choices you want, and then bind that command to C-x b.

C-h f read-buffer tells you that there's a PREDICATE argument that filters the list of available buffers to present only some of them. Use that.

This code reuses the interactive spec from switch-to-buffer, except that it uses read-buffer with a predicate that excludes buffer *Ibuffer*:

(defun my-switch-to-buffer (buffer-or-name &optional norecord force-same-window)
  "Switch to another buffer, besides `*Ibuffer*'."
   (let ((force-same-window
           ((window-minibuffer-p) nil)
           ((not (eq (window-dedicated-p) t)) 'force-same-window)
           ((pcase switch-to-buffer-in-dedicated-window
              (`nil (user-error
                     "Cannot switch buffers in a dedicated window"))
               (if (y-or-n-p
                    (format "Window is dedicated to %s; undedicate it"
                     (set-window-dedicated-p nil nil)
                  "Cannot switch buffers in a dedicated window")))
              (`pop nil)
              (_ (set-window-dedicated-p nil nil) 'force-same-window))))))
     (list (read-buffer "Buffer: "
                        (other-buffer (current-buffer))
                        (lambda (name.buf)
                          (not (string= "*Ibuffer*" (car name.buf))))))))
  (switch-to-buffer buffer buffer-or-name norecord force-same-window))

(global-set-key (kbd "C-x b") 'my-switch-to-buffer)

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.