From 0bbe83830be5a07a1161bb1a23d7280310656177 Mon Sep 17 00:00:00 2001 From: Steven Arcangeli Date: Sat, 4 Nov 2023 13:24:48 -0700 Subject: feat: allow formatters_by_ft to be a function (#174) --- lua/conform/formatters/injected.lua | 8 +++++- lua/conform/health.lua | 8 +++++- lua/conform/init.lua | 55 +++++++++++++++++++------------------ 3 files changed, 42 insertions(+), 29 deletions(-) (limited to 'lua') diff --git a/lua/conform/formatters/injected.lua b/lua/conform/formatters/injected.lua index 21a9830..7028a8b 100644 --- a/lua/conform/formatters/injected.lua +++ b/lua/conform/formatters/injected.lua @@ -170,7 +170,13 @@ return { num_format = num_format + 1 last_start_lnum = start_lnum local input_lines = util.tbl_slice(lines, start_lnum, end_lnum) - local formatter_names = conform.formatters_by_ft[lang] + local ft_formatters = conform.formatters_by_ft[lang] + local formatter_names + if type(ft_formatters) == "function" then + formatter_names = ft_formatters(ctx.buf) + else + formatter_names = require("conform").resolve_formatters(ft_formatters, ctx.buf, false) + end local format_opts = { async = true, bufnr = ctx.buf, quiet = true } local idx = num_format log.debug("Injected format %s:%d:%d: %s", lang, start_lnum, end_lnum, formatter_names) diff --git a/lua/conform/health.lua b/lua/conform/health.lua index 7132007..3a1c9f6 100644 --- a/lua/conform/health.lua +++ b/lua/conform/health.lua @@ -12,8 +12,14 @@ local function get_formatter_filetypes(name) local conform = require("conform") local filetypes = {} for filetype, formatters in pairs(conform.formatters_by_ft) do + if type(formatters) == "function" then + formatters = formatters(0) -- support the old structure where formatters could be a subkey - if not vim.tbl_islist(formatters) then + elseif not vim.tbl_islist(formatters) then + vim.notify_once( + "Using deprecated structure for formatters_by_ft. See :help conform-options for details.", + vim.log.levels.ERROR + ) ---@diagnostic disable-next-line: undefined-field formatters = formatters.formatters end diff --git a/lua/conform/init.lua b/lua/conform/init.lua index 23c3818..32f24eb 100644 --- a/lua/conform/init.lua +++ b/lua/conform/init.lua @@ -56,8 +56,9 @@ local M = {} ---@field end integer[] ---@alias conform.FormatterUnit string|string[] +---@alias conform.FiletypeFormatter conform.FormatterUnit[]|fun(bufnr: integer): string[] ----@type table +---@type table M.formatters_by_ft = {} ---@type table @@ -78,20 +79,6 @@ M.setup = function(opts) M.notify_on_error = opts.notify_on_error end - for ft, formatters in pairs(M.formatters_by_ft) do - ---@diagnostic disable-next-line: undefined-field - if formatters.format_on_save ~= nil then - vim.notify( - string.format( - 'The "format_on_save" option for filetype "%s" is deprecated. It is recommended to put this logic in the autocmd, see :help conform-autoformat', - ft - ), - vim.log.levels.WARN - ) - break - end - end - local aug = vim.api.nvim_create_augroup("Conform", { clear = true }) if opts.format_on_save then if type(opts.format_on_save) == "boolean" then @@ -214,7 +201,6 @@ local function get_matching_filetype(bufnr) local filetypes = vim.split(vim.bo[bufnr].filetype, ".", { plain = true }) table.insert(filetypes, "_") for _, filetype in ipairs(filetypes) do - ---@type conform.FormatterUnit[] local ft_formatters = M.formatters_by_ft[filetype] if ft_formatters then return filetype @@ -254,16 +240,23 @@ M.list_formatters_for_buffer = function(bufnr) end table.insert(filetypes, "*") for _, ft in ipairs(filetypes) do - ---@type conform.FormatterUnit[] local ft_formatters = M.formatters_by_ft[ft] if ft_formatters then - -- support the old structure where formatters could be a subkey - if not vim.tbl_islist(ft_formatters) then - ---@diagnostic disable-next-line: undefined-field - ft_formatters = ft_formatters.formatters - end + if type(ft_formatters) == "function" then + dedupe_formatters(ft_formatters(bufnr), formatters) + else + -- support the old structure where formatters could be a subkey + if not vim.tbl_islist(ft_formatters) then + vim.notify_once( + "Using deprecated structure for formatters_by_ft. See :help conform-options for details.", + vim.log.levels.ERROR + ) + ---@diagnostic disable-next-line: undefined-field + ft_formatters = ft_formatters.formatters + end - dedupe_formatters(ft_formatters, formatters) + dedupe_formatters(ft_formatters, formatters) + end end end @@ -301,11 +294,12 @@ local function range_from_selection(bufnr, mode) } end +---@private ---@param names conform.FormatterUnit[] ---@param bufnr integer ---@param warn_on_missing boolean ---@return conform.FormatterInfo[] -local function resolve_formatters(names, bufnr, warn_on_missing) +M.resolve_formatters = function(names, bufnr, warn_on_missing) local all_info = {} local function add_info(info, warn) if info.available then @@ -372,7 +366,7 @@ M.format = function(opts, callback) local explicit_formatters = opts.formatters ~= nil local formatter_names = opts.formatters or M.list_formatters_for_buffer(opts.bufnr) local formatters = - resolve_formatters(formatter_names, opts.bufnr, not opts.quiet and explicit_formatters) + M.resolve_formatters(formatter_names, opts.bufnr, not opts.quiet and explicit_formatters) local any_formatters = not vim.tbl_isempty(formatters) if not explicit_formatters and opts.lsp_fallback == true and M.will_fallback_lsp(opts) then @@ -464,7 +458,7 @@ M.format_lines = function(formatter_names, lines, opts, callback) local errors = require("conform.errors") local log = require("conform.log") local runner = require("conform.runner") - local formatters = resolve_formatters(formatter_names, opts.bufnr, not opts.quiet) + local formatters = M.resolve_formatters(formatter_names, opts.bufnr, not opts.quiet) if vim.tbl_isempty(formatters) then callback(nil, lines) return @@ -499,7 +493,7 @@ M.list_formatters = function(bufnr) bufnr = vim.api.nvim_get_current_buf() end local formatters = M.list_formatters_for_buffer(bufnr) - return resolve_formatters(formatters, bufnr, false) + return M.resolve_formatters(formatters, bufnr, false) end ---List information about all filetype-configured formatters @@ -507,8 +501,15 @@ end M.list_all_formatters = function() local formatters = {} for _, ft_formatters in pairs(M.formatters_by_ft) do + if type(ft_formatters) == "function" then + ft_formatters = ft_formatters(0) + end -- support the old structure where formatters could be a subkey if not vim.tbl_islist(ft_formatters) then + vim.notify_once( + "Using deprecated structure for formatters_by_ft. See :help conform-options for details.", + vim.log.levels.ERROR + ) ---@diagnostic disable-next-line: undefined-field ft_formatters = ft_formatters.formatters end -- cgit v1.2.3-70-g09d2