Subject: bug#64696: 30.0.50; indent-to inherits preceding text properties, including 'invisible

From: Eli Zaretskii <[email-masked]>
Date: Sun, 23 Jul 2023 13:05:30 +0300

> From: Ihor Radchenko <[email-masked]>
> Cc: [email-masked], [email-masked]
> Date: Sun, 23 Jul 2023 07:30:34 +0000
> 
> On one hand, Emacs' indentation is nicely aligning text as is it
> actually displayed in the buffer, taking into account all kinds of bells
> and whistles that alter the displayed text width.
> 
> On the other hand, such visual indentation is not always good. Visuals
> present in one Emacs config may not be enabled in another config. And
> code/text nicely aligned on one machine will suddenly look ugly on
> other. For example, see
> http://endlessparentheses.com/using-prettify-symbols-in-clojure-and-elisp-without-breaking-indentation.html

Programs that want "indentation" that only counts codepoints (which is
really a rare situation, see below) need to disable all kinds of Emacs
features, otherwise they will not get what they want.

> In Org mode, visual indentation is also not necessarily good thing:
> 
> 1. Org mode is generally aiming for the produced Org files to be
>    readable as unfontified plain text. So, quirks related to visual
>    indentation generally tend to mess things up.

"Unfontified"?  AFAIK, Org files do use fontifications, don't they?
So what do you mean by "unfontified plain text" here?  But that's an
aside, feel free to ignore.

> 2. Org mode uses indentation as part of the syntax. I had to get rid of
>    using `current-column' and calculated "true textual indentation"
>    manually to avoid breakage after `current-column' started to take
>    into account invisibility. (bug#56837)

This cannot be avoided.  Emacs provides by default many features that
"mess up" this kind of "true textual indentation".  Some of these
features include:

  . character composition
  . tab expansion
  . display properties that hide text and display some other text
  . display properties that align text
  . faces that affect character metrics via fonts
  . invisible text

(I'm probably missing some more.)  Only the Lisp program knows which
of those are relevant to the particular application at hand.  For
example, in your "true textual indentation", how do you account for
U+0061 LATIN SMALL LETTER A followed by U+0301 COMBINING ACUTE ACCENT?
They are almost always displayed as a single glyph: á.  Do you
consider this a single column or 2 columns?  What about long Emoji
sequences?

We could introduce separate indentation/current-column knobs for each
of the above features, but it would make little sense to me, since
most, if not all, of them already have such knobs.  For example,
character composition can be disabled by flipping a variable.

> > I don't insist in making that change.  Quite the opposite, actually.
> > I also expect it to break gobs of indentation code where invisible
> > text is involved.  Indentation code should probably temporarily remove
> > the invisibility spec, while indenting, or something.
> 
> That would make sense, yes.
> 
> > The main motivation to fix scan_for_column to consider more visual
> > effects was so vertical cursor motion works as expected when large
> > portions of text are hidden.
> 
> What about having something like `current-visual-column' that will be
> used when we really need to examine which display column the cursor is
> it, accounting for all the display-affecting properties?
> 
> Or maybe even have `use-visual-columns' variable that will modify how
> `current-column' behaves ('visual, 'textual, 'visual-ignore-invisible,
> etc)

See above: you are actually opening a Pandora box, and any solution
will likely be based on existing variables.  So I think we already
have what you want, it just might not be immediately obvious in each
case which of the knobs to use.  The default behavior of
current-column can already be affected by disabling
auto-composition-mode, by tweaking the buffer's invisibility spec, and
by defining display properties whose values are conditional.  Tab
expansion can also be controlled.  What else would make sense?