diff options
author | Steven Arcangeli <506791+stevearc@users.noreply.github.com> | 2023-10-15 16:18:08 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-15 16:18:08 -0700 |
commit | 7027ebbd772e2d3593f7dd566dea06d2d20622ee (patch) | |
tree | b78bbe24dda9cd7e1272bce6c699b5e576d76a66 /lua/conform | |
parent | 9b5fbddfca5080c6961dabafb3f0a6ef7e2fc18a (diff) |
feat!: merge configs in conform.formatters with defaults (#140)
This breaking change should make it significantly easier to modify formatters. While I expect 99% of configs to be backwards-compatible, this can still potentially cause problems. If you:
* define a formatter in the `formatters` option
* that has the same name as a built-in formatter
* and omits a property from the original formatter (e.g. leaves out `range_args` or `cwd`)
Then you may encounter breaking behavior from this commit, because now your config definition will be merged with the built-in definition, and so will inherit those omitted properties. This config merging behavior can be opted-out of by adding `inherit = false` to your formatter config.
Diffstat (limited to 'lua/conform')
-rw-r--r-- | lua/conform/formatters/injected.lua | 11 | ||||
-rw-r--r-- | lua/conform/init.lua | 46 | ||||
-rw-r--r-- | lua/conform/util.lua | 11 |
3 files changed, 51 insertions, 17 deletions
diff --git a/lua/conform/formatters/injected.lua b/lua/conform/formatters/injected.lua index 71005bc..21a9830 100644 --- a/lua/conform/formatters/injected.lua +++ b/lua/conform/formatters/injected.lua @@ -60,15 +60,10 @@ local function apply_indent(lines, indentation) end end ----@class conform.InjectedFormatterConfig : conform.FileLuaFormatterConfig ----@field format fun(self: conform.InjectedFormatterConfig, ctx: conform.Context, lines: string[], callback: fun(err: nil|string, new_lines: nil|string[])) ----@field condition? fun(self: conform.InjectedFormatterConfig, ctx: conform.Context): boolean ----@field options conform.InjectedFormatterOptions - ---@class (exact) conform.InjectedFormatterOptions ---@field ignore_errors boolean ----@type conform.InjectedFormatterConfig +---@type conform.FileLuaFormatterConfig return { meta = { url = "doc/advanced_topics.md#injected-language-formatting-code-blocks", @@ -94,6 +89,8 @@ return { callback("No treesitter parser for buffer") return end + ---@type conform.InjectedFormatterOptions + local options = self.options --- Disable diagnostic to pass the typecheck github action --- This is available on nightly, but not on stable --- Stable doesn't have any parameters, so it's safe to always pass `true` @@ -134,7 +131,7 @@ return { i = i + 1 end end - if self.options.ignore_errors then + if options.ignore_errors then format_error = nil end end diff --git a/lua/conform/init.lua b/lua/conform/init.lua index 7a3cae6..724aad6 100644 --- a/lua/conform/init.lua +++ b/lua/conform/init.lua @@ -21,6 +21,7 @@ local M = {} ---@class (exact) conform.LuaFormatterConfig ---@field format fun(self: conform.LuaFormatterConfig, ctx: conform.Context, lines: string[], callback: fun(err: nil|string, new_lines: nil|string[])) ---@field condition? fun(self: conform.LuaFormatterConfig, ctx: conform.Context): boolean +---@field options? table ---@class (exact) conform.FileLuaFormatterConfig : conform.LuaFormatterConfig ---@field meta conform.FormatterMeta @@ -30,6 +31,12 @@ local M = {} ---@alias conform.FormatterConfig conform.JobFormatterConfig|conform.LuaFormatterConfig +---@class (exact) conform.FormatterConfigOverride : conform.JobFormatterConfig +---@field inherit? boolean +---@field command? string|fun(ctx: conform.Context): string +---@field prepend_args? string|string[]|fun(ctx: conform.Context): string|string[] +---@field options? table + ---@class (exact) conform.FormatterMeta ---@field url string ---@field description string @@ -53,7 +60,7 @@ local M = {} ---@type table<string, conform.FormatterUnit[]> M.formatters_by_ft = {} ----@type table<string, conform.FormatterConfig|fun(bufnr: integer): nil|conform.FormatterConfig> +---@type table<string, conform.FormatterConfigOverride|fun(bufnr: integer): nil|conform.FormatterConfigOverride> M.formatters = {} M.notify_on_error = true @@ -538,20 +545,39 @@ M.get_formatter_config = function(formatter, bufnr) if not bufnr or bufnr == 0 then bufnr = vim.api.nvim_get_current_buf() end - ---@type nil|conform.FormatterConfig|fun(bufnr: integer): nil|conform.FormatterConfig - local config = M.formatters[formatter] - if type(config) == "function" then - config = config(bufnr) + ---@type nil|conform.FormatterConfigOverride|fun(bufnr: integer): nil|conform.FormatterConfigOverride + local override = M.formatters[formatter] + if type(override) == "function" then + override = override(bufnr) end - if not config then - local ok - ok, config = pcall(require, "conform.formatters." .. formatter) - if not ok then + + ---@type nil|conform.FormatterConfig + local config = override + if not override or override.inherit ~= false then + local ok, mod_config = pcall(require, "conform.formatters." .. formatter) + if ok then + if override then + config = require("conform.util").merge_formatter_configs(mod_config, override) + else + config = mod_config + end + elseif override then + if override.command then + config = override + else + local msg = string.format( + "Formatter '%s' missing built-in definition\nSet `command` to get rid of this error.", + formatter + ) + vim.notify_once(msg, vim.log.levels.ERROR) + return nil + end + else return nil end end - if config.stdin == nil then + if config and config.stdin == nil then config.stdin = true end return config diff --git a/lua/conform/util.lua b/lua/conform/util.lua index 8a0073a..bbb711a 100644 --- a/lua/conform/util.lua +++ b/lua/conform/util.lua @@ -156,6 +156,17 @@ M.add_formatter_args = function(formatter, extra_args, opts) end end +---@param config conform.FormatterConfig +---@param override conform.FormatterConfigOverride +---@return conform.FormatterConfig +M.merge_formatter_configs = function(config, override) + local ret = vim.tbl_deep_extend("force", config, override) + if override.prepend_args then + M.add_formatter_args(ret, override.prepend_args, { append = false }) + end + return ret +end + ---@param bufnr integer ---@return integer M.buf_get_changedtick = function(bufnr) |