feature/popup: add +popup-display-buffer action #337

This is experimental and disabled by default. It uses a slightly more
primitive backend that will stack popups away from the edge of the
frame. This will need more work to take window-slot into account.

To use it:

  (remove-hook '+popup-display-buffer-actions 'display-buffer-in-side-window)
  (add-hook '+popup-display-buffer-actions #'+popup-display-buffer t)
This commit is contained in:
Henrik Lissner
2018-01-09 16:43:07 -05:00
parent 7bdf8cf8d9
commit c03d0dbc06

View File

@ -408,3 +408,44 @@ prevent the popup(s) from messing up the UI (or vice versa)."
"Sets aside all popups before executing the original function, usually to
prevent the popup(s) from messing up the UI (or vice versa)."
(save-popups! (apply orig-fn args)))
;;
;; Popup actions
;;
(defun +popup--dimension (side)
(if (memq side '(left right))
'window-width
'window-height))
(defun +popup--side (side)
(pcase side (`bottom 'below) (`top 'above) (_ side)))
(defun +popup--frame-splittable-p (frame)
(when (and (window--frame-usable-p frame)
(not (frame-parameter frame 'unsplittable)))
frame))
(defun +popup--splittable-frame ()
(let ((selected-frame (selected-frame))
(last-non-minibuffer-frame (last-nonminibuffer-frame)))
(or (+popup--frame-splittable-p selected-frame)
(+popup--frame-splittable-p last-non-minibuffer-frame))))
;;;###autoload
(defun +popup-display-buffer (buf alist)
"Highly experimental!"
(when-let* ((frame (+popup--splittable-frame)))
(let* ((-side (or (alist-get 'side alist) 'bottom))
(side (+popup--side -side))
(size (alist-get (+popup--dimension -side) alist))
(old-size (window-size (frame-root-window frame)
(memq -side '(left right))))
(new-size
(when (numberp size)
(round (if (>= size 1)
(- old-size size)
(* (- 1 size) old-size)))))
(window (split-window (frame-root-window frame) new-size side)))
(window--display-buffer buf window 'window alist t))))