Я обнаружил, что можно настроить поведение функции display-buffer , установив переменную display-buffer-function .
Эта функция, кажется, делает то, что я хочу (конечно, она нуждается в некоторой очистке, но она работает):
(defun my-display-buffer (BUFFER-OR-NAME &optional NOT-THIS-WINDOW)
  (catch 'return
    ;; search the buffer in the existing windows
    (let ((windows (window-list)))
      (while (first windows)
        ;; found
        (if (eq (window-buffer (first windows)) BUFFER-OR-NAME)
            (throw 'return
                   ;; if minibuffer doesn't select the window
                   (if (eq (selected-window) (minibuffer-window))
                       (first windows)
                     (select-window (first windows)))))
        ;; next window
        (setq windows (rest windows))))
    ;; otherwise use current
    (if (eq (selected-window) (minibuffer-window))
        ;; if minubuffer
        (progn
          (select-window (minibuffer-selected-window))
          (switch-to-buffer BUFFER-OR-NAME)
          (select-window (minibuffer-window)))
      ;; if regular window
      (progn
        (switch-to-buffer BUFFER-OR-NAME)
        (selected-window)))))