emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Display problems with `before-string' in overlay


From: Chong Yidong
Subject: Re: Display problems with `before-string' in overlay
Date: Sun, 15 Apr 2007 11:45:38 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.97 (gnu/linux)

Richard Stallman <address@hidden> writes:

> your change is to replace 
>
>              (beg < PT /* && end > PT   <- It's always the case.  */
>             || (beg <= PT && STRINGP (val) && SCHARS (val) == 0))
>
> with a condition that is always true.  Could you please explain the
> motive for that change?  Why is it correct to adjust point when it
> starts out at the beginning of an overlay with a `display' property?

Let me try to explain (again) what the problem is.  It boils down to
where to display the cursor when point is at the beginning/end of an
overlay with a `display' property.  Currently, the cursor can show up
at the following positions (where OOO denotes the overlay, and ABC
denotes the surrounding characters):

 A B|O O O C   (point = 3)
 A B O O O|C   (point = 6)

The problem arises when you have multi-line overlays.  In Emacs 21,
redisplay used a simple rule (see cursor_row_p): "if PT is at the end
of a row, and the row ends with a newline from a string, don't put
cursor on that row."  This rule is desirable for multi-line
before-strings:

 A B X X
 X|O C
 A B X X
 X O|C

But this rule is bad for multi-line display strings, because the
cursor gets pushed down to the next line:

 A B O O
|O C           (point = 3)
 A B O O
 O|C           (point = 6)

The 2005-07-13 change by KFS revoked this rule.  Now, that cursor can
live on a row ending in a newline from a string.  For multi-line
display strings, we have

 A B|O O
 O C           (point = 3)
 A B O O
 O|C           (point = 6)

Note that we MUST revoke the rule if we want multi-line display
strings to behave similar to single-line display strings.

So far so good.  But revoking the rule screws up multi-line
before-strings, because redisplay now tries to draw the cursor on the
first line where the string occurs:

 A B X X|
 X C
 A B X X
 X C|

The naive approach to solving this problem is to change the rule to
"if a row ends with a newline from a before-string, don't put cursor
on that row."  Unfortunately, this is very difficult to implement,
because the glyph matrix does not store information about whether a
string came from a display string or some other source (this is a
deliberate decision for reducing the size of the glyph structure).
Various approaches to extract this information (such as using
get_char_property) don't work for complicated reasons; if someone
comes up with a fast workable solution for this, I'm all ears.

The only other possibility I'm aware of is to sidestep the issue
entirely, by changing adjust_point_for_property so that point can't
land on the start of the overlay.  For instance:

 A|B O O O C   (point = 2)   [point can't be at position 3]
 A B O O O|C   (point = 6)

 A|B O O
 O C           (point = 2)
 A B O O
 O|C           (point = 6)

The trouble with this is that the current adjust_point_for_property
behavior has been in place for a very long time now, and some packages
may have come to rely on it.  So changing this code is not to be done
lightly.


Thus, the current situation is that the cursor is drawn in the wrong
position for mutli-line before-strings.  However,

 (1) this is a seldom-used feature; note that it took 2 years after
     KFS's change for someone to notice this

 (2) There are many redisplay options for working around this bug.

 (3) Even though the cursor position is drawn incorrectly, there is no
     corruption of point or buffer contents, so it's at most a glitch
     that people can live with.

So unless you can come up with an explanation for why changing the
code has no danger of causing instability, I think we should leave
things as they currently are, and adopt my proposed fix for 22.2.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]