New variable 'completion-frontend-properties' (bug#80990)

Allow completion "frontends" to provide extra information
that the backends they call can use to adjust or optimize
their behavior.
See some relevant discussion at
https://yhetil.org/emacs/jwv7bpl28y6.fsf-monnier+emacs@gnu.org/

* lisp/minibuffer.el (completion-frontend-properties):
New variable.
(completion-lazy-hilit-p): New function.
(completion-hilit-commonality, completion-lazy-hilit)
(completion-pcm--hilit-commonality)
(completion-flex-all-completions): Use it instead of
checking the 'completion-lazy-hilit' variable directly.
* lisp/completion-preview.el (completion-preview--capf-wrapper):
Bind 'completion-frontend-properties'.
(completion-preview--try-table): Add comment.
* etc/NEWS: Announce 'completion-frontend-properties'.
This commit is contained in:
Eshel Yaron 2026-05-08 12:45:00 +02:00
parent 876a1db6ee
commit 66729f3e50
No known key found for this signature in database
GPG key ID: EF3EE9CA35D78618
3 changed files with 45 additions and 8 deletions

View file

@ -45,6 +45,13 @@ applies, and please also update docstrings as needed.
* Lisp Changes in Emacs 32.1
---
** New variable 'completion-frontend-properties'.
This variable generalizes the 'completion-lazy-hilit' variable added in
Emacs 30. It allows Lisp programs that present completion candidates
("completion frontends") to provide additional information which can be
used to adjust or optimize completion candidates computation.
* Changes in Emacs 32.1 on Non-Free Operating Systems

View file

@ -499,7 +499,12 @@ candidates or if there are multiple matching completions and
(sort-fn (or (completion-metadata-get md 'cycle-sort-function)
(completion-metadata-get md 'display-sort-function)
completion-preview-sort-function))
(all (let ((completion-lazy-hilit t)
(all (let (;; This is somewhat redundant since we also specify
;; non-nil `lazy-highlight' in
;; `completion-frontend-properties', but we keep it
;; for compatibility with backends that do not know
;; about `completion-frontend-properties' yet.
(completion-lazy-hilit t)
;; FIXME: This does not override styles prescribed
;; by the completion category via
;; e.g. `completion-category-defaults'.
@ -525,7 +530,9 @@ candidates or if there are multiple matching completions and
(defun completion-preview--capf-wrapper (capf)
"Translate return value of CAPF to properties for completion preview overlay."
(let ((res (ignore-errors (funcall capf))))
(let* ((completion-frontend-properties '((no-annotations . t)
(lazy-highlight . t)))
(res (ignore-errors (funcall capf))))
(and (consp res)
(not (functionp res))
(seq-let (beg end table &rest plist) res

View file

@ -2586,7 +2586,7 @@ and with BASE-SIZE appended as the last element."
com-str-len (1+ com-str-len)
'face 'completions-first-difference str))
str)))
(if completion-lazy-hilit
(if (completion-lazy-hilit-p)
(setq completion-lazy-hilit-fn hilit-fn)
(setq completions
(mapcar
@ -2604,6 +2604,11 @@ and with BASE-SIZE appended as the last element."
completions)))
(nconc completions base-size))))
(defun completion-lazy-hilit-p ()
"Return non-nil if the completion frontend supports lazy highlighting."
(or completion-lazy-hilit
(alist-get 'lazy-highlight completion-frontend-properties)))
(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
@ -3198,6 +3203,23 @@ Also respects the obsolete wrapper hook `completion-in-region-functions'.
(delq (assq 'completion-in-region-mode minor-mode-map-alist)
minor-mode-map-alist))
(defvar completion-frontend-properties nil
"Alist of properties describing the current completion frontend.
Frontends may let-bind this variable while calling a completion backend
to provide information which the backend can use to optimize or adjust
its behavior. More specifically, frontends should bind this variable
when calling `completion-try-completion' or `completion-all-completions'.
Currently known frontend properties are:
- \\+`no-annotations': if non-nil, the frontend ignores any
`annotation-function'/`affixation-function'.
- \\+`lazy-highlight': If non-nil, the front-end does not require
`completion-all-completions' completions to be highlighted and knows
to call the function `completion-lazy-hilit' as needed instead.")
(defvar completion-at-point-functions '(tags-completion-at-point-function)
"Special hook to find the completion table for the entity at point.
Each function on this hook is called in turn without any argument and
@ -4501,9 +4523,10 @@ strings with the `face' property.")
(defun completion-lazy-hilit (str)
"Return a copy of completion candidate STR that is `face'-propertized.
See documentation of the variable `completion-lazy-hilit' for more
details."
(if (and completion-lazy-hilit completion-lazy-hilit-fn)
Apply `completion-lazy-hilit-fn' if it is set and the frontend supports
lazy highlighting (see `completion-lazy-hilit-p'), otherwise return STR
as is."
(if (and (completion-lazy-hilit-p) completion-lazy-hilit-fn)
(funcall completion-lazy-hilit-fn (copy-sequence str))
str))
@ -4556,7 +4579,7 @@ see) for later lazy highlighting."
(re (completion-pcm--segments->regex segments 'group))
(point-idx (completion-pcm--segments-point-idx segments)))
(setq completion-pcm--regexp re)
(cond (completion-lazy-hilit
(cond ((completion-lazy-hilit-p)
(setq completion-lazy-hilit-fn
(lambda (str) (completion--hilit-from-re str re point-idx)))
completions)
@ -5036,7 +5059,7 @@ usual. Returns (ALL PAT PREFIX SUFFIX)."
(1+ special-match) (+ 2 special-match)
'completions-first-difference nil str))))
str))
(unless completion-lazy-hilit
(unless (completion-lazy-hilit-p)
(setq all (mapcar completion-lazy-hilit-fn all)))
;; Store pattern for adjust-metadata to use
(setq completion-flex--pattern-str pattern-str)