Prioritize hl-line Highlight Over Neotree Faces
In hindsight, it looks like my quest to tweak how Emacs looks and feels is to make it more Mac-like. No wonder, because I really like the OS X-era UI. So I’m still using the system default selection highlight colors and want these everywhere.
For example in neotree
.
The hl-line
current line highlight, combined with lin.el
(which I use for half a year) to make it act as a prominent selection instead of a subtle hint in that mode, did lose over neotree
’s own face settings.
Inspecting why that looked the way it looked via C-u C-x = to see the character and face information, I got this:
There are 2 overlays here:
From 565 to 598
face hl-line
priority -50
window nil
From 578 to 597
button [Show]
category default-button
face neo-file-link-face
follow-link t
help-echo [Show]
keymap [Show]
neo-full-path [Show]
Never saw this before, but “priority: -50” sounded like the way to go. Raise the priority, then maybe the hl-line
face would override the neo-file-link-face
of the file “button” at point.
But there’s no face property called ‘priority’. Searching the web for this, I found out about show-paren-priority
on Emacs.StackExchange, so it looks like this is commonly a variable, and yes, there is a hl-line-overlay-priority
and its value is -50
. I don’t know what other priorities there are, so I’m just flipping it to +50 for good measure.
Update 2022-06-10: Setting this in neotree still makes sense, but setting this globally only looked good for a while – until I ran into color issues with selections. If the priority is not negative, it will override the region selection colors. So I couldn’t see when I was selecting file names or file sizes in dired
. Here’s a fixed version.
The updated code just enables this for neotree buffers:
(defun my/neotree-hook ()
(hl-line-mode -1) ;; Disable if it's on, see explanation below.
(setq-local hl-line-overlay-priority +50)
(lin-mode))
(add-hook 'neotree-mode-hook #'my/neotree-hook)
The important part is to set the priority buffer-locally before entering hl-line-mode
or lin-mode
. So you cannot use lin-mode-hooks
to auto-enable lin, but have to do it this way instead. Make sure to remove neotree-mode-hook
from lin-mode-hooks
so it isn’t enabled early.
But neotree
has a neo-hide-cursor
setting that auto-enables hl-line-mode
before calling any hooks:
(define-derived-mode neotree-mode special-mode "NeoTree"
"A major mode for displaying the directory tree in text mode."
(setq indent-tabs-mode nil ; only spaces
buffer-read-only t ; read only
truncate-lines -1
neo-buffer--show-hidden-file-p neo-show-hidden-files)
(when neo-hide-cursor
(progn
(setq cursor-type nil)
(hl-line-mode +1)))
...
Geez! So we either have to:
- not use
neo-hide-cursor
, which would be a surprise setting to accommodate for the way I configure lin; - add an advice to
hl-line-mode
limited to a neotree buffer instead and change the priority before enablinghl-line-mode
; - just keep the quick fix to disable
hl-line-mode
before resetting the priority.
Disable and re-enable hl-line-mode
or neotree
, and then it looks good!
The next nit I want to pick is to enable horizontal scrolling with the mouse for long filenames, and removing the block cursor when LIN is active (which you don’t see on the screenshots because I timed the picture with its blinking).