feat(lsp): added support for upcoming dynamic registration of formatters

This commit is contained in:
Folke Lemaitre
2023-05-26 10:50:16 +02:00
parent e990d23cfe
commit 962fc6bab4
2 changed files with 71 additions and 27 deletions

View File

@ -2,16 +2,17 @@ local Util = require("lazy.core.util")
local M = {} local M = {}
M.autoformat = true ---@type PluginLspOpts
M.opts = nil
function M.toggle() function M.toggle()
if vim.b.autoformat == false then if vim.b.autoformat == false then
vim.b.autoformat = nil vim.b.autoformat = nil
M.autoformat = true M.opts.autoformat = true
else else
M.autoformat = not M.autoformat M.opts.autoformat = not M.opts.autoformat
end end
if M.autoformat then if M.opts.autoformat then
Util.info("Enabled format on save", { title = "Format" }) Util.info("Enabled format on save", { title = "Format" })
else else
Util.warn("Disabled format on save", { title = "Format" }) Util.warn("Disabled format on save", { title = "Format" })
@ -24,42 +25,86 @@ function M.format(opts)
if vim.b.autoformat == false and not (opts and opts.force) then if vim.b.autoformat == false and not (opts and opts.force) then
return return
end end
local ft = vim.bo[buf].filetype
local have_nls = package.loaded["null-ls"] local formatters = M.get_formatters(buf)
and (#require("null-ls.sources").get_available(ft, "NULL_LS_FORMATTING") > 0) local client_ids = vim.tbl_map(function(client)
return client.id
end, formatters.active)
if #client_ids == 0 then
return
end
if M.opts.format_notify then
M.notify(formatters)
end
vim.lsp.buf.format(vim.tbl_deep_extend("force", { vim.lsp.buf.format(vim.tbl_deep_extend("force", {
bufnr = buf, bufnr = buf,
filter = function(client) filter = function(client)
if have_nls then return vim.tbl_contains(client_ids, client.id)
return client.name == "null-ls"
end
return client.name ~= "null-ls"
end, end,
}, require("lazyvim.util").opts("nvim-lspconfig").format or {})) }, require("lazyvim.util").opts("nvim-lspconfig").format or {}))
end end
function M.on_attach(client, buf)
-- dont format if client disabled it -- Gets all lsp clients that support formatting.
-- When a null-ls formatter is available for the current filetype,
-- only null-ls formatters are returned.
function M.get_formatters(bufnr)
local ft = vim.bo[bufnr].filetype
-- check if we have any null-ls formatters for the current filetype
local null_ls = package.loaded["null-ls"] and require("null-ls.sources").get_available(ft, "NULL_LS_FORMATTING") or {}
---@class LazyVimFormatters
local ret = {
---@type lsp.Client[]
active = {},
---@type lsp.Client[]
available = {},
null_ls = null_ls,
}
---@type lsp.Client[]
local clients = vim.lsp.get_active_clients({ bufnr = bufnr })
for _, client in ipairs(clients) do
if M.supports_format(client) then
if (#null_ls > 0 and client.name == "null-ls") or #null_ls == 0 then
table.insert(ret.active, client)
else
table.insert(ret.available, client)
end
end
end
return ret
end
-- Gets all lsp clients that support formatting
-- and have not disabled it in their client config
---@param client lsp.Client
function M.supports_format(client)
if if
client.config client.config
and client.config.capabilities and client.config.capabilities
and client.config.capabilities.documentFormattingProvider == false and client.config.capabilities.documentFormattingProvider == false
then then
return return false
end end
return client.supports_method("textDocument/formatting") or client.supports_method("textDocument/rangeFormatting")
end
if client.supports_method("textDocument/formatting") then ---@param opts PluginLspOpts
vim.api.nvim_create_autocmd("BufWritePre", { function M.setup(opts)
group = vim.api.nvim_create_augroup("LspFormat." .. buf, {}), M.opts = opts
buffer = buf, vim.api.nvim_create_autocmd("BufWritePre", {
callback = function() group = vim.api.nvim_create_augroup("LazyVimFormat", {}),
if M.autoformat then callback = function()
M.format() if M.opts.autoformat then
end M.format()
end, end
}) end,
end })
end end
return M return M

View File

@ -77,10 +77,9 @@ return {
config = function(_, opts) config = function(_, opts)
local Util = require("lazyvim.util") local Util = require("lazyvim.util")
-- setup autoformat -- setup autoformat
require("lazyvim.plugins.lsp.format").autoformat = opts.autoformat require("lazyvim.plugins.lsp.format").setup(opts)
-- setup formatting and keymaps -- setup formatting and keymaps
Util.on_attach(function(client, buffer) Util.on_attach(function(client, buffer)
require("lazyvim.plugins.lsp.format").on_attach(client, buffer)
require("lazyvim.plugins.lsp.keymaps").on_attach(client, buffer) require("lazyvim.plugins.lsp.keymaps").on_attach(client, buffer)
end) end)