summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThanos Apollo <public@thanosapollo.org>2026-04-28 20:14:49 +0300
committerThanos Apollo <public@thanosapollo.org>2026-04-28 20:14:49 +0300
commitb8012d73ea566edd514a179e61ee98cf55db8ae7 (patch)
tree04be378d9173ae63d4530ba865a61fd7a1edcadd
parent5e5edc3b7f07fb368fd883a4a800e56f56b9503a (diff)
feat: user-pluggable display backend via function defcustom
-rw-r--r--README.org2
-rw-r--r--keymap-popup.el93
2 files changed, 53 insertions, 42 deletions
diff --git a/README.org b/README.org
index f474a6e..f5cc096 100644
--- a/README.org
+++ b/README.org
@@ -118,7 +118,7 @@ descriptions, and prefix argument support.
"s" ("Sub-menu" :keymap kp-test--sub-map)
"q" ("Quit" quit-window)
"H" ("Popup (child-frame)" (lambda () (interactive)
- (let ((keymap-popup-backend 'child-frame))
+ (let ((keymap-popup-backend #'keymap-popup-backend-child-frame))
(keymap-popup kp-test--map))))
:row
:group "Inapt (entry-level)"
diff --git a/keymap-popup.el b/keymap-popup.el
index ac18fdb..5932206 100644
--- a/keymap-popup.el
+++ b/keymap-popup.el
@@ -40,18 +40,49 @@
(defcustom keymap-popup-display-action
'(display-buffer-in-side-window (side . bottom))
"Display action for the popup buffer.
-Only used when `keymap-popup-backend' is `side-window'.
+Only used by `keymap-popup-backend-side-window'.
Common values:
(display-buffer-in-side-window (side . bottom)) - frame-wide
(display-buffer-below-selected) - current window only"
:type 'sexp
:group 'keymap-popup)
-(defcustom keymap-popup-backend 'side-window
- "Display backend for the popup.
-`side-window' uses a bottom side window (works in terminal and GUI).
-`child-frame' uses a floating child frame (GUI only)."
- :type '(choice (const side-window) (const child-frame))
+(defcustom keymap-popup-backend #'keymap-popup-backend-side-window
+ "Function returning a display backend plist (:show :fit :hide).
+Each backend function receives a single buffer argument.
+:show displays the buffer, :fit refits after content changes,
+:hide removes the display and cleans up."
+ :type '(choice (const :tag "Side window" keymap-popup-backend-side-window)
+ (const :tag "Child frame" keymap-popup-backend-child-frame)
+ function)
+ :group 'keymap-popup)
+
+(defcustom keymap-popup-child-frame-parameters
+ '((no-accept-focus . t)
+ (no-focus-on-map . t)
+ (min-width . t)
+ (min-height . t)
+ (border-width . 0)
+ (child-frame-border-width . 1)
+ (left-fringe . 0)
+ (right-fringe . 0)
+ (vertical-scroll-bars . nil)
+ (horizontal-scroll-bars . nil)
+ (menu-bar-lines . 0)
+ (tool-bar-lines . 0)
+ (tab-bar-lines . 0)
+ (no-other-frame . t)
+ (no-other-window . t)
+ (no-delete-other-windows . t)
+ (unsplittable . t)
+ (undecorated . t)
+ (cursor-type . nil)
+ (no-special-glyphs . t)
+ (desktop-dont-save . t))
+ "Frame parameters for the child-frame backend.
+These are merged with runtime parameters (parent-frame, minibuffer,
+visibility) when creating the child frame."
+ :type '(alist :key-type symbol :value-type sexp)
:group 'keymap-popup)
;;; Faces
@@ -700,34 +731,14 @@ Drops entries whose command has no binding."
(defun keymap-popup--show-child-frame (buf)
"Display BUF in a child frame centered on the parent.
-Frame parameters follow show-paren.el's child frame pattern."
+Frame parameters are taken from `keymap-popup-child-frame-parameters'."
(let* ((parent (selected-frame))
(after-make-frame-functions nil)
(frame (make-frame
`((parent-frame . ,parent)
(minibuffer . ,(minibuffer-window))
- (no-accept-focus . t)
- (no-focus-on-map . t)
- (min-width . t)
- (min-height . t)
- (border-width . 0)
- (child-frame-border-width . 1)
- (left-fringe . 0)
- (right-fringe . 0)
- (vertical-scroll-bars . nil)
- (horizontal-scroll-bars . nil)
- (menu-bar-lines . 0)
- (tool-bar-lines . 0)
- (tab-bar-lines . 0)
- (no-other-frame . t)
- (no-other-window . t)
- (no-delete-other-windows . t)
- (unsplittable . t)
- (undecorated . t)
- (cursor-type . nil)
- (no-special-glyphs . t)
- (desktop-dont-save . t)
- (visibility . nil))))
+ (visibility . nil)
+ ,@keymap-popup-child-frame-parameters)))
(win (frame-root-window frame)))
(set-window-buffer win buf)
(set-window-dedicated-p win t)
@@ -752,17 +763,17 @@ Frame parameters follow show-paren.el's child frame pattern."
(when (frame-parent frame)
(delete-frame frame))))
-(defun keymap-popup--backend ()
- "Return the display backend plist (:show :fit :hide)."
- (pcase keymap-popup-backend
- ('child-frame
- (list :show #'keymap-popup--show-child-frame
- :fit #'keymap-popup--fit-child-frame
- :hide #'keymap-popup--hide-child-frame))
- (_
- (list :show #'keymap-popup--show-side-window
- :fit #'keymap-popup--fit-side-window
- :hide #'keymap-popup--hide-side-window))))
+(defun keymap-popup-backend-side-window ()
+ "Return a side-window display backend."
+ (list :show #'keymap-popup--show-side-window
+ :fit #'keymap-popup--fit-side-window
+ :hide #'keymap-popup--hide-side-window))
+
+(defun keymap-popup-backend-child-frame ()
+ "Return a child-frame display backend."
+ (list :show #'keymap-popup--show-child-frame
+ :fit #'keymap-popup--fit-child-frame
+ :hide #'keymap-popup--hide-child-frame))
(defun keymap-popup--prepare-buffer ()
"Create and configure the popup buffer."
@@ -995,7 +1006,7 @@ Sub-menu keys push a navigation stack. C-u toggles prefix mode."
(user-error "No descriptions in keymap"))
(let* ((source (current-buffer))
(buf (keymap-popup--prepare-buffer))
- (backend (keymap-popup--backend))
+ (backend (funcall keymap-popup-backend))
(raw (keymap-popup--collect-descriptions keymap))
(descriptions (if (keymap-popup--meta keymap 'keymap-popup--annotated)
(keymap-popup--resolve-descriptions raw keymap)