2014-05-27 @ 13:05

Manage Your Vim Plugins Using Pathogen and Git Submodules

If you use Vim for your everyday work, then you probably have some vim plugins too. There are tons of plugins out there to make Vim even more productive and enjoyable tool. I'm not going recommend you plugins I use on this place, but I will help you to manage yours.

Vim plugin management includes:

  • adding
  • removing
  • updating
  • installing on other machine
  • storing (in GitHub repository)

Before we start make sure you have Vim installed on your machine. Here is the way to install Vim on Debian based system. Mac users prefers MacVim and windows guys should consider to change their OS trollface or follow this guide.

Install git version control system and create an empty repository on GitHub. Optionally install Ruby for quick&easy installation of your vimfiles on your system.

I lied when I said "I'm not going recommend you plugins I use", because pathogen is must-have plugin for all Vim users! Pathogen allows us to save containing folder of a plugin in ~/.vim/bundle/ path and pathogen will manage the rest. For installation of pathogen follow the instructions in pathogen's repository.

File Structure

We will start by creating following file-structure:

mkdir -p vimfiles/vim vimfiles/vim/bundle vimfiles/vim/autoload
cp ~/.vimrc vimfiles/vimrc # or `touch vimfiles/vimrc`
wget https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim \
  -O vimfiles/autload/pathogen.vim
touch vimfiles/README.markdown

this is what we have so far:

|-- README.markdown
|-- vim
|   |-- autoload
|   `-- bundle
`-- vimrc

Make sure you have following lines in vimfiles/vimrc file:

execute pathogen#infect()
syntax on
filetype plugin indent on

Plugins as a Git Submodules

Now it's time to put our vim-files under version control and add our first plugin as a git submodule. I choosed vim-easymotion, but you can choose whatever plugin you like.

cd vimfiles
git init
git submodule add git@github.com:Lokaltog/vim-easymotion.git vim/bundle/vim-easymotion
git add --all
git commit -m "My awesome vimfiles"
# make sure you have GitHub respository and `git remote` is set
# git remote add origin git@github.com:user_name/vimfiles.git
git push origin -u master

Cool, now we have our vimfiles in remote repository. Let's delete them locally and install again:

cd ..
rm -rf vimfiles
# correct the url to point to you repository
git clone git@github.com:user_name/vimfiles.git
cd vimfiles

Now you may noticed that vimfiles/vim/bundle/vim-easymotion is empty. We have to some more steps to fetch that submodule:

git submodule init
git submodule update

You may also clone your vimfiles with --recursive option and git will do submodule init and submodule update for you:

git clone --recursive git@github.com:user_name/vimfiles.git

Yay! You have now current version of vim-easymotion plugin.

Updating Plugins

Let's now imagine we have added bunch of plugins using the system described above. How do we update them to the current version confused? Easy enough:

git submodule foreach git pull origin master
# if you want git to stfu:
# git submodule -q foreach git pull -q origin master

Very useful, isn't it?!

Remove plugins

You can do following in order to remove a plugin:

git submodule deinit vim/bundle/vim-easymotion
git rm vim/bundle/vim-easymotion
git rm --cached vim/bundle/vim-easymotion

This will work only with git1.8.3 (April 22d, 2013) and above. Please check this thread for more information on removing submodules.

We have now bunch of plugins, but Vim does not lunch them. We need a way to copy or symlink our vimfiles to the right place in our home directory (~/.vimrc and ~/.vim/):

ln -s $PWD/vim ~/.vim
ln -s $PWD/vimrc ~/.vimrc

works quite well in our case, but if you need a general way to install dotfiles into your home directory, then this script may be handy for you:

# Rakefile
require 'rake'

skip_files = %w[

desc "install vim files into user's home directory"
task :install do
  replace_all = false

  Dir['*'].each do |file|
    next if skip_files.include?(file)

    file_path = File.join(ENV['HOME'], ".#{file}")

    if File.exists?(file_path)
      if File.identical?(file, file_path)
        puts("identical #{file_path}")
      elsif replace_all
        replace_file(file, file_path)
        print "overwrite #{file_path}? [ynaq]"
        case $stdin.gets.chomp
        when 'a'
          replace_all = true
          replace_file(file, file_path)
        when 'y'
          replace_file(file, file_path)
        when 'q'
          puts "skipping #{file_path}"
      link_file(file, file_path)

def replace_file(file, file_path)
  system "rm -rf #{file_path}"
  link_file(file, file_path)

def link_file(file, file_path)
  puts "linking #{file_path}"
  system %Q{ln -s "$PWD/#{file}" "#{file_path}"}

You have to install ruby and rake in order to get this to work. Afterwards you can just type rake install and all files|folders in the same directory like Rakefile will be symlinked to your $HOME prefixed with ..

© 2014-05-27, Jiří Chára

Sanpi 2014-05-27 @ 13:52

You can also use git submodules to manage pathogen. Before the infection, add:

source ~/.vim/bundle/pathogen/autoload/pathogen.vim
1 |


Jiri Chara My name is Jiří Chára and I am an addicted JavaScript and Ruby developer. I was born in Plzeň the home of the Pilsner Beer. I currently live in Munich, Germany together with my wife, my daughter and my son. I currently work as a senior front-end engineer at AppDirect.

see more »

Copyright © 2016 Jiří Chára. All Rights Reserved.