-
Notifications
You must be signed in to change notification settings - Fork 785
Formatting on save
This is the most reliable way to format on save, since it blocks Neovim until results are applied (or the source times out).
require("null-ls").setup({
-- you can reuse a shared lspconfig on_attach callback here
on_attach = function(client)
if client.resolved_capabilities.document_formatting then
vim.cmd([[
augroup LspFormatting
autocmd! * <buffer>
autocmd BufWritePre <buffer> lua vim.lsp.buf.formatting_sync()
augroup END
]])
end
end,
})
Async formatting works by sending a formatting request, then applying and writing results once they're received. This lets you move the cursor, scroll, and otherwise interact with the window while waiting for results, which can make formatting seem more responsive (but doesn't actually speed it up).
The async formatting implementation here comes with the following caveats:
-
If you edit the buffer in between sending a request and receiving results, those results won't be applied.
-
Each save will result in writing the file to the disk twice.
-
:wq
will not format the file before quitting.
The most reliable way to format files on save is to use a sync formatting method, as described above.
NOTE: This snippet is not part of null-ls. If it doesn't work for you, please open a discussion (not an issue). If you want to solve a bug or improve its behavior, feel free to edit this page.
_G.formatting = function(bufnr)
bufnr = tonumber(bufnr) or vim.api.nvim_get_current_buf()
vim.lsp.buf_request(
bufnr,
"textDocument/formatting",
{ textDocument = { uri = vim.uri_from_bufnr(bufnr) } },
function(err, res)
if err then
local err_msg = type(err) == "string" and err or err.message
-- you can modify the log message / level (or ignore it completely)
vim.notify("formatting: " .. err_msg, vim.log.levels.WARN)
return
end
-- don't apply results if buffer is unloaded or has been modified
if not vim.api.nvim_buf_is_loaded(bufnr) or vim.api.nvim_buf_get_option(bufnr, "modified") then
return
end
if res then
vim.lsp.util.apply_text_edits(res, bufnr)
vim.api.nvim_buf_call(bufnr, function()
vim.cmd("silent noautocmd update")
end)
end
end
)
end
local null_ls = require("null-ls")
null_ls.setup({
-- add your sources / config options here
sources = ...,
on_attach = function(client, bufnr)
if client.supports_method("textDocument/formatting") then
-- wrap in an augroup to prevent duplicate autocmds
vim.cmd([[
augroup LspFormatting
autocmd! * <buffer>
autocmd BufWritePost <buffer> lua formatting(vim.fn.expand("<abuf>"))
augroup END
]])
end
end,
})