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.
+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. The user option
+@code{minibuffer-completions-sort-orders} determines which orders this
+command 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. Some commands that use
+minibuffer completion also provide additional sorting options that are
+specifically useful with their completion candidates. For example,
+during file name completion, as in @kbd{C-x C-f} (@pxref{Visiting}),
+you can use @key{C-x C-v} to sort candidate file names chronologically
+by their last modified time.
@kindex C-x n n @r{(completion)}
@findex minibuffer-narrow-completions-to-current
;; instead, but for now, let's keep this non-obsolete.
;;(make-obsolete-variable 'minibuffer-completing-file-name nil "future" 'get)
+(defun minibuffer--sort-file-names-by-last-modified-time (files)
+ "Sort file name completion candidates FILES by last modified time."
+ (let ((file-time-alist
+ (mapcar (lambda (file)
+ (cons file
+ (file-attribute-modification-time
+ (ignore-errors
+ (file-attributes
+ (substitute-in-file-name
+ (concat minibuffer-completion-base file)))))))
+ files)))
+ (sort files (lambda (a b)
+ (let ((atime (alist-get a file-time-alist
+ nil nil #'string=))
+ (btime (alist-get b file-time-alist
+ nil nil #'string=)))
+ (if atime
+ (or (not btime)
+ ;; Put more recently modified files first.
+ (time-less-p btime atime)
+ (and (time-equal-p atime btime)
+ (string-lessp a b)))
+ (and (not btime) (string-lessp a b))))))))
+
(defun read-file-name-default (prompt &optional dir default-filename mustmatch initial predicate)
"Default method for reading file names.
See `read-file-name' for the meaning of the arguments."
(with-current-buffer
(window-buffer (minibuffer-selected-window))
(read-file-name--defaults dir initial))))
+ (setq-local
+ minibuffer-completions-sort-orders
+ (cons '(?m "modified" "Sort by last modified time"
+ minibuffer--sort-file-names-by-last-modified-time
+ "latest modified first")
+ minibuffer-completions-sort-orders))
(set-syntax-table minibuffer-local-filename-syntax))
(completing-read prompt 'read-file-name-internal
pred mustmatch insdef