Commit aa5f098a authored by Kyle Meyer's avatar Kyle Meyer

completion: override default alphabetical sorting

The "*Completions*" buffer for completing-read and for crm-driven
read-from-minibuffer defaults to alphabetically sorting the
collection.  As a result, any meaningful order given to the collection
(e.g., by the recently added magit-list-refs-sortby) won't be visible
to the user.

This is probably most problematic when reading a refname in a repo
with many numeric tags because these tags are displayed before
branches staring with letters even though tags (and especially the
older tags at the beginning of the list) are not likely to be the
desired target.  If the order of the collection is respected, this
problem is avoided because, by default, magit-list-refs returns refs
sorted by their full name, so branches ("refs/heads") come before
tags ("refs/tags"), as well as remotes ("refs/remotes") and GitHub
pull requests ("refs/pull").

Preserve the order of the collection by using identity for the
display-sort-function metadata.  Unfortunately, the items are actually
displayed in reverse in some cases because a completion function,
completion-pcm--all-completions, reverses the collection's
order (Emacs bug#24676).  The next commit will add a kludge for this.

Many third-party completion packages preserve the order of the
collection without any intervention.  I tested completing-read and crm
completion with magit-completing-read-function set to
magit-ido-completing-read, helm--completing-read-default, and
ivy-completing-read.  These all appeared to work fine.

With the global modes for helm and ivy enabled, the order in the crm
completion list is not preserved.  In the case of ivy, this is due to
bug#24676.  For helm, this is because helm--completion-in-region uses
its own function to sort the output of completion-all-completions.

Closes #2925.
parent 388a9a25
......@@ -13,6 +13,12 @@ Changes since v2.10.3
* Added option `magit-list-refs-sortby' to allow more control over the
order of refs in prompts. #2872
* The Magit wrappers around the default Emacs completion functions now
override the default behavior of alphabetically sorting choices when
displaying them in the "*Completions*" buffer. In repositories with
many release tags, the new behavior prevents completion prompts from
being dominated by version tags instead of branch names. #2925
Fixes since v2.10.3
-------------------
......
......@@ -328,11 +328,18 @@ results in additional differences."
nil)
reply)))
(defun magit--completion-table (collection)
(lambda (string pred action)
(if (eq action 'metadata)
'(metadata (display-sort-function . identity))
(complete-with-action action collection string pred))))
(defun magit-builtin-completing-read
(prompt choices &optional predicate require-match initial-input hist def)
"Magit wrapper for standard `completing-read' function."
(completing-read (magit-prompt-with-default prompt def)
choices predicate require-match
(magit--completion-table choices)
predicate require-match
initial-input hist def))
(defun magit-completing-read-multiple
......@@ -350,7 +357,7 @@ When KEYMAP is nil, it defaults to `crm-local-completion-map'.
Unlike `completing-read-multiple', the return value is not split
into a list."
(let* ((crm-separator (or sep crm-default-separator))
(crm-completion-table choices)
(crm-completion-table (magit--completion-table choices))
(choose-completion-string-functions
'(crm--choose-completion-string))
(minibuffer-completion-table #'crm--collection-fn)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment