Neovim: Install plugins without a plugin manager
2024-07-27 | 3 min read | Leer en españolYes, and all we have to do is download them in the right path.
How does it work?
Neovim and vim have this feature called packages. A package is a directory that can contain multiple plugins.
The file structure of package can look like this:
some-package
├── colors
│ ├── a-colorscheme.vim
│ └── some-colorscheme.lua
├── doc
│ └── my-help-page.txt
├── lua
│ └── some-module
│ └── some-file.lua
└── plugin
├── a-file.vim
└── some-file.lua
According to Neovim's documentation, a plugin is literally a script located in the plugin directory. They call it a "global plugin". So in our example, plugin/a-file.vim
is one plugin and plugin/some-file.lua
is another plugin.
Notice something interesting? This is the same file structure all Neovim plugins can have. So what we consider to be one plugin, Neovim's documentation calls it a package
.
But where should we add these things?
The pack directory
Every directory in the packpath
option can contain a directory called pack
. Inside pack
we can group our packages.
For example:
pack
└── vendor
├── opt
│ └── package-one
└── start
├── package-two
└── package-three
vendor
is just a random name I chose for this group. You can pick any name you want.
Within our group we can have opt
packages and start
packages.
Packages in the start
directory will be available in the runtimepath
during Neovim startup process.
A package in the opt
directory will only be added to the runtimepath
after we call the command :packadd
. This is the way we can lazy load plugins.
The download path
First, inspect the value of the option packpath
. Execute this command in Neovim.
:set packpath?
If you find that unreadable, you can try to print each path using lua. Execute this command.
:lua vim.tbl_map(print, vim.opt.packpath:get())
That's the list of directories where you can have a pack
directory.
Example time:
By default Neovim's configuration directory is a part of the packpath, so that's a perfectly valid place to create a pack
directory.
Let's pretend we are using linux and want to download mini.nvim. We could execute this command the terminal.
git clone https://github.com/echasnovski/mini.nvim \
~/.config/nvim/pack/vendor/start/mini.nvim
Note that after we download a plugin we need to generate the help tags using this command inside Neovim.
:helptags ALL
After we create the help tags we can use the :help
command to navigate to the documentation of the plugin.
Now that mini.nvim
is available in Neovim's runtimepath we can test it. We can try for example the module mini.files
in our Neovim configuration.
Let's create a keyboard shortcut to toggle mini.files
explorer.
local mini_files = require('mini.files')
mini_files.setup({})
vim.keymap.set('n', '<F2>', function()
if mini_files.close() then
return
end
mini_files.open()
end)
A little command
If you want, you can have a Neovim command that uses git clone
to download plugins from github.
This should work just fine:
vim.api.nvim_create_user_command(
'GitPlugin',
function(input)
local repo = input.fargs
local url = 'https://github.com/%s/%s.git'
local plugin_dir = vim.fn.stdpath('config')
.. '/pack/vendor/start/%s'
if repo[1] == nil or repo[2] == nil then
local msg = 'Must provide user name and repository'
vim.notify(msg, vim.log.levels.WARN)
return
end
local full_url = url:format(repo[1], repo[2])
local command = {'git', 'clone', full_url, plugin_dir:format(repo[2])}
local on_done = function()
vim.cmd('packloadall! | helptags ALL')
vim.notify('Done.')
end
vim.notify('Cloning repository...')
vim.fn.jobstart(command, {on_exit = on_done})
end,
{nargs = '+'}
)
Going back to our previous example, now we could download mini.nvim
using this command inside Neovim:
GitPlugin echasnovski mini.nvim
Conclusion
You are ready to enjoy Neovim plugins available on github without a plugin manager.
I want to clarify, I'm not saying plugin managers are useless. You probably still need one. Neovim doesn't have a mechanism to update plugins, or remove them. The package feature only loads plugins into Neovim's runtime. You still need to manage your plugins somehow.
If you have a question you can reach out to me on social media:
- Twitter @VonHeikemen_
- Bluesky @vonheikemen.bsky.social
- Mastodon @vonheikemen@hachyderm.io
Thank you for reading. If you find this article useful and want to support my efforts, buy me a coffee ☕