Embark: Display Buffer in Dedicated Side Window

I wanted to show, just this once for this project, the *compilation* buffer in a bottom split. I also wanted the split to be dedicated, so no other buffers would occupy it by accident, and not be deleted (aka closed) when using delete-other-windows. That should be reserved for code buffers.

The solution that I found is this:

(defun display-in-side-window--bottom (&optional buffer)
  (interactive "b")
  (let ((buffer (or buffer (current-buffer)))
        (display-buffer-overriding-action '((display-buffer-in-side-window)
                                            (dedicated . t)
                                            (side . ,side)
                                            (window-parameters . ((no-delete-other-windows . t))))))
    (display-buffer buffer)))

I tried to use display-buffer-in-side-window as a function and pass a buffer along, but no luck. It just wouldn’t work with a parameter. Mekeor Melire pointed out that the documentation mentions this limitation, which I glossed over:

It should be called only by ‘display-buffer’ or a function directly or indirectly called by the latter.

So overriding the display-buffer-alist temporarily, via display-buffer-overriding-action, was the way to go.

Here is the actual macro version I use with Embark that generates display-in-side-window--bottom, display-in-side-window--left, display-in-side-window--right. I don’t see a value in ‘top’, but you can use that anyway if you want:

(defmacro ct/embark-display-in-side-window (side)
  `(defun ,(intern (concat "display-in-side-window--" (symbol-name side))) (&optional buffer)
     (interactive "b")
     (when-let* ((buffer (or buffer (current-buffer)))
                 (display-buffer-overriding-action '((display-buffer-in-side-window)
                                                     (dedicated . t)
                                                     (side . ,side)
                                                     (window-parameters . ((no-delete-other-windows . t))))))
       (display-buffer buffer))))
(define-key embark-buffer-map (kbd "s b") (ct/embark-display-in-side-window bottom))
(define-key embark-buffer-map (kbd "s l") (ct/embark-display-in-side-window left))
(define-key embark-buffer-map (kbd "s r") (ct/embark-display-in-side-window right))

This way I can C-x b show the buffer switcher and run Embark on it via C-, ' s b to split to bottom.