2

I ran into a problem with cursor color being reset when using gruvbox color scheme on both Linux and Windows. During debugging I discovered that the color scheme is reloaded if vimrc is located in $VIM. In my test case I have only two user files: vimrc and $VIM/vimfiles/colors/kgb.vim (the rest is the standard vim installation). I set VIMINIT to "source $VIM\vimrc" to control which vimrc is loaded.

set|grep VIM
MYVIMRC=C:\Users\Public\Vim\vimrc
VIM=C:\Users\Public\Vim
VIMINIT=source C:\Users\Public\Vim\vimrc
VIMRUNTIME=E:\Vim\vim81
cd %VIM%

find vim*
vimfiles
vimfiles/colors
vimfiles/colors/kgb.vim
vimrc

cat vimrc
echomsg "Before colo: " . execute("colo")
color kgb
echomsg "After colo: " . execute("colo")

cat vimfiles/colors/kgb.vim
echomsg "Executing script: " . expand("<sfile>")
let g:colors_name="kgb"
gvim.exe
:mes
Before colo: ^@default
Executing script: C:\Users\Public\Vim\vimfiles\colors\kgb.vim
After colo: ^@kgb
Before colo: ^@kgb
Executing script: C:\Users\Public\Vim\vimfiles\colors\kgb.vim
After colo: ^@kgb
Executing script: C:\Users\Public\Vim\vimfiles\colors\kgb.vim

NOTE: The above output shows that vimrc is loaded twice and colorscheme is loaded three times in Windows (only two times on Linux). If VIMINIT is not set and vimrc is located in $VIM, then vimrc is loaded only once, but colorsheme is still loaded twice on both Windows and Linux.

:scr
  1: C:\Users\Public\Vim\vimrc
  2: C:\Users\Public\Vim\vimfiles\colors\kgb.vim
  3: E:\Vim\vim81\plugin\getscriptPlugin.vim
  4: E:\Vim\vim81\plugin\gzip.vim
  5: E:\Vim\vim81\plugin\logiPat.vim
  6: E:\Vim\vim81\plugin\manpager.vim
  7: E:\Vim\vim81\plugin\matchparen.vim
  8: E:\Vim\vim81\plugin\netrwPlugin.vim
  9: E:\Vim\vim81\plugin\rrhelper.vim
 10: E:\Vim\vim81\plugin\spellfile.vim
 11: E:\Vim\vim81\plugin\tarPlugin.vim
 12: E:\Vim\vim81\plugin\tohtml.vim
 13: E:\Vim\vim81\plugin\vimballPlugin.vim
 14: E:\Vim\vim81\plugin\zipPlugin.vim
 15: E:\Vim\vim81\menu.vim
 16: E:\Vim\vim81\autoload\paste.vim
:quit
Error:
Executing script: C:\Users\Public\Vim\vimfiles\colors\kgb.vim

If I move vimrc under vimfiles and set VIMINIT="source $VIM\vimfiles\vimrc" the scheme is loaded only once:

set|grep VIM
MYVIMRC=C:\Users\Public\Vim\vimfiles\vimrc
VIM=C:\Users\Public\Vim
VIMINIT=source C:\Users\Public\Vim\vimfiles\vimrc
VIMRUNTIME=E:\Vim\vim81

gvim.exe
:mes
Before colo: ^@default
Executing script: C:\Users\Public\Vim\vimfiles\colors\kgb.vim
After colo: ^@kgb
Executing script: C:\Users\Public\Vim\vimfiles\colors\kgb.vim
:quit
Error:
Executing script: C:\Users\Public\Vim\vimfiles\colors\kgb.vim

Any explanation why this is happening?

  • $HOME is searched first anyway. So what's the reason to set $VIM after all? – Matt Dec 4 '19 at 7:10
  • $VIM can point to a single location mounted from multiple clients, which have different access path. – user1602 Dec 11 '19 at 11:24
  • @user1602 Your question now contains 6 different possible configurations, with multiple different sets of resulting behaviour, but only includes the full output for one of these (and doesn't state for which configuration the output applies), which makes it quite hard to nail down the precise issue! If you could either include the full output for all the configurations you are asking about or, better yet, narrow down your question a bit, it would make it easier for us to help you. – Rich Jan 23 at 17:02
3

Why the colorscheme is loaded twice

This is slightly speculative, since your excellent and detailed question nevertheless still doesn't contain quite enough information about your setup to be certain, but I believe what is happening is this:

  1. When Vim starts up, one of the first things it does is load your $VIM/vimrc file, which loads your colorscheme, thus setting g:colors_name. However, note that $VIM/vimrc is not considered a user vimrc file, but is instead a system vimrc. (See :help system-vimrc and check the output of :version to confirm that Vim is using this location for its system vimrc.)

  2. Presuming you don't have another vimrc in any of the locations described in :help _vimrc point 3.c.II, then Vim will then load the defaults.vim file, as described in point 3.c.V, because no user vimrc has been found.

  3. defaults.vim executes the command :syntax on, which sources the file $VIMRUNTIME/syntax/syntax.vim.

  4. syntax.vim executes the command :runtime syntax/synload.vim, which will find and source the file $VIMRUNTIME/syntax/synload.vim.

  5. synload.vim contains the following code:

    " Set the default highlighting colors.  Use a color scheme if specified.
    if exists("colors_name")
      exe "colors " . colors_name
    

    colors_name was set in Step 1, so execution enters the if block, the :colorscheme command is run, and your colorscheme is reloaded.

If you view the output of the command :scriptnames, you should be able to trace (roughly) the execution of Vim's startup procedure through these files.

How to fix your problem

There are several ways you could prevent the double-load, but there's a simpler and more robust method of solving your actual issue, which is that you want to ensure your cursor color is set correctly. You can do this by setting up an autocommand that fires whenever the colorscheme is set e.g.:

augroup SetCursorColor
  autocmd!
  autocmd ColorScheme * highlight Cursor guibg=red guifg=NONE
augroup END

The pattern is matched against the colorscheme name, so if you only want to use this cursor colour in gruvbox, you can specify this like so:

autocmd ColorScheme gruvbox highlight Cursor guibg=red guifg=NONE
| improve this answer | |
  • According to 3.c: "Five places are searched for initializations. The first that exists is used, the others are ignored." Since I set VIMINIT variable, only this value should be used, right? Btw, :scripts does not show that $VIMRUNTIME/defaults.vim is loaded. Now I tried Vim82 and got a new problem: vimrc is loaded twice :) – user1602 Jan 22 at 9:12
  • @user1602 Your question has changed since I wrote my answer, which addressed the original question, and which ignored the P.S. (because I didn't see it!). Did you actually have VIMINIT set on Windows too? – Rich Jan 22 at 9:34
  • @user1602 I haven't investigated fully, but I believe your vimrc is loaded twice because you are setting it as your system vimrc (via its location) and then manually sourcing it with your VIMINIT. – Rich Jan 22 at 9:37
  • @user1602 When you say you "got a new problem" do you mean that this is in addition to your original problem, or has it replaced it? – Rich Jan 22 at 9:39
  • @user1602 Is your intention for your file to be a system or a user vimrc? If the latter, then $VIM is (probably, depending on how Vim was compiled) the wrong location for it. Do all your problems go away if you change the environment variable you are using to e.g. $NOTVIM? – Rich Jan 22 at 9:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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