How to Use Vim Packages

April 13, 2020

Follow @learnvim for more Vim tips and tricks!

Vim 8 has a built-in plugins support using packages (:h packages). This post will show you how to install plugins using packages.

Here are the things I will cover today:

Why is this useful? What problem does it solve?

With packages, you can just drop your package (plugin) in Vim's designated directory (pack/). This makes it easy to update. Many Vim plugins are in Github repo. When they come up with a new version, you only need to go to that directory and git pull latest version. If you want to delete it, just remove that plugin's directory. All our plugins are later added into Vim's runtimepath (rtp).

Prior Vim's package system, if you don't use package manager, there is no buit-in one-stop directory where you can put all your plugins easily.

There are 2 ways to add plugins: automatically and manually. I will show how to add plugins using each methods in the next section.

In short, package is Vim's answer to provide native functionality for users to add 3rd party plugins.

How to use it?

For this demo, I will use NERDTree package. I will show how to add it automatically and manually (make sure you uninstall/ remove NERDTree from your vimrc for now).

Throughout the demo, I am assuming your .vim/ directory is in: ~/.vim.

To use package feature, Vim will look inside pack/ directory inside ~/.vim, like: ~/.vim/pack/.

Automatic loading (start/)

To load plugins automatically when Vim loads, Vim requires you to put your package inside start/ directory, inside a directory, inside pack/ directory (a little confusing at first):

~/.vim/pack/*/start/

* is anything you want to name. It just needs a name. It sounds a little confusing. Be aware that:

~/.vim/pack/start

The above will not work. You need to namespace it with another directory that you can give any name you want. For this demo, let's create one called test:

mkdir -p ~/.vim/pack/test/start

Clone our NERDTree inside:

cd ~/.vim/pack/test/start/
git clone https://github.com/preservim/nerdtree

Now we have:

~/.vim/pack/test/start/nerdtree

...and that's it!

Close and reopen Vim. Let's try calling one of NERDTree's API, ex: :NERDTreeToggle. It should work.

If you remove it:

cd ~/.vim/pack/test/start
rm -rf nerdtree

Close and reopen Vim. Running :NERDTreeToggle throws an error, because we just removed it. Reclone NerdTree and reopen vim. Toggle works again!

Manual Loading (opt/)

To load plugins manually, instead of start/, we need to put our package opt/. Make sure you remove NERDTree again from start/ for this demo:

mkdir -p ~/.vim/pack/test/opt/

Now drop clone it inside opt/:

cd ~/.vim/pack/test/opt/
git clone https://github.com/preservim/nerdtree

Close and reopen vim. :NERDTreeToggle doesn't work yet. We need to manually add it with packadd package-name. Let's do that:

:packadd nerdtree

We use packadd nerdtree because that's what the directory is called. If your directory is called nerdtree2 instead, then you need to run :packadd nerdtree2.

Now close and restart vim. :NERDTreeToggle works.

You need to run packadd everytime you start Vim. If you close and reopen Vim, your package won't be available immediately.

Alternatively, you can also add in your vimrc:

packadd! your-package

The ! is for when you run vim --noplugin so Vim won't add your package.

You may think, "Well this is nice, but why do I ever want to use opt/? Why can't I put all my packages inside start/? It's much more convenient."

Using opt/ allows you to conditionally load your packages, for example:

if neovim
  packadd! neovim-only-package
else
  packadd! vim-package
endif

" or

if fast-machine
  packadd! fancy-plugin
else
  packadd! slower-plugin
endif
# Organizing packages Let's talk about the `*` in `~/.vim/pack/*/start/` and `~/.vim/pack/*/opt/`. You can use this freedom to organize your packages, for example:
~/.vim/pack/colors
~/.vim/pack/syntax
~/.vim/pack/objects
~/.vim/pack/plugins

Whereas:

  • colors = theme related
  • syntax = linters, syntax, compilers related
  • objects = custom text objects
  • plugins = miscellaneous plugins

How you organize your packages is up to you. You can just have one directory to handle them all, like:

~/.vim/pack/myplugins
# Closing thoughts With the advent of package feature, users can now install plugins without plugin managers. Some may ask, "Do I need this? I am already using [pathogen](https://github.com/tpope/vim-pathogen)/ [vundle](https://github.com/VundleVim/Vundle.vim)/ [dein](https://github.com/Shougo/dein.vim) / [vim-plug](https://github.com/junegunn/vim-plug)".

It depends.

Not all plugin managers are equal. Check what features your plugin managers have. For example, vim-plug has :PlugUpdate where it checks for all plugin updates and :PlugClean to remove all unlisted plugins. With package, you have to update and remove them manually. Some plugin manager handles async execution, some doesn't.

In terms of speed, I don't think there are significant differences.

In my opinion, if you're a minimalist and don't use a lot of plugins, package is for you. It is built-in and therefore less dependencies. If you use a lot of plugins, you may consider sticking with a popular package manager.

# Resources - `:h packages` - [What is the Vim8 package feature and how should I use it?](https://vi.stackexchange.com/questions/9522/what-is-the-vim8-package-feature-and-how-should-i-use-it) - [Vim 8 - Any reason to use the build-in package support?](https://www.reddit.com/r/vim/comments/6x64oh/vim_8_any_reason_to_use_the_buildin_package/)
© Copyright 2021 Igor Irianto