Reconfiguring my Vim setup without disturbing my original configuration

A walkthrough of the steps taken to reconfigure my VIM setup while keeping my original vim setup intact

Conrad Gomes • March 16, 2024

Vim has been my primary text editor and IDE for a significant portion of my career. I don’t think I’ve reached the level of mastery I should have after working with it for this long. As of late I’ve been spending time researching the way different developers are using it.

My current configuraion is based on minor changes that I’ve added as and when I felt I’ve needed a faster way of executing certain tasks. I will attempt to use a new vimrc file i.e. vimrc.scratch and a new runtime folder i.e. vim.scratch to reconfigure my Vim setup.

Setting up a new vimrc

In order to proceed I need to be able to experiment with a new configuration without affecting my existing configuration.

The Vim configuration uses a file to lookup your personal settings and mappings. The order of search on a Unix machine is $HOME/.vimrc or $HOME/.vim/vimrc. In my machine I use the former. As seen in Vim’s help documentation :h vimrc:

You probably got tired of typing commands that you use very often. To start Vim with all your favorite option settings and mappings, you write them in what is called the vimrc file. Vim executes the commands in this file when it starts up.

The vimrc can be specified by passing the -u option argument. So, I could start Vim like so:

$ vim -u ~/play/vim/vimrc.scratch

But it turns out that setting the -u option argument doesn’t load the defaults.vim which is the case with $HOME/.vimrc. As seen in the documentation :h -u :

When {vimrc} is equal to “DEFAULTS” (all uppercase), this has the same effect as “NONE”, but the |defaults.vim| script is loaded, which will also set ‘nocompatible’. Also see |–clean|.

Using the “-u” argument with another argument than DEFAULTS has the side effect that the ‘compatible’ option will be on by default. This can have unexpected effects. See |‘compatible’|.

Also the compatible option is switched on when -u is used as stated in the documentation :h compatible :

When a vimrc or gvimrc file is found while Vim is starting up, this option is switched off, and all options that have not been modified will be set to the Vim defaults. Effectively, this means that when a vimrc or gvimrc file exists, Vim will use the Vim defaults, otherwise it will use the Vi defaults. (Note: This doesn’t happen for the system-wide vimrc or gvimrc file, nor for a file given with the -u argument).

To get Vim to work with your vimrc and also retain the defaults I follow the documentation :h defaults:

If you create your own .vimrc, it is recommended to add these lines somewhere near the top: > unlet! skip_defaults_vim source $VIMRUNTIME/defaults.vim Then Vim works like before you had a .vimrc. Copying $VIMRUNTIME/vimrc_example is way to do this. Alternatively, you can copy defaults.vim to your .vimrc and modify it (but then you won’t get updates when it changes).

I guess initially it should be fine to have to use the defaults as instructed in the documentation above. The following two lines are the first lines in my new vimrc file named vimrc.scratch.

unlet! skip_defaults_vim
source $VIMRUNTIME/defaults.vim

One thing to note is when you specify the vimrc using the -u option the $MYVIMRC will not be set so checking the value in command mode will give nothing.

:echo $MYVIMRC

Setting up a new runtimepath

Setting the vimrc doesn’t mean that the runtimepath will not use $HOME/.vim. In order to reconfigure Vim I’ll have to make sure that the runtimepath does not use my current $HOME/.vim directory. I found this solution on the superuser stackexchange The way to check whether your runtimepath is using the original $HOME/.vim is by echoing rtp in command mode:

:echo &rtp

Following the answer from Stackoverflow I change my vim command to the following in order to use the directory ~/play/vim/vim.scratch as the new default runtime path directory

$ vim -u ~/play/vim/vimrc.scratch \
    --cmd 'let &rtp = substitute(&rtp, $HOME."/\.vim", "~/play/vim/vim.scratch", "g")' 

Setting up a new packpath

Additionally Vim automatically looks in $HOME/.vim/pack for packages/plugins that it automatically can load. It adds this to the runtimepath. The way I’ve bypassed this behaviour is to use the same answer as above. In addition to modifying rtp I also modify pp. From the Vim documentaion :h pp

‘packpath’ ‘pp’ string (default: see ‘runtimepath’) Directories used to find packages. See |packages|.

So my vim command now becomes the following as I instruct Vim to change the packpath by substituting $HOME/.vim with ~/play/vim/vim.scratch

$ vim -u ~/play/vim/vimrc.scratch \
    --cmd 'let &rtp = substitute(&rtp, $HOME."/\.vim", "~/play/vim/vim.scratch", "g")' \
    --cmd 'let &pp = substitute(&pp, $HOME."/\.vim", "~/play/vim/vim.scratch", "g")'

Creating a script

In order to simplify invoking the new Vim configuration the above in a bash script and stick it in one of the directories of my $PATH

#!/bin/bash
vim -u ~/play/vim/vimrc.scratch \
    --cmd 'let &rtp = substitute(&rtp, $HOME."/\.vim", "~/play/vim/vim.scratch", "g")' \
    --cmd 'let &pp = substitute(&pp, $HOME."/\.vim", "~/play/vim/vim.scratch", "g")' $@

Automatically Source Vimrc on saving

I found this useful tip on the Vi and Vim stackexchange that basically sources the vimrc on writing it to storage. I initially added this to my vimrc, but it didn’t work :

autocmd BufWritePost .vimrc source %

Since I’m not modifying my original vimrc I need to use my actual file. This works:

autocmd BufWritePost ~/play/vim/vimrc.scratch source %

I noticed that everytime I saved the file with a :w, Vim would get slower. It turns out that it’s important to add the above autocmd within a group name and clear the definitions for that group with autocmd! as indicated in this Stackoverflow post. So I’ve modified my vimscript to create an autocmd group. The autocmd group groups all related autocmd groups and clears previous autocmds associated with the group. In the following example taken from my .vimrc, there is another autocmd to set the foldmethod if the file type belongs to vim.

augroup filetype_vim
    autocmd!
    " This will enable code folding.
    " Use the marker method of folding.
    autocmd FileType vim setlocal foldmethod=marker

    " This will source the vimrc file on saving the buffer
    autocmd BufWritePost ~/.dotfiles/vim.next/.vimrc source %
augroup END

Rebuilding the vimrc

So now with most of the quirks out of the way I set out to rebuild my vimrc using this guide from Freecodecamp. My recommendation is not to use anyone’s configuration unless you can personally communicate with the owner and troubleshoot the issues you’re going to face. In my case I spent time understanding each configuration setting I put into my vimrc file. When I ran into issues I had to backtrack and figure out which options were causing me grief!

When it comes to plugins I’ve included them one by one and spent time understanding how to use the plugin either by going through the documentation of the plugin or looking up tutorials or videos posted online.

The process to rebuild your vimrc is not going to be a quick process. It really depends on how you want to use Vim. Your choice of plugins will be influenced by your primary work flow. Don’t worry about not going with what is popular. Stick to what you understand and what works for you.