Hey there! You’re reading Mastering Neovim, a newsletter that should probably be called Configuring Neovim, because that’s mostly what we’re talking about.
I’ve got my current configuration up on Github. I’m basically rebuilding the whole thing from scratch — starting from almost nothing, and then adding in pieces as I decide I want a particular capability. (Often I’m borrowing things I find useful while pairing with coworkers in IntelliJ.) Then I write about those changes here — basically my workflow is to look through my git history, find something that looks worth sharing, and then write it up for you here.
I’ve been writing a lot of Elm at work, and one of the nice things about it is the consistent formatting, enforced by elm-format.
Every so often I forget to run it before pushing and then I have to make a silly formatting-only commit. So I wanted to configure Neovim to format whenever I save.
To do this I used this autocommand:
vim.api.nvim_create_autocmd('BufWritePre', {
buffer = vim.fn.bufnr(),
callback = function()
vim.lsp.buf.format({ timeout_ms = 3000 })
end,
})
Autocommand’s are Vim’s mechanism for running arbitrary commands (or, in Neovim, Lua functions) in response to events.
Vim exposes a bunch of different events. The BufWritePre
event means “before writing a buffer to the file.” So whenever we save, the registered function will run before we make any other changes to the file we’re writing to. (You might also be able to do this with BufWrite
or FileWritePre
.)
There nvim_create_autocmd
function takes an event and a table of parameters defining what to do in response to that event. One of those parameters will be either command
(for a Vim command) or callback
(for a Lua function.) In this case I’m using a callback. I’ve also passed buffer
because BufWritePre
needs a buffer to act on. I’m using bufnr
to get the current buffer I’m working with.
The really nice part of this is vim.lsp.buf.format({ timeout_ms = 3000 })
which calls the LSP command to run whatever formatter the current LSP provides. (The “timeout” part cuts off the formatter if it takes more than 3 seconds to run.) So now this works for every language that I’ve set up an LSP for.
And as always — if anything I’ve written here isn’t write, you know a better way to do the same thing, or you have a question about anything I’ve written, let me know. You can leave a comment on Substack or send me an e-mail. Any feedback you have is super valuable and I always appreciate you taking the time to share it.