Files
LazyVim/lua/lazyvim/util/lsp.lua
Iordanis Petkakis 03f1293e33 fix(util.lsp): pass formatters_by_ft to opts (#6894)
## Description
Here
c64a61734f/lua/lazyvim/util/lsp.lua (L50)
we call directly `conform.format` with our specific options.

`conform.nvim` also allows passing options such as `lsp_format` directly
to `formatter_by_ft` as also can be seen
[here](5420c4b5ea/doc/conform.txt (L20-L21)).
Those options are not passed when we call `conform.format(opts)` in the
LSP formatter.

So, we add these options. Also, fix the correct name for general format
options, since it had been changed at some time in `conform.nvim` and
that change made it to the plugin spec, but not here.
<!-- Describe the big picture of your changes to communicate to the
maintainers
  why we should accept this pull request. -->

## Related Issue(s)
Fixes #6893
<!--
  If this PR fixes any issues, please link to the issue here.
  - Fixes #<issue_number>
-->

## Screenshots

<!-- Add screenshots of the changes if applicable. -->

## Checklist

- [x] I've read the
[CONTRIBUTING](https://github.com/LazyVim/LazyVim/blob/main/CONTRIBUTING.md)
guidelines.
2026-03-01 10:12:58 +01:00

97 lines
2.8 KiB
Lua

---@class lazyvim.util.lsp
local M = {}
---@param opts? LazyFormatter| {filter?: (string|vim.lsp.get_clients.Filter)}
function M.formatter(opts)
opts = opts or {}
local filter = opts.filter or {}
filter = type(filter) == "string" and { name = filter } or filter
---@cast filter vim.lsp.get_clients.Filter
---@type LazyFormatter
local ret = {
name = "LSP",
primary = true,
priority = 1,
format = function(buf)
M.format(LazyVim.merge({}, filter, { bufnr = buf }))
end,
sources = function(buf)
local clients = vim.lsp.get_clients(LazyVim.merge({}, filter, { bufnr = buf }))
---@param client vim.lsp.Client
local ret = vim.tbl_filter(function(client)
return client:supports_method("textDocument/formatting")
or client:supports_method("textDocument/rangeFormatting")
end, clients)
---@param client vim.lsp.Client
return vim.tbl_map(function(client)
return client.name
end, ret)
end,
}
return LazyVim.merge(ret, opts) --[[@as LazyFormatter]]
end
---@alias lsp.Client.format {timeout_ms?: number, format_options?: table} | vim.lsp.get_clients.Filter
---@param opts? lsp.Client.format
function M.format(opts)
opts = vim.tbl_deep_extend("force", {}, opts or {}, LazyVim.opts("nvim-lspconfig").format or {})
local ok, conform = pcall(require, "conform")
-- use conform for formatting with LSP when available,
-- since it has better format diffing
if ok then
-- It should be `nil`, otherwise it doesn't fetch options from `formatters_by_ft`,
-- see https://github.com/stevearc/conform.nvim/blob/5420c4b5ea0aeb99c09cfbd4fd0b70d257b44f25/lua/conform/init.lua#L417-L418
opts.formatters = nil
conform.format(opts)
else
vim.lsp.buf.format(opts)
end
end
M.action = setmetatable({}, {
__index = function(_, action)
return function()
vim.lsp.buf.code_action({
apply = true,
context = {
only = { action },
diagnostics = {},
},
})
end
end,
})
---@class LspCommand: lsp.ExecuteCommandParams
---@field open? boolean
---@field handler? lsp.Handler
---@field filter? string|vim.lsp.get_clients.Filter
---@field title? string
---@param opts LspCommand
function M.execute(opts)
local filter = opts.filter or {}
filter = type(filter) == "string" and { name = filter } or filter
local buf = vim.api.nvim_get_current_buf()
---@cast filter vim.lsp.get_clients.Filter
local client = vim.lsp.get_clients(LazyVim.merge({}, filter, { bufnr = buf }))[1]
local params = {
command = opts.command,
arguments = opts.arguments,
}
if opts.open then
require("trouble").open({
mode = "lsp_command",
params = params,
})
else
vim.list_extend(params, { title = opts.title })
return client:exec_cmd(params, { bufnr = buf }, opts.handler)
end
end
return M