Subject: bug#71605: 30.0.50; [PATCH] Support variable-width text in 'visual-wrap-prefix-mode'

From: Jim Porter <[email-masked]>
Date: Mon, 17 Jun 2024 11:44:47 -0700

Replying to your individual points below, but in the other subthread, I 
had the idea that maybe a better way to do this would be for the wrap 
prefix to always be the first-line prefix but to make it transparent 
when desired. So for the "* some text" example, the wrap-prefix would be 
"* " but fontified(?) such that you can't see it.

A face transparency attribute might do the trick, and be useful for 
other things too: 
<https://lists.gnu.org/archive/html/emacs-devel/2024-01/msg00657.html>. 
Or maybe :align-to could take a string value, which would mean "use the 
pixel-width of this string as the value".

On 6/17/2024 11:20 AM, Eli Zaretskii wrote:
>> Date: Mon, 17 Jun 2024 10:42:56 -0700
>> Cc: [email-masked]
>> From: Jim Porter <[email-masked]>
>>
>> I tried using :align-to, and it doesn't seem to take effect for the
>> 'wrap-prefix' text property. I haven't looked closely at why that
>> doesn't work, but even if it did, I think it might make things more
>> complex than they already are.
> 
> What exactly did you try?  I might be misremembering, but I'm not
> aware of any limitations wrt use of :align-to in wrap-prefix.  In
> fact, the ELisp reference manual explicitly mentions :align-to in its
> description of wrap-prefix.

My minimal test case is to open a buffer, put some random text in (long 
enough that it would wrap), and then call:

   (put-text-property (point-min) (point-max) 'wrap-prefix '(space 
:align-to 4))

Nothing changes for me. If I replace :align-to with :width, I see the 
continuation lines get indented by 4 characters.

>> The 'face-change' idea could work, or here's another possibility: what
>> about using :relative-width?
> 
> :relative-width could work, but you'd need to make sure it takes the
> width from a fixed character, otherwise different paragraphs won't
> align the same.

In this case, the first character is always a space so that's ok.

>> If I set that correctly, then the pixel-size should adjust as the
>> text scales. It wouldn't handle the case where the actual font
>> changes though.
> 
> Why not?

I was planning to set :relative-width to <first_line_prefix_width> / 
<width_of_one_space>. If the font changes, the result of that 
calculation can change.

>>>> -@defun string-pixel-width string
>>>> +@defun string-pixel-width string &optional buffer
[snip]
>> Maybe this should take the face-remapping-alist directly? Or maybe we
>> should pass in a window?
> 
> If you can pass a window, you can use window-text-pixel-size instead.

I think 'window-text-pixel-size' would compute the size of the text 
already in the buffer, and I was looking for a function that told the 
width of some text if I were to later display it in that window. In any 
case, I might not need to use this function at all depending on how I do 
things...

>> Yeah, though the FCP argument is always the prefix we constructed, so we
>> know what the display-spec looks like if it's present.
> 
> Sure, but that means the code is fragile, and you need to comment
> prominently that if the form of the display spec changes in the
> future, this code will need to be adapted.

Assuming I keep going down this route, I'll be sure to comment this 
extensively.