Subject: bug#8627: closed (Re: bug#8627: 24.0.50: cursor property behaves irregularly in before-strings)

From: [email-masked] (GNU bug Tracking System)
Date: Sun, 05 Dec 2021 18:09:14 +0000

Your bug report

#8627: 24.0.50: cursor property behaves irregularly in before-strings

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
8627: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8627
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#8627: 24.0.50: cursor property behaves irregularly in before-strings
From: Eli Zaretskii <[email-masked]>
To: [email-masked]
Cc: [email-masked], [email-masked]
Date: Sun, 05 Dec 2021 16:42:40 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

> Date: Sat, 04 Dec 2021 22:44:50 +0200
> From: Eli Zaretskii <[email-masked]>
> Cc: [email-masked], [email-masked]
> 
> > From: Lars Ingebrigtsen <[email-masked]>
> > Cc: Alp Aker <[email-masked]>,  [email-masked]
> > Date: Sat, 04 Dec 2021 21:22:44 +0100
> > 
> > Eli Zaretskii <[email-masked]> writes:
> > 
> > > This cannot possibly work, not without rewriting the Emacs display
> > > engine in ways I don't intend to.  Quite simply, you cannot put the
> > > `cursor' property on a newline that belongs to a string, because a
> > > newline, obviously, doesn't have a graphic representation (a glyph) on
> > > the screen, it just causes Emacs to continue drawing on the next
> > > screen line.
> > 
> > [...]
> > 
> > > I will eventually update the documentation with this caveat.
> > 
> > This was ten years ago -- I didn't check whether the documentation has
> > been updated, but there doesn't seem to be anything more to do here than
> > that?
> 
> I promised to fix at least some of the behavior, but never did.  I
> will take a look soon.

I took a look.  The code works correctly: since the before-string
leaves the buffer position visible, Emacs by default places the cursor
there, and a non-nil value of the 'cursor' property cannot override
this basic behavior.  If Emacs 23 behaved differently, it was a bug in
Emacs 23.  By contrast, when the value of 'cursor' is an integer, then
the cursor is placed on that character even if the corresponding
buffer position is visible.  Which is what Emacs now does.

So I've now documented these caveats, including the one wrt newline
characters, and I'm finally marking this bug done.

Subject: 24.0.50: cursor property behaves irregularly in before-strings
From: Alp Aker <[email-masked]>
To: [email-masked]
Date: Thu, 05 May 2011 20:01:00 -0400 (EDT)
List-Id: <debbugs-submit.debbugs.gnu.org>

The documentation for the cursor property (info node "(elisp) Special 
Properties") states that:

"Normally, the cursor is displayed at the end of any overlay and text 
property strings present at the current buffer position.  You can place 
the cursor on any desired character of these strings by giving that 
character a non-`nil' `cursor' text property."

And then follows the description of using integer values for the cursor 
property to make it applicable to a range of buffer positions other than 
the range between the overlay's start and end.

However, when used with overlay before-strings (or after-strings), the 
cursor property appears to behave in ways that aren't consonant with the 
docs and that don't follow a consistent pattern.

Here's a recipe for producing the variety of observed behaviors.  (I use 
before-strings, but using after-strings gives similar results.)

(1) Insert some boilerplate text to interact with.

   (save-excursion
     (goto-char (point-min))
     (insert "Lorem ipsum dolor sit amet.\n"))

Make an overlay and give it a before-string with a non-nil cursor property 
on one character:

   (setq olay (make-overlay 5 6)
         str1 (concat "XX"
                      (propertize "Y" 'cursor t)
                      "ZZ"))
   (overlay-put olay 'before-string str1)

If one now does:

   (goto-char (overlay-start olay))

the cursor property is ignored; the cursor appears after the 
before-string.  However, if the before-string appears before a newline, 
the cursor property is respected:

   (save-excursion
     (goto-char (point-min))
     (search-forward "\n")
     (move-overlay olay (1- (point)) (point)))
   (goto-char (overlay-start olay))

The cursor now appears at the propertized character in the before-string.

(2)  Now give the overlay a before-string one of whose characters has a 
numeric cursor property:

   (setq str2 (concat "XX"
                      (propertize "Y" 'cursor 1)
                      "ZZ"))
   (overlay-put olay 'before-string str2)

In this case, the property is respected regardless of location.  With the 
overlay still at the newline:

   (goto-char (overlay-start olay))

and in the middle of a row:

   (move-overlay olay 5 6)
   (goto-char (overlay-start olay))

the cursor appears at the propertized character in the before-string.

(3) But if the before-string contains a newline, the cursor property 
appears to be ignored regardless of location and regardless of whether the 
value of the cursor property is numeric or merely non-nil.  With the 
overlay still in the middle of the line:

   (setq str3 (concat str1 "\nWWW")
         str4 (concat str2 "\nWWW"))
   (overlay-put olay 'before-string str3)
   (goto-char (overlay-start olay))
   (overlay-put olay 'before-string str4)
   (goto-char (overlay-start olay))

the cursor appears after the before string, for both types of property 
value.  Now moving the overlay back to the newline:

   (save-excursion
     (goto-char (point-min))
     (search-forward "\n")
     (move-overlay olay (1- (point)) (point)))
   (goto-char (overlay-start olay))
   (overlay-put olay 'before-string str3)
   (goto-char (overlay-start olay))

the cursor property is again ignored, in both cases.

I started to read through xdisp.c to make some sense of this, but I'm too 
new to Emacs's internals to be able to follow much of the display routine. 
I did observe, though, that cursor_row_p only checks display properties, 
and doesn't appear to check before-strings and after-strings.

In any case, it would appear that either the treatment of before-strings 
and after-strings should be changed so that the cursor property works with 
them as it does with strings that come from display properties, or the 
documentation should be amended to make clear that that it can't be 
expected to do so.  (In the latter case, it would still seem desirable 
that cursor properties in before- and after-strings behave systematically, 
which isn't currently the case.)