minibuffer-allow-text-properties can be buffer-local and affects completions
authorJuri Linkov <juri@linkov.net>
Mon, 27 May 2024 18:18:17 +0000 (21:18 +0300)
committerJuri Linkov <juri@linkov.net>
Mon, 27 May 2024 18:19:53 +0000 (21:19 +0300)
* doc/lispref/minibuf.texi (Text from Minibuffer): Mention that
minibuffer-allow-text-properties can be let-bound or buffer-local
in the minibuffer.  Correct the description of
minibuffer-allow-text-properties to explain what it did
even before applying code changes in this patch.
Remove wrong example for read-no-blanks-input.

* lisp/imenu.el (imenu--completion-buffer): Set buffer-local
minibuffer-allow-text-properties to t.
(imenu--completion-buffer): Get text property 'imenu-choice'.
(imenu--flatten-index-alist): Propertize annotation
with text property 'imenu-choice'.

* lisp/simple.el (choose-completion): Don't remove text properties
from the returned completion string since the value of
minibuffer-allow-text-properties is already respected
in completion--replace.

* src/minibuf.c (read_minibuf): Preserve text properties not only
when allow_props is non-nil but also in case when
minibuffer_allow_text_properties is non-nil.
(Fread_from_minibuffer): Mention in the docstring that
minibuffer-allow-text-properties can be buffer-local in the minibuffer.
(minibuffer-allow-text-properties): Improve docstring to describe
when text properties are discarded.

https://lists.gnu.org/archive/html/emacs-devel/2024-05/msg00949.html

doc/lispref/minibuf.texi
etc/NEWS
lisp/imenu.el
lisp/simple.el
src/minibuf.c

index 8f2d0d702f91988f74846be790791c972ccadd77..73ff170401e6c6679c3f5d6d9844892a6d68a4d4 100644 (file)
@@ -185,7 +185,8 @@ a starting position in the history list as well.  @xref{Minibuffer
 History}.
 
 If the variable @code{minibuffer-allow-text-properties} is
-non-@code{nil}, then the string that is returned includes whatever text
+non-@code{nil}, either let-bound or buffer-local in the minibuffer,
+then the string that is returned includes whatever text
 properties were present in the minibuffer.  Otherwise all the text
 properties are stripped when the value is returned.  (By default this
 variable is @code{nil}.)
@@ -352,28 +353,32 @@ See @code{read-regexp} above for details of how these values are used.
 
 @defvar minibuffer-allow-text-properties
 If this variable is @code{nil}, the default, then
-@code{read-from-minibuffer} and @code{read-string} strip all text
-properties from the minibuffer 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, remove the
-@code{face} property unconditionally, regardless of the value of this
+@code{read-from-minibuffer} and all functions that do minibuffer input
+strip all text properties from the minibuffer input before returning it.
+
+However, @code{read-minibuffer} and related functions (@pxref{Object
+from Minibuffer,, Reading Lisp Objects With the Minibuffer}), remove the
+text properties 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.
+If this variable is non-@code{nil}, either let-bound or buffer-local in
+the minibuffer, then @code{read-from-minibuffer}, @code{read-string},
+and all related functions preserve text properties.  But functions that
+do minibuffer input with completion remove the @code{face} property
+while preserving other text properties.
 
 @lisp
-(let ((minibuffer-allow-text-properties t))
-  (completing-read "String: " (list (propertize "foobar" 'data 'zot))))
-=> #("foobar" 3 6 (data zot))
+(minibuffer-with-setup-hook
+    (lambda ()
+      (setq-local minibuffer-allow-text-properties t))
+  (completing-read
+   "String: " (list (propertize "foobar" 'face 'baz 'data 'zot))))
+=> #("foobar" 0 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.
+key, and all text properties are preserved except the @code{face}
+property.
 @end defvar
 
 @vindex minibuffer-mode-map
@@ -433,18 +438,6 @@ function, and passes the value of the @code{minibuffer-local-ns-map}
 keymap as the @var{keymap} argument for that function.  Since the keymap
 @code{minibuffer-local-ns-map} does not rebind @kbd{C-q}, it @emph{is}
 possible to put a space into the string, by quoting it.
-
-This function discards text properties, regardless of the value of
-@code{minibuffer-allow-text-properties}.
-
-@smallexample
-@group
-(read-no-blanks-input @var{prompt} @var{initial})
-@equiv{}
-(let (minibuffer-allow-text-properties)
-  (read-from-minibuffer @var{prompt} @var{initial} minibuffer-local-ns-map))
-@end group
-@end smallexample
 @end defun
 
 @c Slightly unfortunate name, suggesting it might be related to the
index ea8729f39391ad50faab560d1e5276d84b20fae5..abd347dfcb226fb6924756c339d76e82a54b6835 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2044,6 +2044,17 @@ UTF-8 byte sequence, and the optional parameter MULTIBYTE of
 'dbus-string-to-byte-array' should be a regular Lisp string, not a
 unibyte string.
 
++++
+** 'minibuffer-allow-text-properties' now can be set buffer-local.
+'read-from-minibuffer' and functions that use it can take the
+buffer-local value from the minibuffer.
+
++++
+** 'minibuffer-allow-text-properties' also affects completions.
+When it has a non-nil value, then completion functions like
+'completing-read' don't discard text properties from the returned
+completion candidate.
+
 \f
 * Lisp Changes in Emacs 30.1
 
index ea097f5da3a59dd1fa63c8a98dec4f76abbccc56..93d84106ec1df66bbe2cce55882e7dd1a0101cfb 100644 (file)
@@ -752,6 +752,7 @@ Return one of the entries in index-alist or nil."
     ;; Display the completion buffer.
     (minibuffer-with-setup-hook
         (lambda ()
+          (setq-local minibuffer-allow-text-properties t)
           (setq-local completion-extra-properties
                       `( :category imenu
                          ,@(when (eq imenu-flatten 'annotation)
@@ -765,10 +766,12 @@ Return one of the entries in index-alist or nil."
                                  nil t nil 'imenu--history-list name)))
 
     (when (stringp name)
-      (setq choice (assoc name prepared-index-alist))
-      (if (imenu--subalist-p choice)
-         (imenu--completion-buffer (cdr choice) prompt)
-       choice))))
+      (or (get-text-property 0 'imenu-choice name)
+         (progn
+           (setq choice (assoc name prepared-index-alist))
+           (if (imenu--subalist-p choice)
+               (imenu--completion-buffer (cdr choice) prompt)
+             choice))))))
 
 (defun imenu--mouse-menu (index-alist event &optional title)
   "Let the user select from a buffer index from a mouse menu.
@@ -798,7 +801,9 @@ Returns t for rescan and otherwise an element or subelement of INDEX-ALIST."
            (new-prefix (and concat-names
                             (if prefix
                                 (concat prefix imenu-level-separator name)
-                              name))))
+                              (if (eq imenu-flatten 'annotation)
+                                   (propertize name 'imenu-choice item)
+                                 name)))))
        (cond
        ((not (imenu--subalist-p item))
         (list (cons (if (and (eq imenu-flatten 'annotation) prefix)
index 88a4a388518f22072baea51f573c9af4c17ac106..44197c3189abe44bb13613540ac7f1485a0711d1 100644 (file)
@@ -10144,9 +10144,9 @@ minibuffer, but don't quit the completions window."
           (completion-no-auto-exit (if no-exit t completion-no-auto-exit))
           (choice
            (if choose-completion-deselect-if-after
-               (if-let ((str (get-text-property (posn-point (event-start event)) 'completion--string)))
-                   (substring-no-properties str)
-                 (error "No completion here"))
+               (or (get-text-property (posn-point (event-start event))
+                                      'completion--string)
+                   (error "No completion here"))
            (save-excursion
              (goto-char (posn-point (event-start event)))
              (let (beg)
@@ -10161,8 +10161,7 @@ minibuffer, but don't quit the completions window."
                (setq beg (or (previous-single-property-change
                               beg 'completion--string)
                              beg))
-               (substring-no-properties
-                (get-text-property beg 'completion--string)))))))
+               (get-text-property beg 'completion--string))))))
 
       (unless (buffer-live-p buffer)
         (error "Destination buffer is dead"))
index 9c1c86680d48a1dd3716175ae4fbc5d188b579e1..1dfee0a59c90133e96bb7b3d46a7146e3fbbcff9 100644 (file)
@@ -563,7 +563,8 @@ If the current buffer is not a minibuffer, return its entire contents.  */)
 
    DEFALT specifies the default value for the sake of history commands.
 
-   If ALLOW_PROPS, do not throw away text properties.
+   If ALLOW_PROPS or `minibuffer-allow-text-properties' (possibly
+   buffer-local) is non-nil, do not throw away text properties.
 
    if INHERIT_INPUT_METHOD, the minibuffer inherits the
    current input method.  */
@@ -928,7 +929,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
 
   /* Make minibuffer contents into a string.  */
   Fset_buffer (minibuffer);
-  if (allow_props)
+  if (allow_props || minibuffer_allow_text_properties)
     val = Fminibuffer_contents ();
   else
     val = Fminibuffer_contents_no_properties ();
@@ -1321,7 +1322,8 @@ Sixth arg DEFAULT-VALUE, if non-nil, should be a string, which is used
 Seventh arg INHERIT-INPUT-METHOD, if non-nil, means the minibuffer inherits
  the current input method and the setting of `enable-multibyte-characters'.
 
-If the variable `minibuffer-allow-text-properties' is non-nil,
+If the variable `minibuffer-allow-text-properties' is non-nil
+ (either let-bound or buffer-local in the minibuffer),
  then the string which is returned includes whatever text properties
  were present in the minibuffer.  Otherwise the value has no text properties.
 
@@ -2464,9 +2466,10 @@ basic completion functions like `try-completion' and `all-completions'.  */);
   DEFVAR_BOOL ("minibuffer-allow-text-properties",
               minibuffer_allow_text_properties,
               doc: /* Non-nil means `read-from-minibuffer' should not discard text properties.
-This also affects `read-string', but it does not affect `read-minibuffer',
-`read-no-blanks-input', or any of the functions that do minibuffer input
-with completion; they always discard text properties.  */);
+The value could be let-bound or buffer-local in the minibuffer.
+This also affects `read-string', or any of the functions that do
+minibuffer input with completion, but it does not affect `read-minibuffer'
+that always discards text properties.  */);
   minibuffer_allow_text_properties = 0;
 
   DEFVAR_LISP ("minibuffer-prompt-properties", Vminibuffer_prompt_properties,