local M = {} ---Collect formatter names from a single `formatters_by_ft` entry. --- ---A conform filetype formatter can be any of: --- * a list of formatter names, optionally followed by string-keyed format --- options (e.g. `{ "stylua", lsp_format = "fallback" }`) --- * a function `fun(bufnr): string[]`, used by the "run the first available --- formatter" recipe --- * the legacy nested list `{ { "prettierd", "prettier" } }` --- ---Only the array part of the table is traversed, so format options such as ---`lsp_format` and `stop_after_first` are ignored. ---@param value any ---@param out table local function collect_entry(value, out) local list = value if type(list) == "function" then -- A function may depend on a buffer and/or on run-time availability. -- We don't have a buffer to pass here, so evaluate it best-effort and -- silently skip it when it cannot be called without one. local ok, result = pcall(list) if not ok or type(result) ~= "table" then return end list = result end if type(list) ~= "table" then return end for _, formatter in ipairs(list) do if type(formatter) == "table" then -- Legacy "run the first available formatter" syntax. collect_entry(formatter, out) elseif type(formatter) == "string" then out[formatter] = true end end end ---List every formatter configured in conform's `formatters_by_ft`. --- ---Understands all `formatters_by_ft` shapes supported by conform, including ---functions returning a list and the legacy nested "run the first available" ---syntax. ---@return string[] names Sorted, de-duplicated formatter names. function M.configured() local out = {} for _, entry in pairs(require("conform").formatters_by_ft or {}) do collect_entry(entry, out) end local names = {} for name in pairs(out) do names[#names + 1] = name end table.sort(names) return names end return M