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.
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.