diff options
Diffstat (limited to 'lua')
-rw-r--r-- | lua/conform/health.lua | 92 | ||||
-rw-r--r-- | lua/conform/init.lua | 130 |
2 files changed, 139 insertions, 83 deletions
diff --git a/lua/conform/health.lua b/lua/conform/health.lua index d36ef03..18085bf 100644 --- a/lua/conform/health.lua +++ b/lua/conform/health.lua @@ -6,11 +6,24 @@ local function get_formatter_filetypes(name) local conform = require("conform") local filetypes = {} for filetype, formatters in pairs(conform.formatters_by_ft) do + -- support the old structure where formatters could be a subkey if not vim.tbl_islist(formatters) then + ---@diagnostic disable-next-line: undefined-field formatters = formatters.formatters end - if vim.tbl_contains(formatters, name) then - table.insert(filetypes, filetype) + + for _, ft_name in ipairs(formatters) do + if type(ft_name) == "string" then + if ft_name == name then + table.insert(filetypes, filetype) + break + end + else + if vim.tbl_contains(ft_name, name) then + table.insert(filetypes, filetype) + break + end + end end end return filetypes @@ -38,6 +51,22 @@ M.check = function() end end +---@param formatters conform.FormatterUnit[] +---@return string[] +local function flatten_formatters(formatters) + local flat = {} + for _, name in ipairs(formatters) do + if type(name) == "string" then + table.insert(flat, name) + else + for _, f in ipairs(flatten_formatters(name)) do + table.insert(flat, f) + end + end + end + return flat +end + M.show_window = function() local conform = require("conform") local lines = {} @@ -60,35 +89,43 @@ M.show_window = function() end table.insert(lines, "") - ---@param formatters conform.FormatterInfo[] + ---@param formatter conform.FormatterInfo + local function append_formatter_info(formatter) + if not formatter.available then + local line = string.format("%s unavailable: %s", formatter.name, formatter.available_msg) + table.insert(lines, line) + table.insert( + highlights, + { "DiagnosticWarn", #lines, formatter.name:len(), formatter.name:len() + 12 } + ) + else + local filetypes = get_formatter_filetypes(formatter.name) + local line = string.format("%s ready (%s)", formatter.name, table.concat(filetypes, ", ")) + table.insert(lines, line) + table.insert( + highlights, + { "DiagnosticInfo", #lines, formatter.name:len(), formatter.name:len() + 6 } + ) + end + end + + local seen = {} + ---@param formatters string[] local function append_formatters(formatters) - for _, formatter in ipairs(formatters) do - if not formatter.available then - local line = string.format("%s unavailable: %s", formatter.name, formatter.available_msg) - table.insert(lines, line) - table.insert( - highlights, - { "DiagnosticWarn", #lines, formatter.name:len(), formatter.name:len() + 12 } - ) + for _, name in ipairs(formatters) do + if type(name) == "table" then + append_formatters(name) else - local filetypes = get_formatter_filetypes(formatter.name) - local line = string.format("%s ready (%s)", formatter.name, table.concat(filetypes, ", ")) - table.insert(lines, line) - table.insert( - highlights, - { "DiagnosticInfo", #lines, formatter.name:len(), formatter.name:len() + 6 } - ) + seen[name] = true + local formatter = conform.get_formatter_info(name) + append_formatter_info(formatter) end end end table.insert(lines, "Formatters for this buffer:") table.insert(highlights, { "Title", #lines, 0, -1 }) - local seen = {} - local buf_formatters = conform.list_formatters_for_buffer() - for _, formatter in ipairs(buf_formatters) do - seen[formatter.name] = true - end + local buf_formatters = flatten_formatters(conform.list_formatters_for_buffer()) append_formatters(buf_formatters) if vim.tbl_isempty(buf_formatters) then table.insert(lines, "<none>") @@ -97,10 +134,11 @@ M.show_window = function() table.insert(lines, "") table.insert(lines, "Other formatters:") table.insert(highlights, { "Title", #lines, 0, -1 }) - local all_formatters = vim.tbl_filter(function(f) - return not seen[f.name] - end, conform.list_all_formatters()) - append_formatters(all_formatters) + for _, formatter in ipairs(conform.list_all_formatters()) do + if not seen[formatter.name] then + append_formatter_info(formatter) + end + end local bufnr = vim.api.nvim_create_buf(false, true) local winid = vim.api.nvim_open_win(bufnr, true, { diff --git a/lua/conform/init.lua b/lua/conform/init.lua index ef6f94a..2761b45 100644 --- a/lua/conform/init.lua +++ b/lua/conform/init.lua @@ -99,7 +99,7 @@ end ---@private ---@param bufnr? integer ----@return conform.FormatterInfo[] +---@return conform.FormatterUnit[] M.list_formatters_for_buffer = function(bufnr) if not bufnr or bufnr == 0 then bufnr = vim.api.nvim_get_current_buf() @@ -107,8 +107,25 @@ M.list_formatters_for_buffer = function(bufnr) local formatters = {} local seen = {} local filetypes = vim.split(vim.bo[bufnr].filetype, ".", { plain = true }) + + local function dedupe_formatters(names, collect) + for _, name in ipairs(names) do + if type(name) == "table" then + local alternation = {} + dedupe_formatters(name, alternation) + if not vim.tbl_isempty(alternation) then + table.insert(collect, alternation) + end + elseif not seen[name] then + table.insert(collect, name) + seen[name] = true + end + end + end + table.insert(filetypes, "*") for _, filetype in ipairs(filetypes) do + ---@type conform.FormatterUnit[] local ft_formatters = M.formatters_by_ft[filetype] if ft_formatters then -- support the old structure where formatters could be a subkey @@ -117,35 +134,11 @@ M.list_formatters_for_buffer = function(bufnr) ft_formatters = ft_formatters.formatters end - for _, formatter in ipairs(ft_formatters) do - if not seen[formatter] then - table.insert(formatters, formatter) - seen[formatter] = true - end - end + dedupe_formatters(ft_formatters, formatters) end end - ---@type conform.FormatterInfo[] - local all_info = vim.tbl_map(function(f) - return M.get_formatter_info(f, bufnr) - end, formatters) - - return all_info -end - ----@param formatters conform.FormatterInfo[] ----@return conform.FormatterInfo[] -local function filter_formatters(formatters) - ---@type conform.FormatterInfo[] - local all_info = {} - for _, info in ipairs(formatters) do - if info.available then - table.insert(all_info, info) - end - end - - return all_info + return formatters end ---@param bufnr integer @@ -179,6 +172,41 @@ local function range_from_selection(bufnr, mode) } end +---@param names conform.FormatterUnit[] +---@param bufnr integer +---@param warn_on_missing boolean +---@return conform.FormatterInfo[] +local function resolve_formatters(names, bufnr, warn_on_missing) + local all_info = {} + local function add_info(info, warn) + if info.available then + table.insert(all_info, info) + elseif warn then + vim.notify( + string.format("Formatter '%s' unavailable: %s", info.name, info.available_msg), + vim.log.levels.WARN + ) + end + return info.available + end + + for _, name in ipairs(names) do + if type(name) == "string" then + local info = M.get_formatter_info(name, bufnr) + add_info(info, warn_on_missing) + else + -- If this is an alternation, take the first one that's available + for i, v in ipairs(name) do + local info = M.get_formatter_info(v, bufnr) + if add_info(info, i == #name) then + break + end + end + end + end + return all_info +end + ---Format a buffer ---@param opts? table --- timeout_ms nil|integer Time in milliseconds to block for formatting. Defaults to 1000. No effect if async = true. @@ -204,34 +232,15 @@ M.format = function(opts, callback) local lsp_format = require("conform.lsp_format") local runner = require("conform.runner") - local formatters = {} - local any_formatters_configured - if opts.formatters then - any_formatters_configured = true - for _, formatter in ipairs(opts.formatters) do - local info = M.get_formatter_info(formatter) - if info.available then - table.insert(formatters, info) - else - if opts.quiet then - log.warn("Formatter '%s' unavailable: %s", info.name, info.available_msg) - else - vim.notify( - string.format("Formatter '%s' unavailable: %s", info.name, info.available_msg), - vim.log.levels.WARN - ) - end - end - end - else - formatters = M.list_formatters_for_buffer(opts.bufnr) - any_formatters_configured = not vim.tbl_isempty(formatters) - formatters = filter_formatters(formatters) - end - local formatter_names = vim.tbl_map(function(f) + local formatter_names = opts.formatters or M.list_formatters_for_buffer(opts.bufnr) + local any_formatters_configured = formatter_names ~= nil and not vim.tbl_isempty(formatter_names) + local formatters = + resolve_formatters(formatter_names, opts.bufnr, not opts.quiet and opts.formatters ~= nil) + + local resolved_names = vim.tbl_map(function(f) return f.name end, formatters) - log.debug("Running formatters on %s: %s", vim.api.nvim_buf_get_name(opts.bufnr), formatter_names) + log.debug("Running formatters on %s: %s", vim.api.nvim_buf_get_name(opts.bufnr), resolved_names) local any_formatters = not vim.tbl_isempty(formatters) if any_formatters then @@ -287,8 +296,11 @@ end ---@param bufnr? integer ---@return conform.FormatterInfo[] M.list_formatters = function(bufnr) + if not bufnr or bufnr == 0 then + bufnr = vim.api.nvim_get_current_buf() + end local formatters = M.list_formatters_for_buffer(bufnr) - return filter_formatters(formatters) + return resolve_formatters(formatters, bufnr, false) end ---List information about all filetype-configured formatters @@ -303,7 +315,13 @@ M.list_all_formatters = function() end for _, formatter in ipairs(ft_formatters) do - formatters[formatter] = true + if type(formatter) == "table" then + for _, v in ipairs(formatter) do + formatters[v] = true + end + else + formatters[formatter] = true + end end end @@ -348,7 +366,7 @@ M.get_formatter_config = function(formatter, bufnr) end ---Get information about a formatter (including availability) ----@param formatter string +---@param formatter string The name of the formatter ---@param bufnr? integer ---@return conform.FormatterInfo M.get_formatter_info = function(formatter, bufnr) |