9

In this Q&A, it's observed that there is a highlight group for CursorLineNr, which applies to the line number for the cursor line when set cursorline is on.

I notice that using cursorline also changes the color for another highlight group, SpecialKey, which applies if you have, e.g.:

 set list listchars=tab:\|_,trail:-

The problem with this for me is I use a dark background (and so a dark cursorline). My normal SpecialKey setting is also very dark, so that the listchar symbols are only marginally visible. But using cursorline they're white, which makes the trail char indistinguishable from having actually hit -. The trail character is used every time you type a space at the end of a line, so this is more than a minor issue; usually typing a line from beginning to end involves a number of spaces that should be easily distinguished from a dash typo while working (or vice versa, a space typo when you intended a dash).

Since none of the other highlight groups seem to be affected, something like CursorLineNr is presumably being applied, but looking through the hi list I don't see anything appropriate.

Does anyone know what this is? Better yet, does anyone know of a way to modify any highlight group for cursorline?

1
  • 2
    I only highlight the cursor line briefly after I have jumped 2 or more lines. When I am editing text, the cursorline is off. If you can get used to that behaviour, it could mitigate your problem. May 24, 2016 at 20:08

4 Answers 4

8

I've been struggling with that behavior for a long time.

Basically, the foreground color of SpecialKey on the current line is changed to the foreground color of Normal if:

  • the cursorline option is enabled,
  • the CursorLine highlight group has a background color set.

I've never been able to fix that behavior, no matter what I tried. The problem lies somewhere in Vim's source code.

2
  • 1
    That's not the answer I wanted! I've changed my trail char to ~ which is a little less confusing (might also look for some obscure unicode char to use).
    – goldilocks
    May 24, 2016 at 17:03
  • I saw this behavior even without a background color for the CursorLine group. I tried to disable it (i.e. none), tried to leave its default value (it was underlined), the spaces still changed their foreground color
    – d.k
    Jun 1, 2017 at 17:51
2

What worked for me was the following lines in my .vimrc (based on Igor Mikushkin's answer).

autocmd BufNewFile,BufRead * call matchadd('SpecialKey', '\s\+')
autocmd BufNewFile,BufRead * call matchadd('NonText', '\n\+')

VimEnter only works for the first file you open, not for files/tabs you open afterwards. BufNewFile,BufRead has worked so far for all the buffers I've opened.

The first line covers whitespace characters. Vim highlights them in the SpecialKey group, so we apply those styles to them.

The second line covers newlines. Vim highlights them in the NonText group, so we apply those styles to them. You only really need the second line if your NonText characters are highlighted differently than SpecialKey characters.

1
  • This should be the answer.
    – hozza
    Jul 25, 2019 at 18:56
1

Following lines in .vimrc fixed the problem for me.

au VimEnter * call matchadd('SpecialKey', '^\s\+', -1)
au VimEnter * call matchadd('SpecialKey', '\s\+$', -1)

It overrides other styles application for tabs and trailing spaces inside a cursor line.

3
  • why are you storing the matchadd() result in a variable, if you don't use it? Aug 10, 2017 at 5:38
  • @ChristianBrabandt Thank you, it is fixed now. Aug 10, 2017 at 10:49
  • This works for me too using NeoVim.
    – hakunin
    Feb 28, 2019 at 12:34
0

There is yet another "solution", actually sort of a kludge for this problem.

I have custom syntax groups for such thing as "listchars".

Like this:

hi WhiteSpaceChar ctermfg=251 guifg=#999999
call matchadd("WhiteSpaceChar", "[ \t]")

You could do something like this (though I didn't test it):

hi TrailChar ctermfg=251 guifg=#999999
" the \v in the regex is Vim's flag to use Perl-like regex syntax
call matchadd("TrailChar", "\v +$")

But there are at least two problems with this approach:

  1. when you split a window, or create a new tab etc. the highlight becomes broken in the current window, like this:

white space highlight becomes broken, when a new window opens

To fix this I have special functions like:

fun! ResetHiglightJS()
  set syntax=javascript
  "these are for the IndentLine plugin
  "IndentLinesDisable
  "IndentLinesEnable
endfun

for each syntax group, which I use often, to fix the highlighting manually. You can do this in other way like autocommands or manually setting the value for the syntax option. To make the syntax resetting work one also must have this:

call matchadd("WhiteSpaceChar", "[ \t]")

in each corresponding syntax file, like ~/.vim/after/syntax/javascript.vim

  1. This approach does not work normally with at least one plugin — the IndentLine one, so I was forced to stick to an old version of it by setting manually let g:indentLine_newVersion = 0, where the plugin worked normally.

But in other way this approach works normally without the IndentLine plugin:

white spaces have a desired color in the cursor line

And acceptable with it:

indentLine color in the cursor line

Your Answer

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

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