* lisp/minibuffer.el (minibuffer-completions-sort-function): New var.
(minibuffer-read-sort-order-with-completion)
(minibuffer-completions-sort-orders): New user options.
(minibuffer-sort-completions): New command.
(minibuffer-local-completion-map): Bind it to 'C-x C-v'.
(display-completion-list, minibuffer-completion-help): Take
'minibuffer-completions-sort-function' into account.
(completions-header-format): Add '%t' format spec construct,
substituted with a description of the current sort order.
* lisp/menu-bar.el (minibuffer-local-completion-map): Add menu bar
menu entry for sorting completions candidates.
* doc/emacs/mini.texi (Completion Commands): Document new command.
Improve documentation and indexing of 'minibuffer-complete-and-exit'.
(Completion Exit, Completion Options): Update
* doc/lispref/minibuf.texi (Completion Commands): Document new user
options and command.
* etc/NEWS: Announce new feature.
@item @key{RET}
Submit the text in the minibuffer as the argument, possibly completing
first (@code{minibuffer-complete-and-exit}). @xref{Completion Exit}.
+@item C-x C-v
+Change the order of the list of possible completions
+(@code{minibuffer-sort-completions}).
@item C-x n n
Narrow (restrict) the list of possible completions according to the
current minibuffer input
giving @samp{auto-fill-}. Another @key{SPC} at this point completes
all the way to @samp{auto-fill-mode}.
+@kindex RET @r{(completion)}
+@findex minibuffer-complete-and-exit
+ @key{RET} (@code{minibuffer-complete-and-exit}) submits the text in
+the minibuffer, or completes it and then submits it, depending on the
+``strictness'' of the completion. @xref{Completion Exit}.
+
+@kindex C-x C-v @r{(completion)}
+@findex minibuffer-sort-completions
+ @key{C-x C-v} (@code{minibuffer-sort-completions}) changes the order
+of the completions list. By default, Emacs sorts the list of possible
+completion candidates in the order that you specify in user option
+@code{completions-sort} (@pxref{Completion Options}). This command
+lets you change the order of the current completions list interactively.
+You can invoke it with a negative prefix argument (@kbd{C-- C-x C-v}) to
+reverse the current order.
+
@kindex C-x n n @r{(completion)}
@findex minibuffer-narrow-completions-to-current
@kbd{C-x n n} (@code{minibuffer-narrow-completions-to-current})
@node Completion Exit
@subsection Completion Exit
-@kindex RET @r{(completion in minibuffer)}
-@findex minibuffer-complete-and-exit
+@cindex completion strictness
+@cindex strict completion
When a command reads an argument using the minibuffer with
completion, it also controls what happens when you type @key{RET}
(@code{minibuffer-complete-and-exit}) to submit the argument. There
The variable @code{completions-header-format} is a format spec string
to control the informative line shown before the completions list of
candidates, called the @dfn{completions heading line}. Emacs
-substitutes @samp{%s} and @samp{%r} constructs that occur in this
-string with the number of completion candidates and a description of
-the current completions restriction, respectively. @xref{Narrow
-Completions}. To suppress the display of the heading line, customize
-this variable to @code{nil}. The string that is the value of this
-variable can have text properties to change the visual appearance of
-the heading line; some useful properties are @code{face} or
-@code{cursor-intangible} (@pxref{Special Properties,,Properties with
-Special Meanings, elisp, The Emacs Lisp Reference Manual}).
+substitutes @samp{%s}, @samp{%t} and @samp{%r} constructs that occur
+in this string with the number of completion candidates, the current
+completions sort order, and a description of the current completions
+restriction, respectively. @xref{Narrow Completions}. To suppress
+the display of the heading line, customize this variable to
+@code{nil}. The string that is the value of this variable can have
+text properties to change the visual appearance of the heading line;
+some useful properties are @code{face} or @code{cursor-intangible}
+(@pxref{Special Properties,,Properties with Special Meanings, elisp,
+The Emacs Lisp Reference Manual}).
@vindex completions-highlight-face
When @code{completions-highlight-face} names a face, the current
@file{*Completions*}.
@end deffn
+@deffn Command minibuffer-sort-completions
+This function reorders the list of the possible completions. It
+prompts you for one of the orders in
+@code{minibuffer-completions-sort-orders}, and applies that ordering
+to the current completions list. When you call this function
+interactively with a negative prefix argument (@kbd{C-- C-x C-v} in
+the minibuffer), it reverses the order of the completion candidates.
+@end deffn
+
+@defopt minibuffer-completions-sort-orders
+This user option specifies which orders the command
+@code{minibuffer-sort-completions} suggests for sorting the
+completions list. By default, this includes alphabetical sorting,
+sorting by candidate position in the minibuffer history, and no
+sorting at all. See the documentation string of this user option for
+details about adding new sorting options.
+@end defopt
+
+@deffn Command minibuffer-narrow-completions
+This function narrows (restricts) the list of possible completions.
+It calls the function that the variable
+@code{minibuffer-narrow-completions-function} specifies to get a
+completions predicate, and adds that predicate to
+@code{minibuffer-completion-predicate}.
+@end deffn
+
@defvar minibuffer-narrow-completions-function
The value of this variable is a function that command
-@code{minibuffer-narrow-completions} (@kbd{C-x n m} in the minibuffer)
-calls to restrict the list of completion candidates.
-@code{minibuffer-narrow-completions} calls the function that is the
-value of this variable with no arguments, and this function should
-return a cons cell @code{(@var{pred} . @var{desc})} where @var{pred}
-is a function that takes one argument, a completion candidate, and
-returns non-@code{nil} if that candidate should appear in the
-@file{*Completions*} list, and @var{desc} is a string describing
-@var{pred}.
+@code{minibuffer-narrow-completions} calls to restrict the list of
+completion candidates. @code{minibuffer-narrow-completions} calls the
+function that is the value of this variable with no arguments, and
+this function should return a cons cell @code{(@var{pred}
+. @var{desc})} where @var{pred} is a function that takes one argument,
+a completion candidate, and returns non-@code{nil} if that candidate
+should appear in the @file{*Completions*} list, and @var{desc} is a
+string describing @var{pred}.
@end defvar
@defun minibuffer-narrow-completions-by-regexp
only keeps candidates matching that regular expression.
@end defun
-@deffn Command minibuffer-narrow-completions
-This function narrows (restricts) the list of possible completions.
-It calls the function that the variable
-@code{minibuffer-narrow-completions-function} specifies to get a
-completions predicate, and adds that predicate to
-@code{minibuffer-completion-predicate}.
-@end deffn
-
@deffn Command minibuffer-narrow-completions-to-current
This is similar to @code{minibuffer-narrow-completions}, except that
@code{minibuffer-narrow-completions-to-current} restricts the list of
@item @key{TAB}
@code{minibuffer-complete}
+@item C-x C-v
+@code{minibuffer-sort-completions}
+
@item C-x n
@code{minibuffer-narrow-completions-map}
@end table
include candidates matching the current minibuffer input. See the
Info node "(emacs) Narrow Completions" for more information.
++++
+*** New command for reordering the minibuffer completions list.
+You can now use 'C-x C-v' ('minibuffer-sort-completions') in the
+minibuffer to change the sort order of the completions list. If you
+invoke this command with a negative prefix argument ('C-- C-x C-v'),
+it reverses the current order.
+
*** New minor mode 'completions-auto-update-mode'.
This global minor mode automatically updates the *Completions* buffer
as you type in the minibuffer.
'(menu-item "Restrict to Current Completions"
minibuffer-narrow-completions-to-current
:help "Restrict completions according to minibuffer input"))
+ (bindings--define-key map
+ [menu-bar minibuf minibuffer-sort-completions]
+ '(menu-item "Sort Completions"
+ minibuffer-sort-completions
+ :help "Sort list of completion candidates"))
(bindings--define-key map [menu-bar minibuf ?\?]
'(menu-item "List Completions" minibuffer-completion-help
:help "Display all possible completions"))
:version "28.1")
(defcustom completions-header-format
- (propertize "%s possible completions%r:\n" 'face 'shadow)
+ (propertize "%s possible completions%t%r:\n" 'face 'shadow)
"If non-nil, the format string for completions heading line.
The heading line is inserted before the completions, and is
intended to summarize the completions. The format string may
-contain the sequences \"%s\" and \"%r\", which are substituted
-with the total count of possible completions and the description
-of a description of the current completions restriction,
-respectively. If this option is nil, no heading line is shown."
+contain the sequences \"%s\", \"%t\" and \"%r\", which are
+substituted with the total count of possible completions, the
+current completions sort order, and a description of the current
+completions restriction. If this option is nil, no heading line
+is shown."
:type '(choice (const :tag "No heading line" nil)
(string :tag "Format string for heading line"))
:version "30.1")
minibuffer-completion-predicate)
(when descs (mapconcat #'identity descs ", ")))))
+(defvar minibuffer-completions-sort-function nil
+ "Function for sorting minibuffer completion candidates, or nil.
+
+When the value of this variable is a function,
+`minibuffer-completion-help' uses that function to sort the
+completions list instead of using the `display-sort-function'
+from the completion table or the value of `completions-sort'.
+
+`minibuffer-sort-completions' sets the value of this variable to
+temporarily override the default completions sorting.")
+
+(defcustom minibuffer-completions-sort-orders
+ '((?a "alphabetical" "Sort alphabetically"
+ minibuffer-sort-alphabetically "sorted alphabetically")
+ (?h "historical" "Sort by position in minibuffer history"
+ minibuffer-sort-by-history "sorted by position in minibuffer history")
+ (?i "identity" "Disable sorting" identity nil)
+ (?d "default" "Default sort order" nil nil))
+ "List of minibuffer completions sort orders.
+Each element is a list of the form (CHAR NAME HELP FUNC DESC),
+where CHAR is a character that you type to select this sort order
+in `minibuffer-sort-completions', NAME is the name of the sort
+order, HELP is a short help string that explains what this sort
+order does, FUNC is the completions sorting function, and DESC is
+a desription that is shown in the *Completions* buffer when the
+sort order is in effect.
+
+FUNC can also be nil, which says to use the default sort order
+when you select this sort order."
+ :version "30.1"
+ :type '(repeat
+ (list character string string
+ (choice function
+ (const :tag "No sorting" nil)
+ (const :tag "Use default sort order" identity))
+ (choice string
+ (const :tag "No description" nil)))))
+
(defun display-completion-list (completions &optional common-substring group-fun)
"Display the list of completions, COMPLETIONS, using `standard-output'.
Each element may be just a symbol or string
(let ((pred-desc
(if-let ((pd (minibuffer--completion-predicate-description)))
(concat ", " pd)
+ ""))
+ (sort-desc
+ (if minibuffer-completions-sort-function
+ (concat
+ (when-let
+ ((sd (nth 4 (seq-find
+ (lambda (order)
+ (eq
+ (nth 3 order)
+ (advice--cd*r
+ minibuffer-completions-sort-function)))
+ minibuffer-completions-sort-orders))))
+ (concat ", " sd))
+ (when (advice-function-member-p
+ #'reverse minibuffer-completions-sort-function)
+ ", reversed"))
"")))
(with-current-buffer standard-output
(goto-char (point-max))
(if completions-header-format
(insert (format-spec completions-header-format
(list (cons ?s (length completions))
+ (cons ?t sort-desc)
(cons ?r pred-desc))))
(unless completion-show-help
;; Ensure beginning-of-buffer isn't a completion.
(with-selected-window window
(completions--deselect)))))
+(defcustom minibuffer-read-sort-order-with-completion nil
+ "Whether to use completion for reading minibuffer completions sort order.
+If this user options is nil (the default),
+`minibuffer-sort-completions' lets you to select a sort order by
+typing a single key, which is usually the first letter of the
+name of the sort order. If you set this user option to non-nil,
+`minibuffer-sort-completions' instead reads the sort order name
+in the minibuffer, with completion."
+ :type 'boolean
+ :version "30.1")
+
+(defun minibuffer-sort-completions (arg)
+ "Sort the list of minibuffer completion candidates.
+Prompt for a sort order among
+`minibuffer-completions-sort-orders' and apply it to the current
+completions list. With negative prefix argument ARG, reverse the
+current order instead."
+ (interactive "p" minibuffer-mode)
+ (if (< arg 0)
+ (if (advice-function-member-p
+ #'reverse minibuffer-completions-sort-function)
+ (remove-function
+ (local 'minibuffer-completions-sort-function) #'reverse)
+ (unless minibuffer-completions-sort-function
+ (setq-local minibuffer-completions-sort-function
+ (or (completion-metadata-get
+ (completion--field-metadata
+ (car (minibuffer--completion-boundaries)))
+ 'display-sort-function)
+ (pcase completions-sort
+ ('nil #'identity)
+ ('alphabetical #'minibuffer-sort-alphabetically)
+ ('historical #'minibuffer-sort-by-history)
+ ;; It's already a function, use it.
+ (_ completions-sort)))))
+ (add-function
+ :filter-return
+ (local 'minibuffer-completions-sort-function) #'reverse))
+ (setq-local
+ minibuffer-completions-sort-function
+ (nth 3 (let ((enable-recursive-minibuffers t))
+ (read-multiple-choice
+ "Sort order" minibuffer-completions-sort-orders
+ nil nil minibuffer-read-sort-order-with-completion)))))
+ (when completion-auto-help
+ (let ((beg-end (minibuffer--completion-boundaries)))
+ (minibuffer-completion-help (car beg-end) (cdr beg-end)))))
+
(defun minibuffer-completion-help (&optional start end)
"Display a list of possible completions of the current minibuffer contents."
(interactive)
;; all-completions, not
;; completion-all-completions. Often it's the
;; same, but not always.
- (setq completions (if sort-fun
- (funcall sort-fun completions)
- (pcase completions-sort
- ('nil completions)
- ('alphabetical (minibuffer-sort-alphabetically completions))
- ('historical (minibuffer-sort-by-history completions))
- (_ (funcall completions-sort completions)))))
+ (setq completions
+ (cond
+ (minibuffer-completions-sort-function
+ (funcall minibuffer-completions-sort-function
+ completions))
+ (sort-fun
+ (funcall sort-fun completions))
+ (t
+ (pcase completions-sort
+ ('nil completions)
+ ('alphabetical (minibuffer-sort-alphabetically completions))
+ ('historical (minibuffer-sort-by-history completions))
+ (_ (funcall completions-sort completions))))))
;; After sorting, group the candidates using the
;; `group-function'.
"M-<up>" #'minibuffer-previous-completion
"M-<down>" #'minibuffer-next-completion
"M-RET" #'minibuffer-choose-completion
+ "C-x C-v" #'minibuffer-sort-completions
"C-x n" 'minibuffer-narrow-completions-map)
(defvar-keymap minibuffer-local-must-match-map