Subject: Re: bug#76018: 31.0.50; wrap-prefix properties from visual-wrap-prefix-mode proliferate

From: Jim Porter <[email-masked]>
Date: Sun, 1 Jun 2025 12:24:36 -0700

On 5/31/2025 9:58 PM, Eli Zaretskii wrote:
>> Ok, that was simpler than I thought. Eli, what do you think about adding
>> this patch to the Emacs 30 branch? It just fixes some bugs in
>> 'add-display-text-property', as described in the commit message.
> 
> Not sure we should make such changes on the release branch.

That's alright. I don't have a preference either way.

> Especially since I don't understand the issue very well: what do you
> mean by "list came directly from the property value" and by "used by
> other regions of text"?

I've reworded the commit message to explain things better (I hope):

   When calling 'add-display-text-property' on a region of text that
   already contains PROP, we delete the old property from the list of
   values.  If the region's 'display' property is a list of display
   specifications, we need to avoid destructively modifying the list; other
   regions of text could be using the same list object.  Instead, if
   deleting a property from a list, use 'remove'.  (For a 'display'
   properties that's a vector or a single display spec, this doesn't matter
   since we first make a new list in the code.)

You could see this issue in the old code by doing this:

   (with-temp-buffer
     (erase-buffer)
     (insert "abcd")
     (put-text-property 1 4 'display '((space-width 2) (height 2.0)))
     (add-display-text-property 2 3 'height 1.0)
     (message "%S" (buffer-string)))

This *should* produce the following:

   #("abcd"
     0 1 (display ((space-width 2) (height 2.0)))
     1 2 (display ((height 1.0) (space-width 2)))
     2 3 (display ((space-width 2) (height 2.0))))

but it actually produces this:

   #("abcd"
     0 1 (display ((space-width 2)))
     1 2 (display ((height 1.0) (space-width 2)))
     2 3 (display ((space-width 2))))

That's because the call to 'delete' in 'add-display-text-property' 
destructively modifies the original list object, so the buffer regions 
from 1 to 2 and 3 to 4 end up without the '(height 2.0)' display spec.