,#+ARROYOEMACSMODULE: ivy-posframe
provide 'cce/ivy-posframe) (
Ivy/PosFrame is
an Emacs Glue Library which
allows me to take the Ivy
minibuffer and display it in a temporary Emacs frame, which in Modern Interface Terms means that
it appears in a dedicated window above my Emacs window, rather than
taking a section of it. In EXWM this has the added benefit of not
forcing windows to constantly re-size themselves whenever I hit M-x
or go to swap buffers.
Configuration is more or less taken from the repository's README.md
file, except that I tell it to display
most things at frame center, where my eyes are likely going to find it
most easily. Swiper, however, gets to stay pinned to its parent frame,
since it needs to stay out of the way when I am looking at text. Of note
here as well, I set parent-frame
to nil in
the temporary frame created by posframe
,
which allows them to float above EXWM-managed windows, based on advice
provided in this
GitHub issue.
use-package ivy-posframe
(
:diminish
:configsetq ivy-posframe-parameters '((left-fringe 10)
(10)
(right-fringe
(z-group . above)nil))
(parent-frame
ivy-posframe-display-functions-alist '((swiper . ivy-display-function-fallback)
(complete-symbol . ivy-posframe-display-at-point)t . ivy-posframe-display-exwm)))
( (ivy-posframe-mode))
EXWM and Ivy/PosFrame don't interact well, as hinted above, and in the case of having multiple monitors, Ivy/PosFrame simply doesn't know where to put the window, causing it to appear off-screen at a logical 0,0 coordinate. Ivy/PosFrame lets users define our own display-function, and someone in the thread above implemented one which uses EXWM's workspace metadata to construction a frame location. I haven't tried it, and need to integrate it properly the next time I am on my desktop. I implemented something similar but this is more clear.
defun ivy-posframe-display-exwm (str)
(if (memq #'exwm-init after-make-frame-functions)
(
(ivy-posframe--display strlambda (info)
(let* ((workarea (elt exwm-workspace--workareas exwm-workspace-current-index))
(aref workarea 0))
(x (aref workarea 1))
(y (
aref workarea 2))
(fw (aref workarea 3))
(fh (
(pw (plist-get info :posframe-width))
(ph (plist-get info :posframe-height)))
cons (+ x (/ (- fw pw) 2)) (+ y (/ (- fh ph) 2))))))
( (ivy-posframe-display-at-frame-center str)))