As you may already know, I take buffer switching seriously. Jokes aside, one of the key bindings I use the most is C-x p b , which is bound to project-switch-to-buffer by default. As the above linked article explains, it takes little time to find myself with many open buffers, some of which may not be immediately relevant to the context of my actual work.

Instead of tweaking switch-to-buffer, though, I decided to make it possible for project-switch-to-buffer to act according to certain conditions. With the help of Dmitry Gutov, I have recently added project-ignore-buffer-conditions on Emacs master. Now, for instance, I can do the following:

(defvar-local mu-ignored-buffers
    '("\\` " "^\\*Async" "^\\*Completions" "^\\*Flymake" "^\\*Help"
      "^\\*Messages" "^\\*eldoc" "^\\*envrc" "\\*tramp" "^\\*xref")
  "A list of predicates for buffers to ignore.")
  
(defun mu-project-ignore-buffer-p (buffer)
  "Check if BUFFER is a member of `mu-ignored-buffers'."
  (seq-contains-p mu-ignored-buffers (buffer-name buffer) #'string-match-p)) 
  
(setq-default project-ignore-buffer-conditions '(mu-project-ignore-buffer-p
                                                 (derived-mode . comint-mode))

Note that I changed project--read-project-buffer to take the new defcustom into account, so project-display-buffer and project-display-buffer-other-frame are also affected.

Futhermore, to understand what kind of conditions you can use, check project-kill-buffer-conditions which is what I based project-ignore-buffer-conditions on following Dmitry’s tip.