From aff1d53cd466b64ded08d5cf12f83e5746704c07 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Tue, 9 Jan 2024 19:57:50 +0200 Subject: [PATCH] Support more metadata properties in completion-extra-properties (bug#68214) * doc/lispref/minibuf.texi (Completion Variables): Add to the table of completion-extra-properties new items: `group-function', `display-sort-function', `cycle-sort-function'. * lisp/icomplete.el (icomplete--augment): Remove unnecessary plist-get from completion-extra-properties since now completion-metadata-get does this. * lisp/minibuffer.el (completion-metadata-get): Use plist-get to get prop from completion-extra-properties and cache the keyword. Thanks to Daniel Mendler . (completion-extra-properties): Mention new properties in docstring. (minibuffer-completion-help): Remove unnecessary plist-get from completion-extra-properties since now completion-metadata-get does this. * lisp/net/eww.el (eww-switch-to-buffer): * test/lisp/minibuffer-tests.el (completions-affixation-navigation-test): Unquote lambda in completion-extra-properties. --- doc/lispref/minibuf.texi | 9 +++++++++ etc/NEWS | 5 +++++ lisp/icomplete.el | 6 ++---- lisp/minibuffer.el | 33 ++++++++++++++++++++++++--------- lisp/net/eww.el | 7 ++++--- test/lisp/minibuffer-tests.el | 10 +++++----- 6 files changed, 49 insertions(+), 21 deletions(-) diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 8d25a53161e..18df44256a8 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -1928,6 +1928,15 @@ element of the returned list must be a three-element list, the completion, a prefix string, and a suffix string. This function takes priority over @code{:annotation-function}. +@item :group-function +The function to group completions. + +@item :display-sort-function +The function to sort entries in the @file{*Completions*} buffer. + +@item :cycle-sort-function +The function to sort entries when cycling. + @item :exit-function The value should be a function to run after performing completion. The function should accept two arguments, @var{string} and diff --git a/etc/NEWS b/etc/NEWS index f4d008ee2d6..fcec2ca715a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -752,6 +752,11 @@ The new supported completion properties are 'cycle-sort-function', 'completion-category-overrides' that will override the properties defined in completion metadata. ++++ +*** 'completion-extra-properties' supports more metadata. +The new supported completion properties are 'group-function', +'display-sort-function', 'cycle-sort-function'. + ** Pcomplete --- diff --git a/lisp/icomplete.el b/lisp/icomplete.el index d49714f3204..aa3c5680a7e 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -789,10 +789,8 @@ and SUFFIX, if non-nil, are obtained from `affixation-function' or `group-function'. Consecutive `equal' sections are avoided. COMP is the element in PROSPECTS or a transformation also given by `group-function''s second \"transformation\" protocol." - (let* ((aff-fun (or (completion-metadata-get md 'affixation-function) - (plist-get completion-extra-properties :affixation-function))) - (ann-fun (or (completion-metadata-get md 'annotation-function) - (plist-get completion-extra-properties :annotation-function))) + (let* ((aff-fun (completion-metadata-get md 'affixation-function)) + (ann-fun (completion-metadata-get md 'annotation-function)) (grp-fun (and completions-group (completion-metadata-get md 'group-function))) (annotated diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 04b36f03d11..42d04e0ff96 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -151,15 +151,25 @@ The metadata of a completion table should be constant between two boundaries." minibuffer-completion-predicate)) (defun completion-metadata-get (metadata prop) - "Get PROP from completion METADATA. + "Get property PROP from completion METADATA. If the metadata specifies a completion category, the variables `completion-category-overrides' and -`completion-category-defaults' take precedence." +`completion-category-defaults' take precedence for +category-specific overrides. If the completion metadata does not +specify the property, the `completion-extra-properties' plist is +consulted. Note that the keys of the +`completion-extra-properties' plist are keyword symbols, not +plain symbols." (if-let (((not (eq prop 'category))) (cat (alist-get 'category metadata)) (over (completion--category-override cat prop))) (cdr over) - (alist-get prop metadata))) + (or (alist-get prop metadata) + (plist-get completion-extra-properties + ;; Cache the keyword + (or (get prop 'completion-extra-properties--keyword) + (put prop 'completion-extra-properties--keyword + (intern (concat ":" (symbol-name prop))))))))) (defun complete-with-action (action collection string predicate) "Perform completion according to ACTION. @@ -2447,6 +2457,15 @@ These include: `:annotation-function' when both are provided, so only this function is used. +`:group-function': Function for grouping the completion candidates. + +`:display-sort-function': Function to sort entries in *Completions*. + +`:cycle-sort-function': Function to sort entries when cycling. + +See more information about these functions above +in `completion-metadata'. + `:exit-function': Function to run after completion is performed. The function must accept two arguments, STRING and STATUS. @@ -2569,12 +2588,8 @@ The candidate will still be chosen by `choose-completion' unless base-size md minibuffer-completion-table minibuffer-completion-predicate)) - (ann-fun (or (completion-metadata-get all-md 'annotation-function) - (plist-get completion-extra-properties - :annotation-function))) - (aff-fun (or (completion-metadata-get all-md 'affixation-function) - (plist-get completion-extra-properties - :affixation-function))) + (ann-fun (completion-metadata-get all-md 'annotation-function)) + (aff-fun (completion-metadata-get all-md 'affixation-function)) (sort-fun (completion-metadata-get all-md 'display-sort-function)) (group-fun (completion-metadata-get all-md 'group-function)) (mainbuf (current-buffer)) diff --git a/lisp/net/eww.el b/lisp/net/eww.el index 22f07cbc5b4..6c46ef0fedb 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -2064,9 +2064,10 @@ If CHARSET is nil then use UTF-8." "Prompt for an EWW buffer to display in the selected window." (interactive nil eww-mode) (let ((completion-extra-properties - '(:annotation-function (lambda (buf) - (with-current-buffer buf - (format " %s" (eww-current-url)))))) + `(:annotation-function + ,(lambda (buf) + (with-current-buffer buf + (format " %s" (eww-current-url)))))) (curbuf (current-buffer))) (pop-to-buffer-same-window (read-buffer "Switch to EWW buffer: " diff --git a/test/lisp/minibuffer-tests.el b/test/lisp/minibuffer-tests.el index 6dc15d0801f..c1fe3032cb5 100644 --- a/test/lisp/minibuffer-tests.el +++ b/test/lisp/minibuffer-tests.el @@ -505,11 +505,11 @@ (ert-deftest completions-affixation-navigation-test () (let ((completion-extra-properties - '(:affixation-function - (lambda (completions) - (mapcar (lambda (c) - (list c "prefix " " suffix")) - completions))))) + `(:affixation-function + ,(lambda (completions) + (mapcar (lambda (c) + (list c "prefix " " suffix")) + completions))))) (completing-read-with-minibuffer-setup '("aa" "ab" "ac") (insert "a") -- 2.39.2