5

I'm trying to change the location of the viminfo file.

Why does the value of &viminfo revert after it is set in vimrc?

TL;DR:

In my vimrc I have:

set nocompatible
exec "set viminfo+=n".expand($XDG_DATA_HOME)."/vim/viminfo"
echom &viminfo

I've noticed that echo &viminfo from command mode shows the previous version of &viminfo even though the echom inside vimrc shows that &viminfo was correctly (but temporarily) updated.

I'd suspect autocommand, but ag -ul viminfo only shows my vimrc and the viminfo file itself.

Why does the value of &viminfo change after I explicitly set it?

Full description

@ravi@boxy:~$ vim --version | head -1
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Aug 05 2016 16:48:20)

I start vim with VIMINIT set to honour the XDG Base Directory Specification

@ravi@boxy:~$ echo $VIMINIT
let $MYVIMRC="$XDG_CONFIG_HOME/vim/vimrc"|set nocp|exec "set viminfo+=n".expand($XDG_DATA_HOME)."/vim/viminfo"|echom &viminfo|source $MYVIMRC
@ravi@boxy:~$ 

For belts and braces, I also have in my vimrc:

set nocompatible
" Location of the viminfo file
exec "set viminfo+=n".expand($XDG_DATA_HOME)."/vim/viminfo"
echom &viminfo

Now I remove the existing ~/.viminfo, start vim, then exit:

@ravi@boxy:~$ rm ~/.viminfo 
@ravi@boxy:~$ vim
'100,<50,s10,h,n/home/ravi/.local/share/vim/viminfo
'100,<50,s10,h,n/home/ravi/.local/share/vim/viminfo
Press ENTER or type command to continue
@ravi@boxy:~$ file ~/.viminfo 
/home/ravi/.viminfo: ASCII text
@ravi@boxy:~$

The &viminfo variable gets printed twice because of the belt and braces, but as you can see, the file is still created at the default location.

2

TL;DR

This seems to be a bug in vim where set nocompatible is not idempotent and doesn't follow the principle of least astonishment.

As a workaround, either:

  1. Ensure that you set nocompatible (or the equivalent set nocp) only once, and at the top of your vimrc.

  2. Don't set it if it's already set:

    if &compatible | set nocompatible | endif " Avoid side effects if `nocp` already set
    

Explanation and bug illustration

From :help compatible (empahsis mine):

This is a special kind of option, because when it's set or reset, other options are also changed as a side effect. CAREFUL: Setting or resetting this option can have a lot of unexpected effects: Mappings are interpreted in another way, undo behaves differently, etc. If you set this option in your vimrc file, you should probably put it at the very start.

Note that &viminfo is not listed in the side-effects, however the following lines clearly show the side effect upon &viminfo:

set nocompatible
set viminfo+=nWatch-my-viminfo-file-location-be-ignored
echom &viminfo
set nocompatible " do side effects even though nocomptible is already set
echom 'After 2nd "set nocompatible":'
echom &viminfo

Output:

'100,<50,s10,h,nWatch-my-viminfo-file-location-be-ignored
After 2nd "set nocompatible":
'100,<50,s10,h

vim --version | head -1

VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Aug 05 2016 16:48:20)


Resolution

I have raised two GitHub issues regarding this:

See also StackExchange's question: How to tell VIM to store the viminfo file somewhere else?

  • 1
    "Ensure that you set nocompatible (or the equivalent set nocp) only once, and at the top of your vimrc" -> Actually, you don't need to do put this in your vimrc at all, ever. Using nocompatible is the default if there is a vimrc file! Vim only loads in compatible mode if there's no vimrc. This is mentioned in :help 'nocompatible' in the paragraph after the one you quoted ;-) – Martin Tournoij May 1 '17 at 5:07

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.