It looks, to me, like it might be a bug. The hl-line-mode
code moves its overlay (using move-overlay
) to line-beginning-position
, which is at the beginning of the buffer text for the current line (before the (
before overlay-put
).
Why would that mean that the overlay has an effect in the margin as well? If that's normal behavior then maybe the doc could be improved a bit. overlay-start
and overlay-end
necessarily point to buffer positions, so they can't say anything about places that are not buffer-text positions.
The only overlay present is hl-line-overlay
, and its properties are only (window nil face hl-line priority -50)
.
If this is really the expected/intended behavior then perhaps the doc needs to be enhanced a bit to make clear what's happening. Or if the doc already covers it well somewhere then perhaps that somewhere should be cross-referenced from nodes such as (elisp) Overlay Properties.
If you don't get a good answer here or from [email protected] (where you posted the same question) then consider filing a bug report: M-x report-emacs-bug
.
One guess is that this is expected and there is a good explanation for this. But that doesn't seem too clear from the doc.
I notice that node Display Margins says this:
put the margin display specification on the contents of the before-string.
In your example, neither the before-string nor the display specification for it specify property face
.
So far, I haven't found anything in the doc that would suggest that the appearance of the text on the current line (in particular, any overlay on its buffer positions) should affect the appearance of the margin.
On the contrary, the doc says that a before-string
overlay with property display
that affects the margin does not affect the text of the line it is attached to:
To display something in the margin in association with certain
buffer text, without altering or preventing the display of that text,
put a before-string
property on the text and put the margin display
specification on the contents of the before-string.
That would kind of suggest the other way around as well, that is, that the text appearance should not affect the margin appearance.
Update after Eli Zaretski's message to [email protected]
The behavior is by design and is documented, in a way, in the Elisp manual, node Displaying Faces.
What's going on in this case is this:
- A margin-spec
display
-property overlay is applied to a particular buffer zone (which is empty - from a given position to itself).
- Another overlay, with property
face
(value hl-line-face
) is applied to that same buffer zone.
- By the rules of displaying faces (Displaying Faces), that
face
property is what is shown by the margin-spec overlay also.
In other words, because the margin-spec overlay is put on buffer positions that also have a face
overlay, the margin shows that face.
The gotcha is that the margin display is in fact defined on particular buffer positions (like any overlay), and a face
property applied to those positions thus affects the margin appearance.
Note too this part of what I said originally was wrong:
The only overlay present is hl-line-overlay
, and its properties are only (window nil face hl-line priority -50)
.
I mistakenly checked at a buffer position on the line, but not at the position where the margin-spec overlay was put. It was put at the end of the line, because point was there when I did C-x C-e
. Checking at that position shows that there are two overlays, the hl-line-overlay
and a before-string
overlay with this before-string
property value:
#("." 0 1
(display
((margin left-margin)
"Hi there!")))