From d1a6051613a042b0704cd5f9e0b370c446840610 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Fri, 5 Jan 2024 19:03:13 +0100 Subject: [PATCH] Add completion annotations for file name completion * lisp/minibuffer.el (completion-file-name-affixation): New function. (completion-file-name-table): Use it as 'affixation-function'. * doc/emacs/help.texi (Name Help): Move doc of 'completions-detailed' from here to... * doc/emacs/mini.texi (Completion Options): ...here. Improve wording. * etc/NEWS: Announce. --- doc/emacs/help.texi | 8 -------- doc/emacs/mini.texi | 11 +++++++++++ etc/NEWS | 6 ++++++ lisp/minibuffer.el | 38 +++++++++++++++++++++++++++++++++++++- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi index 5bed5d6f037..39888cac6d4 100644 --- a/doc/emacs/help.texi +++ b/doc/emacs/help.texi @@ -363,14 +363,6 @@ completions to only include symbols with a given property by typing @xref{Narrow Completions}, and @ref{Symbol Properties,,,elisp,The Emacs Lisp Reference Manual}. -@vindex completions-detailed - If the @code{completions-detailed} user option is non-@code{nil}, -some commands provide details about the possible values when -displaying completions. For instance, @kbd{C-h o TAB} will then -include the first line of the doc string, and will also say whether -each symbol is a function or a variable (and so on). Which details -are included varies depending on the command used. - @node Apropos @section Apropos @cindex apropos diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index b1a6e8b6dce..40d9ae7d4dc 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -996,6 +996,17 @@ face. The default value of this variable is highlighting. This feature uses the special text property @code{cursor-face}. +@vindex completions-detailed +If the @code{completions-detailed} user option is non-@code{nil}, some +commands that provide completion display extra details as annotations +next to completion candidates in the @file{*Completions*} buffer. +Which details are included varies between different commands. For +instance, the completions list for @kbd{C-h o} (@pxref{Name Help}) +includes the first line of the doc string of each symbol, and says +whether each symbol is a function or a variable (and so on). For file +name completion, the extra details annotations include file modes, +sizes, modification times and ownership information. + @node Minibuffer History @section Minibuffer History @cindex minibuffer history diff --git a/etc/NEWS b/etc/NEWS index 18a57f13150..f0d11bb9c20 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -825,6 +825,12 @@ which you can use to customize completion behavior via and you can now customize the face 'completions-heading' to control its appearance. ++++ +*** File name completions can now provide detailed candidate annotations. +With non-nil user option 'completions-detailed', Emacs now displays +extra details about file name completion candidates in the +"*Completions*" buffer as completion annotations. + ** Pcomplete --- diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index c51065bb68c..b9fe3df7f84 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -3629,11 +3629,47 @@ same as `substitute-in-file-name'." (completion-table-with-context prefix table (substring string beg) nil action))))))) +(defun completion-file-name-affixation (files) + "Return completion affixations for file list FILES." + (let ((max-file (seq-max (mapcar #'string-width files)))) + (mapcar + (lambda (file) + (list + file + "" ; empty prefix + (if-let ((attrs + (ignore-errors + (file-attributes + (substitute-in-file-name + (concat minibuffer-completion-base file)) + 'string)))) + (propertize + (concat (propertize " " 'display + `(space :align-to ,(+ max-file 2))) + (file-attribute-modes attrs) + " " + (format "%8s" (file-size-human-readable + (file-attribute-size attrs))) + " " + (format-time-string + "%Y-%m-%d %T" (file-attribute-modification-time attrs)) + " " + (file-attribute-user-id attrs) + ":" + (file-attribute-group-id attrs)) + 'face 'completions-annotations) + ""))) + files))) + (defun completion-file-name-table (string pred action) "Completion table for file names." (condition-case nil (cond - ((eq action 'metadata) '(metadata (category . file))) + ((eq action 'metadata) + `(metadata + (category . file) + ,@(when completions-detailed + '((affixation-function . completion-file-name-affixation))))) ((string-match-p "\\`~[^/\\]*\\'" string) (completion-table-with-context "~" (mapcar (lambda (u) (concat u "/")) -- 2.39.2