Creating portable Vim environment
2014. 10. 22.

As you might have guessed, I use a heavily customized Vim. My .vimrc as of now contains over 1,400 lines of custom mappings, settings, functions and commands that were accumulated over the years. I also have 46 plugins installed, some of which tremendously boost my editing performance. And sure, I'm proud of this delicately crafted environment of mine.

However, the obvious side-effect is that I've become very dependent upon this particular environment and my productivity plummets on vanilla Vim without my favorite plugins and key bindings. And that's why I have dotfiles repository on GitHub so I can download it from any machine. Unfortunately, having my .vimrc on GitHub turned out to be not enough at all.

At work, I log on to several service accounts on dozens of servers that are shared among other developers. The main problem is that those servers do not have direct access to internet, making it impossible to download my Vim configuration and plugins from GitHub without setting up a proxy server. Even worse is that some of those servers are running very old versions of Linux distribution and do not even have Git installed.

So in order to set up my Vim usual environment on such a server I have to:

  1. Set up an HTTP proxy so I can access GitHub
  2. Download, compile, and install Git
  3. Backup current Vim configuration as I'm logged on to a shared account
  4. Download .vimrc from dotfiles repository
  5. Install plugins for GitHub. With 46 plugins, this takes considerable amount of time. Parallel installer of vim-plug does not help, since those servers usually do not have Vim with Ruby support, not to mention Neovim.
  6. Finally, do the real work
  7. I don't want to impose my personal preferences on others. So I remove my .vimrc and .vim, and restore the previous configuration.

That's obviously not the best way to do my job. There must be/should be a better way. I want to set up my Vim environment without GitHub, without Git, and without having to wait while plugins are being downloaded, and the environment should be temporary and cleaned up automatically when I exit Vim.

With these requirements, I wrote a small script called myvim. myvim is a small bash script that creates a tarball of the snapshot of your Vim environment and attaches it to an executable bash script that temporarily swaps ~/.vim directory while running Vim with the attached environment.

To use it, you may download the script and run it, or simply execute it via curl as follows:

bash <(curl -L

The command will generate an executable named vim.$(whoami) that contains your .vimrc and .vim directory. Now you have a portable bundle of your Vim environment you can easily bring around. Put it on an FTP server or on a Web server which all your servers have access to. Setting up your Vim environment reduces to a one-liner like so:

# Download myvim bundle from FTP
ftp -n < <(echo -e 'user jg\nget ~/vim.jg') && chmod +x vim.jg

# Start your Vim

However, there are a couple of issues that arise due to the temporary swap of ~/.vim directory:

  1. The other Vim processes running at the moment on the same account can be affected as well
  2. If you abort the process, the script will not able to clean up the environment

It would be ideal if we could avoid swapping the directory, but most Vim configurations in the wild are not written in a portable way and directly refer to the directory, so there was no other way. But I'd love to hear about better approaches.

It's been only a few days since I started using myvim, but this simple script has worked great for me. Try it and let me know what you think about it.

Updates (January 2015)

Swapping ~/.vim directory has caused some headaches as expected. So I came up with an idea to simply swap $HOME variable instead by injecting some code to the vimrc, and it has turned out to work well without any known side effects.

The new version also takes --edit option, which allows you to prepend some environment variables to be applied and to edit the list of files to be archived.

» capture | close