Files
LazyVim/lua/lazyvim/plugins/lsp/format.lua
2023-06-08 07:48:34 +02:00

153 lines
3.8 KiB
Lua

local Util = require("lazy.core.util")
local M = {}
---@type PluginLspOpts
M.opts = nil
function M.enabled()
return M.opts.autoformat
end
function M.toggle()
if vim.b.autoformat == false then
vim.b.autoformat = nil
M.opts.autoformat = true
else
M.opts.autoformat = not M.opts.autoformat
end
if M.opts.autoformat then
Util.info("Enabled format on save", { title = "Format" })
else
Util.warn("Disabled format on save", { title = "Format" })
end
end
---@param opts? {force?:boolean}
function M.format(opts)
local buf = vim.api.nvim_get_current_buf()
if vim.b.autoformat == false and not (opts and opts.force) then
return
end
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)
return vim.tbl_contains(client_ids, client.id)
end,
}, require("lazyvim.util").opts("nvim-lspconfig").format or {}))
end
---@param formatters LazyVimFormatters
function M.notify(formatters)
local lines = { "# Active:" }
for _, client in ipairs(formatters.active) do
local line = "- **" .. client.name .. "**"
if client.name == "null-ls" then
line = line
.. " ("
.. table.concat(
vim.tbl_map(function(f)
return "`" .. f.name .. "`"
end, formatters.null_ls),
", "
)
.. ")"
end
table.insert(lines, line)
end
if #formatters.available > 0 then
table.insert(lines, "")
table.insert(lines, "# Disabled:")
for _, client in ipairs(formatters.available) do
table.insert(lines, "- **" .. client.name .. "**")
end
end
vim.notify(table.concat(lines, "\n"), vim.log.levels.INFO, {
title = "Formatting",
on_open = function(win)
vim.api.nvim_win_set_option(win, "conceallevel", 3)
vim.api.nvim_win_set_option(win, "spell", false)
local buf = vim.api.nvim_win_get_buf(win)
vim.treesitter.start(buf, "markdown")
end,
})
end
-- 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 false
end
return client.supports_method("textDocument/formatting") or client.supports_method("textDocument/rangeFormatting")
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