Skip to content

Commit e325fab

Browse files
committed
fix(config): defaults override special tables
ref: #2692
1 parent 1ae863c commit e325fab

1 file changed

Lines changed: 61 additions & 51 deletions

File tree

lua/fzf-lua/config.lua

Lines changed: 61 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,48 @@ M.globals = setmetatable({}, {
7777
local function setup_defaults()
7878
return M._profile_opts and (M._profile_opts.defaults or {}) or M.setup_opts.defaults or {}
7979
end
80+
local special_tbl = function(opts, k)
81+
local fzflua_default = utils.map_get(M.defaults, k)
82+
local setup_default = utils.map_get(setup_defaults(), k)
83+
local setup_value = utils.map_get(setup_opts(), k)
84+
-- convert function types
85+
if type(opts[k]) == "function" then opts[k] = opts[k](opts) end
86+
if type(setup_value) == "function" then setup_value = setup_value(opts) end
87+
-- NOTE: maybe we should assert for non-table values?
88+
-- return all non table values in this priority
89+
-- (1) setup `defaults = { k = ...}` trumps all
90+
-- (2) opts.<k>
91+
-- (3) setup({ <k> })
92+
if setup_default ~= nil and type(setup_default) ~= "table" then return setup_default end
93+
if opts[k] ~= nil and type(opts[k]) ~= "table" then return opts[k] end
94+
if not setup_default and not opts[k]
95+
and setup_value ~= nil and type(setup_value) ~= "table"
96+
then
97+
return setup_value
98+
end
99+
opts[k] = opts[k] or {}
100+
fzflua_default = fzflua_default or {}
101+
setup_default = setup_default or {}
102+
setup_value = type(setup_value) == "table" and setup_value or {}
103+
-- (1) setup defaults trumps all, e.g. `defaults = { winopts = {...} }`
104+
-- (2) merge setup on top, e.g. `setup({ winopts = {...} })`
105+
-- (3) merge fzf-lua true defaults on top
106+
opts[k] = vim.tbl_deep_extend("force", {}, opts[k], setup_default)
107+
opts[k] = vim.tbl_deep_extend("keep", opts[k], setup_value)
108+
opts[k] = vim.tbl_deep_extend("keep", opts[k], fzflua_default)
109+
local function build_bind_tables(keys)
110+
for _, _k in ipairs(keys) do
111+
-- TODO: lowercase merge, handle [1] = {true|false|
112+
opts[k][_k][1] = nil
113+
end
114+
end
115+
if k == "actions" then
116+
build_bind_tables({ "files", "buffers" })
117+
elseif k == "keymap" then
118+
build_bind_tables({ "fzf", "builtin" })
119+
end
120+
return opts
121+
end
80122
-- build normalized globals, option priority below:
81123
-- (1) provider specific globals (post-setup)
82124
-- (2) generic global-defaults (post-setup), i.e. `setup({ defaults = { ... } })`
@@ -122,16 +164,31 @@ M.globals = setmetatable({}, {
122164
elseif fzflua_default == nil and setup_value == nil then
123165
return
124166
end
167+
-- the existence of the `actions` key implies we're dealing with a picker
168+
local is_picker =
169+
(fzflua_default and (fzflua_default.actions or fzflua_default._actions))
170+
or (setup_value and (setup_value.actions or setup_value._actions))
125171
-- (1) use fzf-lua's true defaults (pre-setup) as our options base
126172
local ret = utils.tbl_deep_clone(fzflua_default) or {}
127-
if (fzflua_default and (fzflua_default.actions or fzflua_default._actions))
128-
or (setup_value and (setup_value.actions or setup_value._actions)) then
129-
-- (2) the existence of the `actions` key implies we're dealing with a picker
130-
-- override global provider defaults supplied by the user's setup `defaults` table
173+
if is_picker then
174+
-- (2.1) override global picker defaults with the user's setup `defaults` table
131175
ret = vim.tbl_deep_extend("force", ret, setup_defaults())
176+
elseif type(setup_default) == "table" then
177+
-- (2.2) index was included in defaults, e.g. `{ defaults = winopts = { ... } }`
178+
-- TODO: do we ever get here after the special_tbl change?
179+
assert(index)
180+
ret = vim.tbl_deep_extend("force", ret, setup_default)
132181
end
133182
-- (3) override with the specific provider options from the users's `setup` option
134183
ret = vim.tbl_deep_extend("force", ret, utils.map_get(setup_opts(), index) or {})
184+
-- (4) for pickers, special tables which merge from true globals but can be
185+
-- overwritten from setup defaults, e.g. `{ defaults = winopts = { ... } }`
186+
if is_picker then
187+
for _, k in ipairs({ "winopts", "keymap", "fzf_opts", "fzf_colors", "fzf_tmux_opts", "hls" })
188+
do
189+
ret = special_tbl(ret, k)
190+
end
191+
end
135192
return ret
136193
end,
137194
__newindex = function(_, index, _)
@@ -334,53 +391,6 @@ function M.normalize_opts(opts, globals, __resume_key) ---@diagnostic disable
334391
-- merge with provider defaults from globals (defaults + setup options)
335392
opts = vim.tbl_deep_extend("keep", opts, utils.tbl_deep_clone(globals))
336393

337-
-- Backward compat: merge `winopts` with outputs from `winopts_fn`
338-
local winopts_fn = opts.winopts_fn or M.globals.winopts_fn
339-
if type(winopts_fn) == "function" then
340-
vim.deprecate("winopts_fn", "winopts", "Jan 2026", "FzfLua")
341-
local ret = winopts_fn(opts) or {}
342-
if not utils.tbl_isempty(ret) and (not opts.winopts or type(opts.winopts) == "table") then
343-
opts.winopts = vim.tbl_deep_extend("force", opts.winopts or {}, ret)
344-
end
345-
end
346-
347-
local extend_opts = function(m, k)
348-
local setup_val = m[k]
349-
if type(setup_val) == "function" then
350-
setup_val = setup_val(opts)
351-
if type(setup_val) == "table" then
352-
local default_val = utils.map_get(M.defaults, k)
353-
if type(default_val) == "table" then
354-
setup_val = vim.tbl_deep_extend("force", {}, default_val, setup_val)
355-
end
356-
end
357-
end
358-
if type(setup_val) == "table" then
359-
-- must clone or map will be saved as reference
360-
-- and then overwritten if found in 'backward_compat'
361-
setup_val = utils.tbl_deep_clone(setup_val)
362-
end
363-
if opts[k] == nil then
364-
opts[k] = setup_val
365-
else
366-
if type(opts[k]) == "function" then
367-
opts[k] = opts[k](opts)
368-
end
369-
if type(opts[k]) == "table" then
370-
opts[k] = vim.tbl_deep_extend("keep",
371-
opts[k], type(setup_val) == "table" and setup_val or {})
372-
end
373-
end
374-
end
375-
376-
-- Merge values from globals
377-
for _, k in ipairs({
378-
"winopts", "keymap", "fzf_opts", "fzf_colors", "fzf_tmux_opts", "hls"
379-
}) do
380-
extend_opts(globals, k)
381-
extend_opts(M.globals, k)
382-
end
383-
384394
-- backward compat: no-value flags should be set to `true`, in the past these
385395
-- would be set to an empty string which would now translate into a shell escaped
386396
-- string as we automatically shell escape all fzf_opts

0 commit comments

Comments
 (0)