]> git.eshelyaron.com Git - emacs.git/commitdiff
Don't mess up grouping in completion-all-sorted-completions
authorJoão Távora <joaotavora@gmail.com>
Sun, 22 Aug 2021 14:56:36 +0000 (15:56 +0100)
committerJoão Távora <joaotavora@gmail.com>
Sun, 22 Aug 2021 15:11:40 +0000 (16:11 +0100)
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.

lisp/minibuffer.el

index ffcd5d88abe39c350fb68a8e4a7c09a920226d5f..89d3a2a09d45586e34c7a6a942f83570ded0ba48 100644 (file)
@@ -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