4

I'm using vim 8.1 on windows. The IT department has set $HOME to a slow network drive. Every time a file gets written to $HOME vim slows down.

I have $VIM/vimrc with the following content.

let $HOME = $USERPROFILE

This used to work, but now netrw still creates files on the network drive.

How do I change $HOME so that no slowdown occurs?

  • 2
    Does :echo $HOME and :echo expand("$HOME") print what you expect? (Just to make sure it is not reset afterwards.) – Ralf Jan 4 '19 at 12:50
  • Yes, it does print what I expect – user20406 Jan 4 '19 at 13:23
7

After you answered the question yourself, the focus shifted. It seems the Question is now "How can I prevent Vim from checking for $HOME/_vimrc?".

Try the following:

  • Create the file $USERPROFILE/vimrc with all your configuration.
  • Create the environment variable VIMINIT with the value source $USERPROFILE/vimrc.

On startup the variable VIMINIT is checked first. If it is set, the value of $VIMINIT is used as an Ex command line.


Update (I know that the questioner is not interested anymore):

You should also check your runtimepath. Most likely it still points to $HOME/vimfiles (on Windows). So you should create the directory $USERPROFILE/vimfiles to store extended configuration and plugins etc.

At the beginning of $USERPROFILE/vimrc you have to fix the runtimepath. I would try it like this:

set runtimepath-=~/vimfiles
set runtimepath^=$USERPROFILE/vimfiles
set runtimepath-=~/vimfiles/after
set runtimepath+=$USERPROFILE/vimfiles/after

After that you should still change $HOME, as others (like netrw) still uses it.

let $HOME=$USERPROFILE

I'm on Linux, so someone should test this on Windows.

| improve this answer | |
  • I did what you said. I put let $HOME = $USERPROFILE and color blue in it. It got blue and echo $HOME echoes home, but vim still starts dog slow until I disconnect the network drive. – user20406 Jan 4 '19 at 14:01
2

Running without major issues for a week now so I'm adding this as an alternative answer.

I tried all suggestions made here and wherever I could find and the only thing that effectively worked in skipping accessing my networked homefolder was using gvim --clean.

  • Although the help states that --clean is equivalent to -u DEFAULTS -U NONE -i NONE, it is not. Using procmon, it was clear that vim was still accessing my network drive.
  • It's not a solution. It's good to troubleshoot but I don't want to work with a clean vim.

I ended up patching the executable to skip the HOME* environment variables all together.
It did require me to change my $HOME references in my vimrc.local to an absolute path

Tested on vim 8.1.282.0
if the byte sequence is present in your version of vim, I assume it will work as well. You might just as well crash vim but there's little/no harm in trying

search for following bytes

CB 65 00 E8 D1 9B F1 FF 8B E8 83 C4 04 85 ED 74 06 80 7D 00 00 75 7F
68 04 CC 65 00 E8 B8 9B F1 FF 83 C4 04 8B F8

and replace with

CB 65 00 E8 D1 9B F1 FF 8B E8 83 C4 04 85 ED 74 04 80 7D 00 00 EB 7F
68 04 CC 65 00 E8 B8 9B F1 FF 83 C4 04 8B F8 
  • Original vim's MD5 E6BBB217EAAB09FE6E2C380D4DF09BD3
  • Patched vim's MD5 BDAAAC3FA3F6796825A51EF1C0E5B3FD

Description of the patch

Using Ghidra to reverse engineer vim, you can find where references to the HOME* environment variables get checked. I have relabeled the autogenerated labels in below screenshots as to show what the block of code does in the context of following/skipping the home folders.

I found two code paths that lead to executing the Cullprit code depending on whether or not the HOME* environment variables are set. The plan of attack then was to patch the code to always flow to SkipHome

Original code


Patch two instructions

  1. Changed the 74 06 JZ instruction to 74 04 JZ so instead of jumping 6 bytes into the Cullprit code when the $HOME environment variable is not set, jump to our unconditional JMP
  2. Changed the 75 7f JNZ conditional jump to a eb 7f JMP unconditional jump.

Patched code


Addendum

That said, vim first checks for a $HOME variable and only checks for $HOMEDRIVE and $HOMEPATH if $HOME is empty. Windows, afaik, does not set a $HOME variable out of the box so I assume that is simply a cross platform check.

If you don't want to mess with your existing HOME* variables and don't want to patch, it looks like you can abuse that fact by setting a $HOME variable to whatever you like and skip the HOME* code.

for example setx home <path to your _vimrc> might just work.

| improve this answer | |
  • 2
    Fascinating answer; can you explain what the byte patch is/does? – D. Ben Knoble Jun 25 at 20:18
  • @D.BenKnoble - I have added an explanation of the patch and an addendum. – Lieven Keersmaekers Jun 26 at 6:26
  • 2
    Lieven, that is real hacking! I would not recommend that to anyone, but I like it! :-) – Ralf Jun 26 at 7:20
  • As it turns out, the Addendum does appear in the help as is shown in this answer – Lieven Keersmaekers Jun 29 at 5:45
0

You can use the -u option to give an alternate .vimrc file of your choice when starting vim. As stated here, you can also use the $MYVIMRC variable to automate this (this takes precedence over $HOME), which should answer your question.

| improve this answer | |
  • I know the -u option, but that's a hack. The $MYVIMRC gets set to the first config file it finds so that's not an option either. – user20406 Jan 4 '19 at 12:31
  • 1
    Ok, and what about HOME=new_address vim ... ? – Charles Gueunet Jan 4 '19 at 13:06
  • What do you exactly mean by that? – user20406 Jan 4 '19 at 13:22
  • Also what did you mean in your answer, that $MYVIMRC takes precedence? The documentation says "The $MYVIMRC environment variable is set to the file that was first found, unless $MYVIMRC was already set and when using VIMINIT." – user20406 Jan 4 '19 at 13:27
  • 1
    in bash, if you use HOME=$USERPROFILE vim the environment variable $HOME will be set to the content of $USERPROFILE only for the following command: vim. Ok, the $MYVIMRC only point to a file, it is not used by vim to find the .vimrc. Mea culpa. – Charles Gueunet Jan 4 '19 at 13:33
0

Turns out the culprit was

source $VIMRUNTIME/vimrc_example.vim

in my $HOME/_vimrc. After removing it no files were created anymore.

Never mind. After more testing it didn't work.

Solution

Create a vimrc in $VIM with following content

let $HOME = $USERPROFILE

This however is not a perfect solution.

According to the documentation it first searches $HOME and then $VIM. This means there is a slow access to the network drive to check if there exists a vimrc. This is quite noticeable. To fix that you either have to somehow undo the work of the IT guys or open Vim with -u everywhere. Or just keep Vim open forever.

Or you use an editor with manners that saves its configuration in %appdata% like it's supposed to. I'm out.

| improve this answer | |
  • This was driving me nuts. I ended up patching the executable to skip the HOME* environment variables all together. So far, no side effects noticed. For anyone interested and using vim 8.1.282.0 - search for following bytes CB 65 00 E8 D1 9B F1 FF 8B E8 83 C4 04 85 ED 74 06 80 7D 00 00 75 7F 68 04 CC 65 00 E8 B8 9B F1 FF 83 C4 04 8B F8 and replace with CB 65 00 E8 D1 9B F1 FF 8B E8 83 C4 04 85 ED 74 04 80 7D 00 00 EB 7F 68 04 CC 65 00 E8 B8 9B F1 FF 83 C4 04 8B. My original vim's MD5 is E6BBB217EAAB09FE6E2C380D4DF09BD3. My patched vim's MD5 is BDAAAC3FA3F6796825A51EF1C0E5B3FD. – Lieven Keersmaekers Jun 18 at 12:12

Your Answer

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