diff --git a/lua/lazyvim/plugins/lsp/format.lua b/lua/lazyvim/plugins/lsp/format.lua index d8af70ab..556a1214 100644 --- a/lua/lazyvim/plugins/lsp/format.lua +++ b/lua/lazyvim/plugins/lsp/format.lua @@ -2,16 +2,17 @@ local Util = require("lazy.core.util") local M = {} -M.autoformat = true +---@type PluginLspOpts +M.opts = nil function M.toggle() if vim.b.autoformat == false then vim.b.autoformat = nil - M.autoformat = true + M.opts.autoformat = true else - M.autoformat = not M.autoformat + M.opts.autoformat = not M.opts.autoformat end - if M.autoformat then + if M.opts.autoformat then Util.info("Enabled format on save", { title = "Format" }) else 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 return end - local ft = vim.bo[buf].filetype - local have_nls = package.loaded["null-ls"] - and (#require("null-ls.sources").get_available(ft, "NULL_LS_FORMATTING") > 0) + + local formatters = M.get_formatters(buf) + 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", { bufnr = buf, filter = function(client) - if have_nls then - return client.name == "null-ls" - end - return client.name ~= "null-ls" + return vim.tbl_contains(client_ids, client.id) end, }, require("lazyvim.util").opts("nvim-lspconfig").format or {})) 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 client.config and client.config.capabilities and client.config.capabilities.documentFormattingProvider == false then - return + return false end + return client.supports_method("textDocument/formatting") or client.supports_method("textDocument/rangeFormatting") +end - if client.supports_method("textDocument/formatting") then - vim.api.nvim_create_autocmd("BufWritePre", { - group = vim.api.nvim_create_augroup("LspFormat." .. buf, {}), - buffer = buf, - callback = function() - if M.autoformat then - M.format() - end - end, - }) - end +---@param opts PluginLspOpts +function M.setup(opts) + M.opts = opts + vim.api.nvim_create_autocmd("BufWritePre", { + group = vim.api.nvim_create_augroup("LazyVimFormat", {}), + callback = function() + if M.opts.autoformat then + M.format() + end + end, + }) end return M diff --git a/lua/lazyvim/plugins/lsp/init.lua b/lua/lazyvim/plugins/lsp/init.lua index 26af19f1..188c8be0 100644 --- a/lua/lazyvim/plugins/lsp/init.lua +++ b/lua/lazyvim/plugins/lsp/init.lua @@ -77,10 +77,9 @@ return { config = function(_, opts) local Util = require("lazyvim.util") -- setup autoformat - require("lazyvim.plugins.lsp.format").autoformat = opts.autoformat + require("lazyvim.plugins.lsp.format").setup(opts) -- setup formatting and keymaps Util.on_attach(function(client, buffer) - require("lazyvim.plugins.lsp.format").on_attach(client, buffer) require("lazyvim.plugins.lsp.keymaps").on_attach(client, buffer) end)