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?
- How to use it?
- Organizing packages
- Closing thoughts
- Resources
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/ vundle/ dein / 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.
Top comments (3)
I want to port my current neovim config to lua and I'm planning to use
packer.nvim
. It hasopt
option so I really didn't know what it was for so I'm trying to read more about it.Thanks for this article. It really helped me :D
I'd like to point out that
packadd!
with!
creates more nuances than what you mentioned. I ran into a problem that the ftdetect scripts were not being loaded because I was using the!
option.I'm just writing this for the record, since your article popped up when I was googling my problem :)
shouldn't that code i.e.,
//
if neovim
packadd! neovim-only-package
else
packadd! vim-package
endif
//
be more like :
//
if neovim
packadd neovim-only-package
else
packadd! vim-package
endif
//