From: João Távora Date: Sun, 22 Aug 2021 14:56:36 +0000 (+0100) Subject: Don't mess up grouping in completion-all-sorted-completions X-Git-Tag: emacs-28.0.90~1358 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=ba852512f23fdab674086e35d4207e3970dd0912;p=emacs.git Don't mess up grouping in completion-all-sorted-completions The default sorting order will mess up the naturally grouped order of the candidates in the table that specified the group-function. As seen in xref.el when (setq xref-show-definitions-function 'xref-show-definitions-completing-read) (setq completions-group t) M-x fido-mode Also partially seen with C-x 8 RET (M-x insert-char) with (setq read-char-by-name-sort 'code) bug#48545 * lisp/minibuffer.el (completion-all-sorted-completions): Don't use default sort if there's a group-function in the table. --- diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index ffcd5d88abe..89d3a2a09d4 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1496,7 +1496,8 @@ Remove completion BASE prefix string from history elements." base-size md minibuffer-completion-table minibuffer-completion-predicate)) - (sort-fun (completion-metadata-get all-md 'cycle-sort-function))) + (sort-fun (completion-metadata-get all-md 'cycle-sort-function)) + (group-fun (completion-metadata-get all-md 'group-function))) (when last (setcdr last nil) @@ -1506,17 +1507,25 @@ Remove completion BASE prefix string from history elements." (setq all (delete-dups all)) (setq last (last all)) - (if sort-fun - (setq all (funcall sort-fun all)) - ;; Sort first by length and alphabetically. + (cond + (sort-fun (setq all (funcall sort-fun all))) + ((and completions-group group-fun) + ;; TODO: experiment with re-grouping here. Might be slow + ;; if the group-fun (given by the table and out of our + ;; control) is slow and/or allocates too much. + ) + (t + ;; If the table doesn't stipulate a sorting function or a + ;; group function, sort first by length and + ;; alphabetically. (setq all (minibuffer--sort-by-length-alpha all)) - ;; Sort by history position, put the default, if it + ;; Then sort by history position, and put the default, if it ;; exists, on top. (when (minibufferp) (setq all (minibuffer--sort-by-position (minibuffer--sort-preprocess-history (substring string 0 base-size)) - all)))) + all))))) ;; Cache the result. This is not just for speed, but also so that ;; repeated calls to minibuffer-force-complete can cycle through