Customizing highlighting of individual Neovim windows
In 2017, Neovim released the winhighlight
feature. It gave users the ability to perform “window-local highlights”. There were talks of using it in tandem with the upcoming (hopefully) floating windows feature. But how can you use it now?
Disclaimer: Thanks to Niall Burkley, I have realized that you should only use
guifg
andguibg
if you havetermguicolors
enabled in Neovim. If not, then you should be usingctermfg
andctermbg
for color changes.See
:h 'termguicolors'
for more details.
Highlighting Active/Inactive Windows
One of the most obvious benefits of per-window highlighting is the ability to distinguish between active and inactive windows.
This used to be done via plugins like blueyed/vim-diminactive that were built on a hack using &cursorcolumn
. Now, the basic functionality of changing the background color of inactive windows is now done easily in Neovim:
The process is pretty straight forward:
1. Create an auto-command group to call a function when a new window is entered.
2. Create your new local highlights in that function to customize windows.
Note the use of the Normal
and NormalNC
highlight groups. According to the documentation, the Normal
highlight group affects “normal text” and the NormalNC
highlight group affects “normal text in non-current windows”.
This allows us to set the highlight group of the active window to the ActiveWindow
highlight group, and inactive windows to the InactiveWindow
. The syntax for winhighlight
is to define a comma-delimited set of highlight groups in the format {Highlight_Group_To_Replace}:{Highlight_Group_To_Use_Instead}
.
I found that using something like this hex color tool allows you to darken/lighten your colorscheme’s background color by a few percent to achieve a good “inactive” background color.
Targeting Specific Window Types
Another useful feature is the ability to target specific types of windows. My personal setup is very minimal. I started with the Oceanic-Next colorscheme and removed the background from several highlight groups. This resulted in a very clean, minimal interface.
However, I had an issue. When I tried to invoke auto-complete, I had a hard time distinguishing between the editor window and the preview window.
Before winhighlight
this was a difficult task. Preview windows had the same background as your normal window, and if your status line didn’t have a different background color, everything ran together. Fortunately, this can also be fixed with winhighlight
:
That’s all it takes. Just by checking the &previewwindow
variable, we can specifically target the preview window. I replaced the Normal
highlight group with the MarkdownError
group because it suited my needs: only a subtle background difference. I could’ve created another custom highlight group, but this one worked just fine.
In case you’ve never messed with highlighting groups, you can see all the predefined highlight groups by running the command:
:so $VIMRUNTIME/syntax/hitest.vim
The end result is a subtle background change for the preview window that keeps the desired minimal UI, while still offering a clear distinction between the main window and the preview window.
You can also target the Neovim terminal window. If you use the feature and want to customize anything about the highlighting groups, you can do it by checking the &buftype
variable:
That about wraps it up. I hope the was a useful intro into the winhighlight
feature. Let me know if I missed anything or if there are any other good examples of window-local highlights.