Skip to content

Commit 076388f

Browse files
Stebalienprogfolio
andauthored
elpaca-menu-item: improve candidate completion (#436)
elpaca--completion-group-by-menu: group completion candidates by menu elpaca-description-column: set minimum column for completion descriptions elpaca--completion-affixation-fn: align completion descriptions Co-authored-by: Nicholas Vollmer <[email protected]>
1 parent 7a68b7d commit 076388f

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

elpaca.el

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,28 @@ Values for each key are that of the right-most plist containing that key."
276276
"Return E's Q."
277277
(and e (car (last elpaca--queues (1+ (elpaca<-queue-id e))))))
278278

279+
(defun elpaca--completion-group-by-menu (candidate transform)
280+
"Return CANDIDATE menu if TRANSFORM non-nil, otherwise CANDIDATE item."
281+
(if-let* ((space (string-match-p " " candidate)))
282+
(substring candidate (if transform 0 (1+ space)) (when transform space))
283+
candidate))
284+
285+
(defcustom elpaca-description-column 20 "Minimum column for completion descriptions."
286+
:type 'number)
287+
288+
(defun elpaca--completion-affixation-fn (candidates)
289+
"Return `elpaca-menu-item' CANDIDATES affixation function."
290+
(let ((col elpaca-description-column))
291+
(lambda (completions)
292+
(setq col (max col (or (cl-loop for c in completions maximize (string-match-p " " c)) 0)))
293+
(mapcar
294+
(lambda (c) (list c ""
295+
(concat (propertize " " 'display `(space :align-to ,col))
296+
(when-let* ((item (cdr (assoc-string c candidates)))
297+
(desc (plist-get (cdr item) :description)))
298+
(propertize (concat " " desc) 'face 'completions-annotations)))))
299+
completions))))
300+
279301
;;;###autoload
280302
(defun elpaca-menu-item (&optional id interactive)
281303
"Return menu item matching ID in `elpaca-menu-functions'.
@@ -289,12 +311,13 @@ If ID is nil, prompt for item. If INTERACTIVE is non-nil, copy to `kill-ring'."
289311
(cons (concat (symbol-name (car i)) " " (plist-get (cdr i) :source)) i))
290312
into candidates
291313
finally return
292-
(let* ((completion-extra-properties
293-
(list :annotation-function
294-
(lambda (s)
295-
(concat " " (plist-get (cdr (alist-get s candidates nil nil #'equal))
296-
:description)))))
297-
(choice (completing-read (or elpaca-overriding-prompt "Menu Item: ") candidates nil t)))
314+
(let ((choice (completing-read
315+
(or elpaca-overriding-prompt "Menu Item: ")
316+
(completion-table-with-metadata
317+
candidates
318+
`((group-function . elpaca--completion-group-by-menu)
319+
(affixation-function . ,(elpaca--completion-affixation-fn candidates))))
320+
nil t)))
298321
(alist-get choice candidates nil nil #'equal))))))
299322
(when interactive
300323
(message "menu-item copied to kill-ring:\n%S" item)

0 commit comments

Comments
 (0)