11

With:

(when window-system
  (set-face-background 'hl-line "light yellow")
  (global-hl-line-mode 1))

current line highlighted by yellow background, but if text has background properties it also overwritten (like diff-mode, rainbow-mode).

Is it possible to set background only for parts that have no appropriate properties?

UPDATE I start experimenting, seems that stipple isn't conflicting with background:

(set-face-stipple 'hl-line '(4 4 "\x01\x00\x00\x00"))
(set-face-attribute 'hl-line nil :inherit nil)

But stipple unfortunately damage text appearance...

3
  • 1
    Another possibility you may wish to consider is a removal function placed at the tail end of each hl-line command loop, such that a search is performed from the beginning of the current line to the end of the current line (or to the end of the current visual line, if applicable) and the hl-line overlay face can then be removed from wherever other text with a different background color exists. You will likely be searching for highlighting placed by font-lock, although you might also have highlighting placed with other overlays (e.g., flyspell errors / duplicates).
    – lawlist
    Commented Apr 1, 2015 at 13:55
  • 1
    @lawlist I am interested in its implementation; can you please add the full solution below? Commented Apr 1, 2015 at 15:01
  • @kaushalmodi -- I know how to do this for specific overlays or raw text at point, but not for specific text-properties / font-lock highlighting at point. Because I would need to research how to test for those latter two occurrences in order to properly answer this question, I chose to to make a comment instead. Here is a snippet [borrowed from one of Drew's libraries] to test for specific overlays at point: (when (memq NAME-OF-FACE (mapcar (function (lambda (ovr) (overlay-get ovr 'face))) (overlays-at (point)))) (remove-overlays BEGINNING-POINT ENDING-POINT 'face hl-line))
    – lawlist
    Commented Apr 1, 2015 at 16:18

3 Answers 3

5

The problem is that sometimes text property face is used for highlighting, and hl-line-mode uses an overlay. And overlays always appear "on top of" text property face highlighting.

diff-mode, for example, uses the text property, not an overlay. So for cases like this you are out of luck.

But for highlighting that is produced by an overlay you can just reduce the overlay priority of the hl-line overlay: either hl-line-overlay or global-hl-line-overlay, so that that overlay appears to be "below" the other overlay highlighting.

If you use library hl-line+.el then you can use option hl-line-overlay-priority to set the overlay priority. See also Emacs Wiki page Highlight Current Line. (But again, changing the overlay priority has no effect if the other highlighting is not from an overlay.)

4
  • Thanks for answer. I don't bother about difference between faces and overlays... +1
    – gavenkoa
    Commented Apr 2, 2015 at 9:01
  • How do I access that hl-line-overlay property? It e.g. does not show up in customize-variable.
    – 9000
    Commented Nov 9, 2016 at 19:51
  • 1
    @9000: As the answer says, if you use library hl-line+.el then you just customize option hl-line-overlay-priority. Otherwise, you cannot (except by redefining or advising the preprovided functions). That's the point of providing this user option.
    – Drew
    Commented Nov 10, 2016 at 3:03
  • 1
    @9000 You just need to redefine the function hl-line-make-overlay in your init.el. (Or use (advice-add 'hl-line-make-overlay :override #'my/hl-line-make-overlay).) It's rather useless though, as the background properties are ignored.
    – HappyFace
    Commented May 19, 2021 at 17:27
6

I end with a partial solution - highlight only from the end of line:

(defun my-hl-line-range-function ()
  (cons (line-end-position) (line-beginning-position 2)))
(setq hl-line-range-function #'my-hl-line-range-function)

(when window-system
  (require 'hl-line)
  (set-face-attribute 'hl-line nil :inherit nil :background "light yellow")
  (setq global-hl-line-sticky-flag t)
  (global-hl-line-mode 1))
1

Stumbled on this question when attempting not to make the hl-line override the background (although it was indentation guides in this case):

I settled on this, which starts drawing the highlight line after the indentation:

(defun my-hl-line-range-function ()
  (cons
   (+ (line-beginning-position 1) (current-indentation))
   (line-beginning-position 2)))
(setq hl-line-range-function #'my-hl-line-range-function)

Replacing (+ (line-beginning-position 1) (current-indentation)) with (point) works too, (starting at the cursor).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.