From 4601a270af996193c6ff06a3d32a035657bf5141 Mon Sep 17 00:00:00 2001 From: Daniel Mendler Date: Tue, 11 May 2021 09:08:05 +0200 Subject: [PATCH 5/5] (minibuffer-completion-help): Add group sorting Sort the groups as returned by the `group-function` of the completion table depending on the value of the customizable variable `completions-group-sort`. By default `completions-group-sort` is set to nil. The variable can be set to the symbol `alphabetical` in order to configure alphabetical sorting. Furthermore, a custom sorting function can be used as value of `completions-group-sort`. * lisp/minibuffer.el (completions-group-sort): New variable. (minibuffer--group-by): Add SORT-FUN argument. (minibuffer-completion-help): Pass `completions-group-sort` to `minibuffer--group-by`. --- lisp/minibuffer.el | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 2a2552a6f0..6bd3baf074 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1147,10 +1147,22 @@ completion-cycle-threshold (defcustom completions-group nil "Enable grouping of completion candidates in the *Completions* buffer. -See also `completions-group-format'." +See also `completions-group-format' and `completions-group-sort'." :type 'boolean :version "28.1") +(defcustom completions-group-sort nil + "Sort groups in the *Completions* buffer. + +The value can either be nil to disable sorting, `alphabetical' for +alphabetical sorting or a custom sorting function. The sorting +function takes and returns an alist of groups, where each element is a +pair of a group title string and a list of group candidate strings." + :type '(choice (const nil :tag "No sorting") + (const alphabetical :tag "Alphabetical sorting") + function) + :version "28.1") + (defcustom completions-group-format (concat (propertize " " 'face 'completions-group-separator) @@ -1434,16 +1446,21 @@ minibuffer--sort-preprocess-history (substring c base-size))) hist))))) -(defun minibuffer--group-by (fun elems) - "Group ELEMS by FUN." +(defun minibuffer--group-by (group-fun sort-fun elems) + "Group ELEMS by GROUP-FUN and sort groups by SORT-FUN." (let ((groups)) (dolist (cand elems) - (let* ((key (funcall fun cand nil)) + (let* ((key (funcall group-fun cand nil)) (group (assoc key groups))) (if group (setcdr group (cons cand (cdr group))) (push (list key cand) groups)))) - (mapcan (lambda (x) (nreverse (cdr x))) (nreverse groups)))) + (setq groups (nreverse groups) + groups (mapc (lambda (x) + (setcdr x (nreverse (cdr x)))) + groups) + groups (funcall sort-fun groups)) + (mapcan #'cdr groups))) (defun completion-all-sorted-completions (&optional start end) (or completion-all-sorted-completions @@ -2216,7 +2233,17 @@ minibuffer-completion-help ;; `group-function'. (when group-fun (setq completions - (minibuffer--group-by group-fun completions))) + (minibuffer--group-by + group-fun + (pcase completions-group-sort + ('nil #'identity) + ('alphabetical + (lambda (groups) + (sort groups + (lambda (x y) + (string< (car x) (car y)))))) + (_ completions-group-sort)) + completions))) (cond (aff-fun -- 2.20.1