unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
@ 2020-04-24 15:56 Clément Pit-Claudel
  2020-04-25  7:58 ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Clément Pit-Claudel @ 2020-04-24 15:56 UTC (permalink / raw)
  To: 40821

[-- Attachment #1: Type: text/plain, Size: 2289 bytes --]

Hi all,

The following sample shows the words "low", "mid" and "high" in the left margin using overlays.

(with-current-buffer (get-buffer-create "*margins*")
  (erase-buffer)
  (delete-all-overlays)
  (setq left-margin-width 16)
  (let ((beg (point))
        (end (progn (insert "test") (point))))
    (let ((ov-low (make-overlay beg end)))
      (overlay-put ov-low 'before-string (propertize "low" 'display '((margin left-margin) "low")))
      (overlay-put ov-low 'priority 10))
    (let ((ov-mid (make-overlay beg end)))
      (overlay-put ov-mid 'before-string (propertize "mid" 'display '((margin left-margin) "mid")))
      (overlay-put ov-mid 'priority 50))
    (let ((ov-high (make-overlay beg end)))
      (overlay-put ov-high 'before-string (propertize "high" 'display '((margin left-margin) "high")))
      (overlay-put ov-high 'priority 100))))

All three overlays begin at the same point.  Currently, it seems that margin specs are concatenated in order of increasing priority.  This is likely due to before-strings being concatenated in that order?
One unfortunate side effect of this is that, when margins are too narrow, low-priority margin specs are displayed before high-priority ones, and hence high-priority ones are not visible.

Additionally, unlike fringe bitmaps, for which the highest-priority bitmap replaces all others on the same line, there doesn't seem to be a way for higher-priority margin specs to replace lower-priority ones.

This issue came up when trying to develop a mode to indicate errors and warnings in the margins (instead of drawing symbols in the fringes).  Currently, if a line contains errors and warnings, Flycheck will place multiple overlays on the same line, and the fringe bitmap corresponding to the highest-priority one will be displayed.  But if we put a symbol in the margins instead of the fringes, the symbols won't override each others: instead, they will be concatenated, often in the wrong order (as shown in the attached screenshot).

It would be great if margin specs could be displayed in order of decreasing priority, or if some mechanism existed to indicate that two margin specs are intended to replace each other (the highest-priority one replacing the lowest-priority one), rather than being concatenated.

Clément.


[-- Attachment #2: margins-w.png --]
[-- Type: image/png, Size: 40646 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-04-24 15:56 bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones) Clément Pit-Claudel
@ 2020-04-25  7:58 ` Eli Zaretskii
  2020-04-25 13:01   ` Clément Pit-Claudel
  2020-05-13 15:58   ` Clément Pit-Claudel
  0 siblings, 2 replies; 12+ messages in thread
From: Eli Zaretskii @ 2020-04-25  7:58 UTC (permalink / raw)
  To: Clément Pit-Claudel; +Cc: 40821

severity 40821 wishlist
thanks

> From: Clément Pit-Claudel <cpitclaudel@gmail.com>
> Date: Fri, 24 Apr 2020 11:56:45 -0400
> 
> All three overlays begin at the same point.  Currently, it seems that margin specs are concatenated in order of increasing priority.  This is likely due to before-strings being concatenated in that order?

The strings are not concatenated, they are displayed one after
another, in the order they are processed by the display engine.

The overlays at a given buffer position are indeed sorted.  First,
before-strings should come before after-strings, and within each class
the overlays are sorted in the order of increasing priority.  Then the
sorted overlays are processed one by one in the sorted order.

> One unfortunate side effect of this is that, when margins are too narrow, low-priority margin specs are displayed before high-priority ones, and hence high-priority ones are not visible.

Yes, the display margins use this very simple strategy of truncating
the stuff that has no margin space to be displayed.  Why can't you
compute the width of the margins taking into consideration the size of
what you need to display there?

> Additionally, unlike fringe bitmaps, for which the highest-priority bitmap replaces all others on the same line, there doesn't seem to be a way for higher-priority margin specs to replace lower-priority ones.

First, I don't understand what you say about fringe bitmaps: I don't
think there's any priority associated with those bitmaps, or what am I
missing?

It should be possible to support this idea of "replacing" margin specs
(which seems strange to me, FWIW), given some special display spec,
but it would need a separate pass through the overlays, to find those
which draw in the margins, and mark the replaced ones as "not to be
processed".  But I question the need for such a complexity, when a
simpler solution that doesn't require any changes seems to be at hand.

> This issue came up when trying to develop a mode to indicate errors and warnings in the margins (instead of drawing symbols in the fringes).  Currently, if a line contains errors and warnings, Flycheck will place multiple overlays on the same line, and the fringe bitmap corresponding to the highest-priority one will be displayed.  But if we put a symbol in the margins instead of the fringes, the symbols won't override each others: instead, they will be concatenated, often in the wrong order (as shown in the attached screenshot).

A simple way of overcoming this problem is to define the overlay
priorities in the reverse order of the Flycheck's error/warning
priorities.  A better solution would be to make the margin wider as
needed, something that should be easy enough (line-number-mode did
that, for example).





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-04-25  7:58 ` Eli Zaretskii
@ 2020-04-25 13:01   ` Clément Pit-Claudel
  2020-04-25 14:04     ` Eli Zaretskii
  2020-05-13 15:58   ` Clément Pit-Claudel
  1 sibling, 1 reply; 12+ messages in thread
From: Clément Pit-Claudel @ 2020-04-25 13:01 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 40821

On 25/04/2020 03.58, Eli Zaretskii wrote:
>> One unfortunate side effect of this is that, when margins are too narrow, low-priority margin specs are displayed before high-priority ones, and hence high-priority ones are not visible.
> 
> Yes, the display margins use this very simple strategy of truncating
> the stuff that has no margin space to be displayed.  Why can't you
> compute the width of the margins taking into consideration the size of
> what you need to display there?

I only want/need to display one margin indicator — the highest priority one :)
Consider a line with the following contents:

eee www ewew

And let's assume that the compiler says this:

0-3: error: …
4-7: warning: …
8-12: error: …
8-12: warning: …

In that case, I don't need 4 indicators in the margin, I want just one (indicating an error). But in the the buffer I'd like 4 overlays to apply error and warning faces (though, since two of them cover the same area, one will not be visible; overlay priorities are used to ensure that the error one will take precedence over the warning one).

>> Additionally, unlike fringe bitmaps, for which the highest-priority bitmap replaces all others on the same line, there doesn't seem to be a way for higher-priority margin specs to replace lower-priority ones.
> 
> First, I don't understand what you say about fringe bitmaps: I don't
> think there's any priority associated with those bitmaps, or what am I
> missing?

Your confusion is understandable: I was wrong :(

(with-current-buffer (get-buffer-create "*fringes*")
  (erase-buffer)
  (delete-all-overlays)
  (let ((beg (point))
        (end (progn (insert "test") (point))))
    (let ((ov-low (make-overlay beg end)))
      (overlay-put ov-low 'before-string (propertize "low" 'display '(left-fringe right-arrow compilation-info)))
      (overlay-put ov-low 'priority 10))
    (let ((ov-mid (make-overlay beg end)))
      (overlay-put ov-mid 'before-string (propertize "mid" 'display '(left-fringe compilation-warning)))
      (overlay-put ov-mid 'priority 50))
    (let ((ov-high (make-overlay beg end)))
      (overlay-put ov-high 'before-string (propertize "high" 'display '(left-fringe compilation-error)))
      (overlay-put ov-high 'priority 100)))
  (pop-to-buffer (current-buffer)))

I thought this would show a fringe icon in compilation-error face, because of the higher priority of the corresponding overlay.  It doesn't.
Should I report this as a separate issue?

> It should be possible to support this idea of "replacing" margin specs
> (which seems strange to me, FWIW), given some special display spec,
> but it would need a separate pass through the overlays, to find those
> which draw in the margins, and mark the replaced ones as "not to be
> processed".  But I question the need for such a complexity, when a
> simpler solution that doesn't require any changes seems to be at hand.

Widening the margin isn't a working solution for this case, but displaying the margin specs in order of increasing priority would work.  However, wouldn't that require a second pass as well?  That is, if margin specs were sorted by priority before being inserted, it would work (it wouldn't matter that there are multiple instead of one, since the most important one would be first).

>> This issue came up when trying to develop a mode to indicate errors and warnings in the margins (instead of drawing symbols in the fringes).  Currently, if a line contains errors and warnings, Flycheck will place multiple overlays on the same line, and the fringe bitmap corresponding to the highest-priority one will be displayed.  But if we put a symbol in the margins instead of the fringes, the symbols won't override each others: instead, they will be concatenated, often in the wrong order (as shown in the attached screenshot).
> 
> A simple way of overcoming this problem is to define the overlay
> priorities in the reverse order of the Flycheck's error/warning
> priorities.  A better solution would be to make the margin wider as
> needed, something that should be easy enough (line-number-mode did
> that, for example).

Unfortunately, neither of these will do.  Reversing the overlay priorities means that the text (ewew) in the example above (eee www ewew) will have the warning face applied to it, not the error face.

Making the margins wider won't help either, because I'd like to display the highest-priority issue in the margin, not all of them (often compilers get confused and issue additional spurious messages, so even if there's multiple errors and warnings on one line displaying a single error indicator in the fringe or margin is enough).

Thanks for your help,
Clément.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-04-25 13:01   ` Clément Pit-Claudel
@ 2020-04-25 14:04     ` Eli Zaretskii
  2020-04-25 16:51       ` Clément Pit-Claudel
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2020-04-25 14:04 UTC (permalink / raw)
  To: Clément Pit-Claudel; +Cc: 40821

> Cc: 40821@debbugs.gnu.org
> From: Clément Pit-Claudel <cpitclaudel@gmail.com>
> Date: Sat, 25 Apr 2020 09:01:07 -0400
> 
> On 25/04/2020 03.58, Eli Zaretskii wrote:
> >> One unfortunate side effect of this is that, when margins are too narrow, low-priority margin specs are displayed before high-priority ones, and hence high-priority ones are not visible.
> > 
> > Yes, the display margins use this very simple strategy of truncating
> > the stuff that has no margin space to be displayed.  Why can't you
> > compute the width of the margins taking into consideration the size of
> > what you need to display there?
> 
> I only want/need to display one margin indicator — the highest priority one :)

Then why not have your code do that?

> Consider a line with the following contents:
> 
> eee www ewew
> 
> And let's assume that the compiler says this:
> 
> 0-3: error: …
> 4-7: warning: …
> 8-12: error: …
> 8-12: warning: …
> 
> In that case, I don't need 4 indicators in the margin, I want just one (indicating an error). But in the the buffer I'd like 4 overlays to apply error and warning faces (though, since two of them cover the same area, one will not be visible; overlay priorities are used to ensure that the error one will take precedence over the warning one).

It is your Lisp program that puts these overlays, isn't it?  Why
cannot it put only one overlay, the one you want to be displayed in
this case?

> (with-current-buffer (get-buffer-create "*fringes*")
>   (erase-buffer)
>   (delete-all-overlays)
>   (let ((beg (point))
>         (end (progn (insert "test") (point))))
>     (let ((ov-low (make-overlay beg end)))
>       (overlay-put ov-low 'before-string (propertize "low" 'display '(left-fringe right-arrow compilation-info)))
>       (overlay-put ov-low 'priority 10))
>     (let ((ov-mid (make-overlay beg end)))
>       (overlay-put ov-mid 'before-string (propertize "mid" 'display '(left-fringe compilation-warning)))
>       (overlay-put ov-mid 'priority 50))
>     (let ((ov-high (make-overlay beg end)))
>       (overlay-put ov-high 'before-string (propertize "high" 'display '(left-fringe compilation-error)))
>       (overlay-put ov-high 'priority 100)))
>   (pop-to-buffer (current-buffer)))
> 
> I thought this would show a fringe icon in compilation-error face, because of the higher priority of the corresponding overlay.  It doesn't.
> Should I report this as a separate issue?

Why is that an issue?  You in effect invoke undefined behavior, and
the result is not outlandish, IMO.

> > It should be possible to support this idea of "replacing" margin specs
> > (which seems strange to me, FWIW), given some special display spec,
> > but it would need a separate pass through the overlays, to find those
> > which draw in the margins, and mark the replaced ones as "not to be
> > processed".  But I question the need for such a complexity, when a
> > simpler solution that doesn't require any changes seems to be at hand.
> 
> Widening the margin isn't a working solution for this case, but displaying the margin specs in order of increasing priority would work.  However, wouldn't that require a second pass as well?  That is, if margin specs were sorted by priority before being inserted, it would work (it wouldn't matter that there are multiple instead of one, since the most important one would be first).

Now I'm confused: the overlays are already being sorted by the display
engine, and displayed in the order of increasing priority, as I
explained in my original message.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-04-25 14:04     ` Eli Zaretskii
@ 2020-04-25 16:51       ` Clément Pit-Claudel
  2020-04-25 17:08         ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Clément Pit-Claudel @ 2020-04-25 16:51 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 40821

On 25/04/2020 10.04, Eli Zaretskii wrote:
>> I only want/need to display one margin indicator — the highest priority one :)
> 
> Then why not have your code do that?

It's quite complicated: every time I add a new overlay (they arrive asynchronously, not all at once), I need to check for others on the same line and adjust the symbols.  Every time the text is changed, I need to rescan the current line and adjust the overlay properties.

> It is your Lisp program that puts these overlays, isn't it?  Why
> cannot it put only one overlay, the one you want to be displayed in
> this case?

Because both are needed: for example, when the point is on ewew, the help-echo will be the concatenation of both.  Similarly, when the user browses the error list in a separate buffer, highlighting one error will light up the corresponding portion of the buffer.  Additionally, users can filter errors, hiding certain overlays.

>> I thought this would show a fringe icon in compilation-error face, because of the higher priority of the corresponding overlay.  It doesn't.
>> Should I report this as a separate issue?
> 
> Why is that an issue?  You in effect invoke undefined behavior, and
> the result is not outlandish, IMO.

It is: the buffer shows the face of one overlay and the icon of another one.

>> Widening the margin isn't a working solution for this case, but displaying the margin specs in order of increasing priority would work.  However, wouldn't that require a second pass as well?  That is, if margin specs were sorted by priority before being inserted, it would work (it wouldn't matter that there are multiple instead of one, since the most important one would be first).
> 
> Now I'm confused: the overlays are already being sorted by the display
> engine, and displayed in the order of increasing priority, as I
> explained in my original message.

The margin specs are displayed in order of decreasing priority, as far as I can tell: first the one coming from the overlay with the lowest priority, then the next one, etc.







^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-04-25 16:51       ` Clément Pit-Claudel
@ 2020-04-25 17:08         ` Eli Zaretskii
  2020-04-25 17:21           ` Clément Pit-Claudel
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2020-04-25 17:08 UTC (permalink / raw)
  To: Clément Pit-Claudel; +Cc: 40821

> Cc: 40821@debbugs.gnu.org
> From: Clément Pit-Claudel <cpitclaudel@gmail.com>
> Date: Sat, 25 Apr 2020 12:51:52 -0400
> 
> On 25/04/2020 10.04, Eli Zaretskii wrote:
> >> I only want/need to display one margin indicator — the highest priority one :)
> > 
> > Then why not have your code do that?
> 
> It's quite complicated: every time I add a new overlay (they arrive asynchronously, not all at once), I need to check for others on the same line and adjust the symbols.  Every time the text is changed, I need to rescan the current line and adjust the overlay properties.

Yes, but is it reasonable to ask the display engine to figure that out
for you?  You are talking about something that is clearly application
logic; other applications might want some other logic to have other
overlays "win".

> > It is your Lisp program that puts these overlays, isn't it?  Why
> > cannot it put only one overlay, the one you want to be displayed in
> > this case?
> 
> Because both are needed: for example, when the point is on ewew, the help-echo will be the concatenation of both.  Similarly, when the user browses the error list in a separate buffer, highlighting one error will light up the corresponding portion of the buffer.  Additionally, users can filter errors, hiding certain overlays.

You are talking about aspects of the overlay other than the margin
display.  So leave the other overlays, but remove the margin display
spec from them as needed.

> >> I thought this would show a fringe icon in compilation-error face, because of the higher priority of the corresponding overlay.  It doesn't.
> >> Should I report this as a separate issue?
> > 
> > Why is that an issue?  You in effect invoke undefined behavior, and
> > the result is not outlandish, IMO.
> 
> It is: the buffer shows the face of one overlay and the icon of another one.

As expected: faces are merged, but fringe bitmaps aren't.

> >> Widening the margin isn't a working solution for this case, but displaying the margin specs in order of increasing priority would work.  However, wouldn't that require a second pass as well?  That is, if margin specs were sorted by priority before being inserted, it would work (it wouldn't matter that there are multiple instead of one, since the most important one would be first).
> > 
> > Now I'm confused: the overlays are already being sorted by the display
> > engine, and displayed in the order of increasing priority, as I
> > explained in my original message.
> 
> The margin specs are displayed in order of decreasing priority, as far as I can tell: first the one coming from the overlay with the lowest priority, then the next one, etc.

What you described is actually the order of _increasing_ priority.  Or
am I confused?





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-04-25 17:08         ` Eli Zaretskii
@ 2020-04-25 17:21           ` Clément Pit-Claudel
  2020-04-25 17:36             ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Clément Pit-Claudel @ 2020-04-25 17:21 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 40821

On 25/04/2020 13.08, Eli Zaretskii wrote:
>> Cc: 40821@debbugs.gnu.org
>> From: Clément Pit-Claudel <cpitclaudel@gmail.com>
>> Date: Sat, 25 Apr 2020 12:51:52 -0400
>>
>> On 25/04/2020 10.04, Eli Zaretskii wrote:
>>>> I only want/need to display one margin indicator — the highest priority one :)
>>>
>>> Then why not have your code do that?
>>
>> It's quite complicated: every time I add a new overlay (they arrive asynchronously, not all at once), I need to check for others on the same line and adjust the symbols.  Every time the text is changed, I need to rescan the current line and adjust the overlay properties.
> 
> Yes, but is it reasonable to ask the display engine to figure that out
> for you?  You are talking about something that is clearly application
> logic; other applications might want some other logic to have other
> overlays "win".

I think it is reasonable: we already have a notion of overlays "winning", namely their priority.

>>>> I thought this would show a fringe icon in compilation-error face, because of the higher priority of the corresponding overlay.  It doesn't.
>>>> Should I report this as a separate issue?
>>>
>>> Why is that an issue?  You in effect invoke undefined behavior, and
>>> the result is not outlandish, IMO.
>>
>> It is: the buffer shows the face of one overlay and the icon of another one.
> 
> As expected: faces are merged, but fringe bitmaps aren't.

Yes, which is the outlandish part :)

>>>> Widening the margin isn't a working solution for this case, but displaying the margin specs in order of increasing priority would work.  However, wouldn't that require a second pass as well?  That is, if margin specs were sorted by priority before being inserted, it would work (it wouldn't matter that there are multiple instead of one, since the most important one would be first).
>>>
>>> Now I'm confused: the overlays are already being sorted by the display
>>> engine, and displayed in the order of increasing priority, as I
>>> explained in my original message.
>>
>> The margin specs are displayed in order of decreasing priority, as far as I can tell: first the one coming from the overlay with the lowest priority, then the next one, etc.
> 
> What you described is actually the order of _increasing_ priority.  Or
> am I confused?

Of, yes, you're completely right; sorry for mixing up the terms.
I meant to say that, if highest-priority overlays were displayed first in the margin, then on narrow margins specs from high-priority overlays would take precedence.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-04-25 17:21           ` Clément Pit-Claudel
@ 2020-04-25 17:36             ` Eli Zaretskii
  2020-04-25 19:29               ` Dmitry Gutov
  2020-04-25 20:50               ` Clément Pit-Claudel
  0 siblings, 2 replies; 12+ messages in thread
From: Eli Zaretskii @ 2020-04-25 17:36 UTC (permalink / raw)
  To: Clément Pit-Claudel; +Cc: 40821

> Cc: 40821@debbugs.gnu.org
> From: Clément Pit-Claudel <cpitclaudel@gmail.com>
> Date: Sat, 25 Apr 2020 13:21:13 -0400
> 
> > Yes, but is it reasonable to ask the display engine to figure that out
> > for you?  You are talking about something that is clearly application
> > logic; other applications might want some other logic to have other
> > overlays "win".
> 
> I think it is reasonable: we already have a notion of overlays "winning", namely their priority.

But you want to change that, based I don't really understand on what?

The handling of overlays by their priorities is mainly for when each
overlay is created by a different Lisp program, when coordination is
hard or impossible.  This is not the case here.

> > As expected: faces are merged, but fringe bitmaps aren't.
> 
> Yes, which is the outlandish part :)

I don't think I see it that way.

> > What you described is actually the order of _increasing_ priority.  Or
> > am I confused?
> 
> Of, yes, you're completely right; sorry for mixing up the terms.
> I meant to say that, if highest-priority overlays were displayed first in the margin, then on narrow margins specs from high-priority overlays would take precedence.

And we are right back to square one...

I can only reiterate my suggestion: don't rely on the display engine
to solve the problems in such cases.  The best solution is for the
Lisp program to apply its logic and put only the overlays it needs.

I'm not saying this just out of stubbornness.  Handling of overlays is
a notoriously complex part of the display engine, because they
interact with faces, invisible properties, and display properties in
complicated ways.  We shouldn't complicate it more where Lisp programs
which create the overlays can DTRT instead.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-04-25 17:36             ` Eli Zaretskii
@ 2020-04-25 19:29               ` Dmitry Gutov
  2020-04-25 20:50               ` Clément Pit-Claudel
  1 sibling, 0 replies; 12+ messages in thread
From: Dmitry Gutov @ 2020-04-25 19:29 UTC (permalink / raw)
  To: Eli Zaretskii, Clément Pit-Claudel; +Cc: 40821

On 25.04.2020 20:36, Eli Zaretskii wrote:
> I can only reiterate my suggestion: don't rely on the display engine
> to solve the problems in such cases.  The best solution is for the
> Lisp program to apply its logic and put only the overlays it needs.

I'd like to remind of a longer wishlist item: some infrastructure to 
help different modes use margins (or fringes) on the same line together, 
with predictable results and without stepping on each other's toes.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-04-25 17:36             ` Eli Zaretskii
  2020-04-25 19:29               ` Dmitry Gutov
@ 2020-04-25 20:50               ` Clément Pit-Claudel
  1 sibling, 0 replies; 12+ messages in thread
From: Clément Pit-Claudel @ 2020-04-25 20:50 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 40821

On 25/04/2020 13.36, Eli Zaretskii wrote:
>> Cc: 40821@debbugs.gnu.org
>> From: Clément Pit-Claudel <cpitclaudel@gmail.com>
>> Date: Sat, 25 Apr 2020 13:21:13 -0400
>>
>>> Yes, but is it reasonable to ask the display engine to figure that out
>>> for you?  You are talking about something that is clearly application
>>> logic; other applications might want some other logic to have other
>>> overlays "win".
>>
>> I think it is reasonable: we already have a notion of overlays "winning", namely their priority.
> 
> But you want to change that, based I don't really understand on what?

I think we're getting too closely attached to a specific use case.  There's a simple problem with the margins: you put two overlays on one line, they both have margin specs, they both have faces with a foreground.  One is priority 100, the other 0.  The margin is 1-character wide.  Then you see just one thing in the margin: the spec from the low-priority overlay.  And you see one face in the buffer: the one from the high priority overlay.

I'm saying it doesn't make much sense.  Same for the fringes.  Of course, it's not specified, so nowhere have committed to this broken behavior or to any other beahvior at this point.
But that doesn't make it less broken: the one mechanism we have for determining which overlay wins (priorities) applies in reverse for the fringes and the margins.
Maybe what we need is a more general mechanism for deciding which spec wins, if you don't think priority is the right one.

> I can only reiterate my suggestion: don't rely on the display engine
> to solve the problems in such cases.  The best solution is for the
> Lisp program to apply its logic and put only the overlays it needs.
> …
> We shouldn't complicate it more where Lisp programs
> which create the overlays can DTRT instead.

Then TRT sounds a lot like reimplementing a part of the display engine in ELisp: iterating over overlays on each line, sorting them by priority, taking their margin specs and fringes, determining the highest priority one, and displaying that in the margin/fringe, for each modified line, after each command.  And ideally, doing that lazily too, to avoid doing work on the whole buffer at once and slowing editing down.  Isn't that the job description of the display engine?

Thanks for your help,
Clément.  





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-04-25  7:58 ` Eli Zaretskii
  2020-04-25 13:01   ` Clément Pit-Claudel
@ 2020-05-13 15:58   ` Clément Pit-Claudel
  2020-05-13 16:25     ` Eli Zaretskii
  1 sibling, 1 reply; 12+ messages in thread
From: Clément Pit-Claudel @ 2020-05-13 15:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 40821

On 25/04/2020 03.58, Eli Zaretskii wrote:
> The strings are not concatenated, they are displayed one after
> another, in the order they are processed by the display engine.

I wonder if this should be its separate issue, but the order of strings in the margins changes as the point moves around in the buffer:

(with-current-buffer (get-buffer-create "overlay props")
  (erase-buffer)
  (delete-all-overlays)
  (setq-local left-margin-width 5)
  (save-excursion (insert "test\ntest\n"))
  (let ((ov1 (make-overlay (point-min) (point-max)))
        (ov2 (make-overlay (point-min) (point-at-eol))))
    (overlay-put
     ov1
     'before-string
     #("!" 0 1 (display
                ((margin left-margin) "c"))))
    (overlay-put
     ov2
     'before-string
     #("!" 0 1 (display
                ((margin left-margin) "3")))))
  (display-buffer (current-buffer)))

In this example, moving the point back and forth between point-min and 1+ point-min causes the margins to display alternatively "c3" and "3c".
Is this a bug?





^ permalink raw reply	[flat|nested] 12+ messages in thread

* bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones)
  2020-05-13 15:58   ` Clément Pit-Claudel
@ 2020-05-13 16:25     ` Eli Zaretskii
  0 siblings, 0 replies; 12+ messages in thread
From: Eli Zaretskii @ 2020-05-13 16:25 UTC (permalink / raw)
  To: Clément Pit-Claudel; +Cc: 40821

> Cc: 40821@debbugs.gnu.org
> From: Clément Pit-Claudel <cpitclaudel@gmail.com>
> Date: Wed, 13 May 2020 11:58:26 -0400
> 
> (with-current-buffer (get-buffer-create "overlay props")
>   (erase-buffer)
>   (delete-all-overlays)
>   (setq-local left-margin-width 5)
>   (save-excursion (insert "test\ntest\n"))
>   (let ((ov1 (make-overlay (point-min) (point-max)))
>         (ov2 (make-overlay (point-min) (point-at-eol))))
>     (overlay-put
>      ov1
>      'before-string
>      #("!" 0 1 (display
>                 ((margin left-margin) "c"))))
>     (overlay-put
>      ov2
>      'before-string
>      #("!" 0 1 (display
>                 ((margin left-margin) "3")))))
>   (display-buffer (current-buffer)))
> 
> In this example, moving the point back and forth between point-min and 1+ point-min causes the margins to display alternatively "c3" and "3c".
> Is this a bug?

It is not a bug.  You haven't defined any priorities, so the sorting
of the overlay strings is arbitrary, and the display engine processes
them in the sorted order.  IOW, this is unspecified behavior in
action.

(I can explain why the order changes technically, but it hardly
matters for the more general question.)





^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-05-13 16:25 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-24 15:56 bug#40821: Margin strings are displayed in reverse order of overlay priority (low-priority specs hide high-priority ones) Clément Pit-Claudel
2020-04-25  7:58 ` Eli Zaretskii
2020-04-25 13:01   ` Clément Pit-Claudel
2020-04-25 14:04     ` Eli Zaretskii
2020-04-25 16:51       ` Clément Pit-Claudel
2020-04-25 17:08         ` Eli Zaretskii
2020-04-25 17:21           ` Clément Pit-Claudel
2020-04-25 17:36             ` Eli Zaretskii
2020-04-25 19:29               ` Dmitry Gutov
2020-04-25 20:50               ` Clément Pit-Claudel
2020-05-13 15:58   ` Clément Pit-Claudel
2020-05-13 16:25     ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).