Subject: bug#65015: 29.1; align-to on wrapped line regression

From: Eli Zaretskii <[email-masked]>
Date: Thu, 03 Aug 2023 08:49:46 +0300

> From: Axel Forsman <[email-masked]>
> Date: Wed, 2 Aug 2023 23:19:02 +0200
> Cc: [email-masked]
> 
> > It was intentional, since :align-to counts columns, and columns in
> > Emacs continue being counted in continuation lines, they don't start
> > from zero again at the point where the line wraps.
> 
> But in that case this is still a documentation bug, since all
> documentation refers to the value of :align-to as being a hpos and
> not a col.

Well, it doesn't really say what HPOS is.  I have clarified it now,
thanks.

> Where does the notion that :align-to takes a column come from?

What else can it be?  :align-to is used for indenting and aligning
text, and is equivalent to using TABs, so column numbers are natural
when doing that.  People expect current-column to agree with
:align-to, and rightfully so.

> > What you seem to expect would make it impossible
> > to wrap lines with :align-to space display specs without losing the
> > alignment when the line wraps.
> 
> More like "make it impossible to specify a :align-to value greater than
> the width of the text area", because as you worded it, I would argue
> the opposite holds. According to the docs,
> 
>     (concat "..." (propertize " " 'display `(space :align-to (- right
> 4))) "foo")
> 
> should right align the string "foo", however that alignment is lost now
> in version 29 when the line has been wrapped, but not in 28.

The above just makes no sense in wrapped lines, that's all.  It only
makes sense in lines that are narrower than the window width.

> Could you please link to the discussion where the old behavior was
> termed a bug so I can read up?

The change was the result of fixing bug#56176, although there isn't
much of discussion there, and the situation didn't involve
continuation lines, it involved horizontal scrolling and line
truncation.  But the behavior should be consistent; in particular,
when a line is hscrolled, it would be wrong to reset :align-to to
count from the visual left edge of the line on display, instead of
from the (hidden) beginning of line.

> because just from reading the Emacs Lisp manual I am not so sure I
> agree.

It's okay to disagree, but my opinion on this is quite firm.

> Since it is easier to get the version 29 behavior using the min-width
> property instead of :align-to (except that does not work in overlays?)
> than the version 28 behavior, is there any chance this could be reverted?

Reverting the change is out of the question, because it fixed a real
bug, see bug#56176.  We could perhaps consider some changes in this
area, but to make any such changes, we'd need a consistent idea of
behavior that covers line continuation, line truncation, and
horizontal scrolling, and is at least in some sense consistent with
current-column.  TBH, I don't believe something like this is possible,
unless we keep the behavior of Emacs 29.

> I had an implementation of overlay-based popups working in Emacs 28
> that used vertical-motion and :align-to to render the popup on the right
> xy-positions regardless of where logical line breaks were. It cannot easily
> be adapted for Emacs 29 since a lot of the work that the display engine
> otherwise was doing now has to be done manually due to :align-to being
> dumber.
> So I have a bit of a bias toward the old :align-to workings.

I hear you, but building features on top of such dark corners of the
display-engine behavior was and always will be fraught with some risk
of breakage.

AFAIU, to adapt to this change, your code will have to call
current-column to compute the adjustment of the value you pass to
:align-to.  Something like the below:

  (save-excursion
    (beginning-of-visual-line)
    (or (= (char-before) ?\n)
        (backward-char))
    (current-column))

will tell you what to add to the "visual-based" value of :align-to to
get what you want.