Allow preserving (some) text properties from completion tables

* doc/lispref/minibuf.texi (Text from Minibuffer): Document it.

* lisp/minibuffer.el (completion--replace): Preserve text
properties on completed items (bug#43218).
This commit is contained in:
Lars Ingebrigtsen 2020-09-14 14:22:06 +02:00
parent cbfa411544
commit 14486c4488
3 changed files with 32 additions and 6 deletions

View file

@ -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

View file

@ -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'

View file

@ -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