Use macOS Native Highlight Colors for Emacs hl-line

In some modes in Emacs, the hl-line (‘hl’ for ‘highlight’) is used. That’s not intended to highlight the current line when you edit text; it’s used for things like feed readers and email, where you operate on items that are represented on lines. This highlight is way too subtle for my taste.

I use the very excellent dark and light [modus-themes][modus] in Emacs. The light theme has black text on white background, and that is pretty much what you see in macOS Finder, too, when you browse directories. In Finder, when you select something, you get the classic blue bakcground with white foreground color.

That’s what was missing from my life, so I overwrite the colors. Native GUI Emacs on macOS has named colors like the NSColors from AppKit, so I can just use selectedContentBackgroundColor and alternateSelectedControlTextColor. This could, in theory, also adapt to dark vs light mode, but on macOS, the color is actually the same for both modes. (At least from eyeballing it.)

Some random newsletter emails with the new colors

Update 2021-11-09: This approach has been improved and in part superseded by the introduction of LIN so I can apply these colors to selection UIs but not to regular text documents.

Here’s how I hook into dark/light mode changes to make sure the color is replaced:

(defun ct/theme-mac-os-hl-line ()
  "On macOS, use the system selection color combo. Should work for dark and light mode."
  (when (memq window-system '(mac ns))
    (set-face-attribute 'hl-line nil
                        :foreground "alternateSelectedControlTextColor"
                        :background "selectedContentBackgroundColor")))
(add-hook 'ns-system-appearance-change-functions #'ct/theme-mac-os-hl-line)

I also hook this up to modus-themes.

(add-hook 'modus-themes-after-load-theme-hook #'ct/theme-mac-os-hl-line)