migrating to neovim's new built-in plugin manager

· erock's devlog


A couple of weeks ago neovim merged a built-in plugin manager.

This is very exciting for me in my journey to create a high value yet minimal config. High value in this context is the perfect strike point between the smallest config file I can create while preserving many of the IDE-like features that modern SWEs use to be productive.

Here is my config

One side-effect of having a minimal config is it's easy to make major changes to it since it's only ~200 lines of code.

vim.pack is still a work-in-progress but I was too excited to not try it out.

I'm coming from lazy.nvim which works great and I don't really have any complaints beyond my ascetic desire to have as few dependencies as possible. Before migrating to vim.pack my config had 230 LoC.

Alright, first we register all of our plugins:

 1vim.pack.add({
 2  "https://github.com/nvim-lua/plenary.nvim",
 3  "https://github.com/Mofiqul/dracula.nvim",
 4  { src = "https://github.com/nvim-treesitter/nvim-treesitter", version = 'main' },
 5  "https://github.com/nvim-treesitter/nvim-treesitter-context",
 6  "https://github.com/neovim/nvim-lspconfig",
 7  "https://github.com/ibhagwan/fzf-lua",
 8  "https://github.com/karb94/neoscroll.nvim",
 9  "https://github.com/ruifm/gitlinker.nvim",
10  "https://github.com/tpope/vim-fugitive",
11})

The main difference between lazy.nvim and vim.pack is how plugins are loaded. With vim.pack there is no lazy loading. For my setup it's actually preferred to simply load all of my plugins because there's only 9 and I'm not really getting much value out of lazy loading.

Now we need to run .setup on the plugins that require it. First we start with color scheme:

1require("dracula").setup({})
2vim.cmd[[colorscheme dracula]]

Then we run treesitter:

 1local ts_parsers = {
 2  "bash",
 3  "c",
 4  "dockerfile",
 5  "fish",
 6  "git_config",
 7  "git_rebase",
 8  "gitattributes",
 9  "gitcommit",
10  "gitignore",
11  "go",
12  "gomod",
13  "gosum",
14  "html",
15  "javascript",
16  "json",
17  "lua",
18  "make",
19  "markdown",
20  "python",
21  "rust",
22  "sql",
23  "toml",
24  "tsx",
25  "typescript",
26  "typst",
27  "vim",
28  "yaml",
29  "zig",
30}
31local nts = require("nvim-treesitter")
32nts.install(ts_parsers)
33autocmd('PackChanged', { callback = function() nts.update() end })

PackChanged is a new autocmd from vim.pack that will trigger whenever there's an install on disk, update, or delete. I'll eventually tweak this to only run treesitter update when there's a change to that specific plugin. But for now, this seems okay. I also haven't tested this callback to know it is doing the right thing. If anyone has any tips on how to test it, lemme know!

Then we setup our LSP, fzf-lua, and the rest of my plugins:

 1setup_lsp()
 2setup_fzf()
 3require("treesitter-context").setup({
 4  max_lines = 3,
 5  multiline_threshold = 1,
 6  separator = '-',
 7  min_window_height = 20,
 8  line_numbers = true,
 9})
10require("neoscroll").setup({ duration_multiplier = 0.4 })
11require("gitlinker").setup({})

The final thing is to add an autocmd to enable treesitter highlighting and indents:

 1autocmd("FileType", { -- enable treesitter highlighting and indents
 2  callback = function(args)
 3    local filetype = args.match
 4    local lang = vim.treesitter.language.get_lang(filetype)
 5    if vim.treesitter.language.add(lang) then
 6      vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
 7      vim.treesitter.start()
 8    end
 9  end
10})

And that's it! The only real issue I ran into was treesitter where I needed to "uninstall" lazy to remove all the parsers and queries it installed.

It really was pretty simple. However, the main reason why it was simple for me to convert to vim.pack so easily is because of my high value lua config.

After I converted to vim.pack my total line count went to 197, nice!

In my next post I'll breakdown my nvim config and show a demo of what I'm able to do with it.

last updated:

I have no idea what I'm doing. Subscribe to my rss feed to read more posts.