diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index d30114f768b..da27805f86d 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -316,8 +316,22 @@ input before returning it. However, @code{read-no-blanks-input} (see below), as well as @code{read-minibuffer} and related functions (@pxref{Object from Minibuffer,, Reading Lisp Objects With the Minibuffer}), and all -functions that do minibuffer input with completion, discard text -properties unconditionally, regardless of the value of this variable. +functions that do minibuffer input with completion, remove the @code{face} +property unconditionally, regardless of the value of this variable. + +If this variable is non-@code{nil}, most text properties on strings +from the completion table are preserved---but only on the part of the +strings that were completed. + +@lisp +(let ((minibuffer-allow-text-properties t)) + (completing-read "String: " (list (propertize "foobar" 'data 'zot)))) +=> #("foobar" 3 6 (data zot)) +@end lisp + +In this example, the user typed @samp{foo} and then hit the @kbd{TAB} +key, so the text properties are only preserved on the last three +characters. @end defvar @defvar minibuffer-local-map diff --git a/etc/NEWS b/etc/NEWS index 52092f2ef72..4076630bf22 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1190,6 +1190,12 @@ directory instead of the default directory. * Incompatible Lisp Changes in Emacs 28.1 ++++ +** Some properties from completion tables are now preserved. +If 'minibuffer-allow-text-properties' is non-nil, doing completion +over a table of strings with properties will no longer remove all the +properties before returning. This affects things like 'completing-read'. + ** 'equal' no longer examines some contents of window configurations. Instead, it considers window configurations to be equal only if they are 'eq'. To compare contents, use 'compare-window-configurations' diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 62a33f3e2dd..3e23c05bb0c 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1065,10 +1065,16 @@ in the last `cdr'." (defun completion--replace (beg end newtext) "Replace the buffer text between BEG and END with NEWTEXT. Moves point to the end of the new text." - ;; The properties on `newtext' include things like - ;; completions-first-difference, which we don't want to include - ;; upon insertion. - (set-text-properties 0 (length newtext) nil newtext) + ;; The properties on `newtext' include things like the + ;; `completions-first-difference' face, which we don't want to + ;; include upon insertion. + (if minibuffer-allow-text-properties + ;; If we're preserving properties, then just remove the faces + ;; and other properties added by the completion machinery. + (remove-text-properties 0 (length newtext) '(face completion-score) + newtext) + ;; Remove all text properties. + (set-text-properties 0 (length newtext) nil newtext)) ;; Maybe this should be in subr.el. ;; You'd think this is trivial to do, but details matter if you want ;; to keep markers "at the right place" and be robust in the face of