branch: externals/ivy
commit 4b1df7c492fd9be39df7f97dd6e22b8a0e99fb8a
Author: Basil L. Contovounesios <[email protected]>
Commit: Basil L. Contovounesios <[email protected]>
Don't completely replace prompt text properties
ivy--insert-prompt seems to emulate some of read-from-minibuffer's
text property logic, but hasn't been doing so correctly w.r.t
minibuffer-prompt-properties and in particular the face property.
This change allows users to affect the entire prompt via m-p-p, or
just the prompt text itself by passing, e.g., a propertized string
to ivy-read. It should support multiple faces too.
* ivy.el (ivy--insert-prompt): Break text property logic out...
(ivy--propertize-prompt): ...to this new function. Use
add-text-properties and add-face-text-property in place of
set-text-properties (#3077). Heed minibuffer-prompt-properties.
---
ivy.el | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/ivy.el b/ivy.el
index 8d94c2ce5d..62e81b75c4 100644
--- a/ivy.el
+++ b/ivy.el
@@ -3214,6 +3214,25 @@ parts beyond their respective faces `ivy-confirm-face'
and
(when line (push line lines)))
(string-join (nreverse lines) "\n"))))
+(defun ivy--propertize-prompt (prompt)
+ "Propertize PROMPT like `read-from-minibuffer' would.
+Also handle `ivy-set-prompt-text-properties-function'."
+ (let ((len (length prompt))
+ ;; Added unconditionally by `read-from-minibuffer'.
+ (props (list 'front-sticky t 'rear-nonsticky t 'field t))
+ ;; Configurable.
+ (extras minibuffer-prompt-properties))
+ ;; Filter out `face'; it is documented as being appended instead, and was
+ ;; historically excluded from `ivy-set-prompt-text-properties-function'.
+ (while extras
+ (let ((key (pop extras))
+ (val (pop extras)))
+ (if (eq key 'face)
+ (add-face-text-property 0 len val t prompt)
+ (setq props (plist-put props key val)))))
+ (add-text-properties 0 len props prompt)
+ (funcall ivy-set-prompt-text-properties-function prompt props)))
+
(defun ivy--insert-prompt ()
"Update the prompt according to `ivy--prompt'."
(when (setq ivy--prompt (ivy-prompt))
@@ -3228,7 +3247,6 @@ parts beyond their respective faces `ivy-confirm-face' and
(setq head ivy--prompt)
(setq tail ""))
(let ((inhibit-read-only t)
- (std-props '(front-sticky t rear-nonsticky t field t read-only t))
(n-str
(concat
(and (bound-and-true-p minibuffer-depth-indicate-mode)
@@ -3263,12 +3281,7 @@ parts beyond their respective faces `ivy-confirm-face'
and
(when ivy-add-newline-after-prompt
(setq n-str (concat n-str "\n")))
(setq n-str (ivy--break-lines n-str (window-width)))
- (set-text-properties 0 (length n-str)
- `(face minibuffer-prompt ,@std-props)
- n-str)
- (setq n-str (funcall ivy-set-prompt-text-properties-function
- n-str std-props))
- (insert n-str))
+ (insert (ivy--propertize-prompt n-str)))
;; Mark prompt as selected if the user moves there or it is the only
;; option left. Since the user input stays put, we have to manually
;; remove the face as well.