Skip to content

Commit 32e19e0

Browse files
committed
feat: combine pickers (#1879)
Combine a list of pickers, first picker opts will determine the settings (window, previewer, etc), althought we can combine any number of pickers beware of combining pickers with wrong type of previewers as they may not work or worse, raise an exception. ```lua :FzfLua combine pickers=buffers,files ```
1 parent 93bf4f8 commit 32e19e0

13 files changed

Lines changed: 96 additions & 39 deletions

File tree

lua/fzf-lua/core.lua

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,11 @@ end
197197

198198
---@param contents string?
199199
---@param opts table
200-
---@return thread
200+
---@return thread, string, table
201201
M.fzf_wrap = function(contents, opts)
202202
opts = opts or {}
203203
local _co
204-
coroutine.wrap(function()
204+
local wrapped = coroutine.wrap(function()
205205
_co = coroutine.running()
206206
if type(opts.cb_co) == "function" then opts.cb_co(_co) end
207207
-- Default fzf exit callback acts upon the selected items
@@ -217,8 +217,13 @@ M.fzf_wrap = function(contents, opts)
217217
return
218218
end
219219
utils.err("fn_selected threw an error: " .. debug.traceback(err, 1))
220-
end)()
221-
return _co
220+
end)
221+
-- Do not strt fzf, return the stringified contents and opts onlu
222+
-- used by the "combine" picker to merge inputs
223+
if opts._start ~= false then
224+
wrapped()
225+
end
226+
return _co, contents, opts
222227
end
223228

224229
-- conditionally update the context if fzf-lua

lua/fzf-lua/init.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ do
287287
register_ui_select = { "fzf-lua.providers.ui_select", "register" },
288288
deregister_ui_select = { "fzf-lua.providers.ui_select", "deregister" },
289289
tmux_buffers = { "fzf-lua.providers.tmux", "buffers" },
290-
profiles = { "fzf-lua.providers.module", "profiles" },
290+
profiles = { "fzf-lua.providers.meta", "profiles" },
291+
combine = { "fzf-lua.providers.meta", "combine" },
291292
complete_path = { "fzf-lua.complete", "path" },
292293
complete_file = { "fzf-lua.complete", "file" },
293294
complete_line = { "fzf-lua.complete", "line" },
@@ -403,7 +404,7 @@ M.builtin = function(opts)
403404
if not opts then return end
404405
opts.metatable = M
405406
opts.metatable_exclude = M._excluded_metamap
406-
return require "fzf-lua.providers.module".metatable(opts)
407+
return require "fzf-lua.providers.meta".metatable(opts)
407408
end
408409

409410
return M

lua/fzf-lua/providers/buffers.lua

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,12 @@ M.buffers = function(opts)
214214
opts = core.set_header(opts, opts.headers or { "actions", "cwd" })
215215
opts = opts.filename_only and opts or core.set_fzf_field_index(opts)
216216

217-
core.fzf_exec(contents, opts)
217+
return core.fzf_exec(contents, opts)
218218
end
219219

220220
M.lines = function(opts)
221221
opts = config.normalize_opts(opts, "lines")
222-
M.buffer_lines(opts)
222+
return M.buffer_lines(opts)
223223
end
224224

225225
M.blines = function(opts)
@@ -230,7 +230,7 @@ M.blines = function(opts)
230230
opts.start_line = opts.start_line or sel.start.line
231231
opts.end_line = opts.end_line or sel["end"].line
232232
end
233-
M.buffer_lines(opts)
233+
return M.buffer_lines(opts)
234234
end
235235

236236

@@ -352,7 +352,7 @@ M.buffer_lines = function(opts)
352352
end
353353

354354
opts = core.set_fzf_field_index(opts, "{3}", opts._is_skim and "{}" or "{..-2}")
355-
core.fzf_exec(contents, opts)
355+
return core.fzf_exec(contents, opts)
356356
end
357357

358358
M.tabs = function(opts)
@@ -466,7 +466,7 @@ M.tabs = function(opts)
466466
opts = core.set_header(opts, opts.headers or { "actions", "cwd" })
467467
opts = opts.filename_only and opts or core.set_fzf_field_index(opts, "{4}", "{}")
468468

469-
core.fzf_exec(contents, opts)
469+
return core.fzf_exec(contents, opts)
470470
end
471471

472472

@@ -600,7 +600,7 @@ M.treesitter = function(opts)
600600

601601
opts = core.set_header(opts, opts.headers or { "actions" })
602602

603-
core.fzf_exec(contents, opts)
603+
return core.fzf_exec(contents, opts)
604604
end
605605

606606
M.spellcheck = function(opts)
@@ -703,7 +703,7 @@ M.spellcheck = function(opts)
703703

704704
opts = core.set_header(opts, opts.headers or { "actions" })
705705

706-
core.fzf_exec(contents, opts)
706+
return core.fzf_exec(contents, opts)
707707
end
708708

709709
return M

lua/fzf-lua/providers/colorschemes.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ M.colorschemes = function(opts)
8282
utils.setup_highlights()
8383
end
8484

85-
core.fzf_exec(colors, opts)
85+
return core.fzf_exec(colors, opts)
8686
end
8787

8888
M.highlights = function(opts)
@@ -137,7 +137,7 @@ M.highlights = function(opts)
137137
end
138138
end
139139

140-
core.fzf_exec(contents, opts)
140+
return core.fzf_exec(contents, opts)
141141
end
142142

143143

lua/fzf-lua/providers/dap.lua

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ M.commands = function(opts)
4040
end,
4141
}
4242

43-
core.fzf_exec(entries, opts)
43+
return core.fzf_exec(entries, opts)
4444
end
4545

4646
M.configurations = function(opts)
@@ -73,7 +73,7 @@ M.configurations = function(opts)
7373
end,
7474
}
7575

76-
core.fzf_exec(entries, opts)
76+
return core.fzf_exec(entries, opts)
7777
end
7878

7979
M.breakpoints = function(opts)
@@ -116,7 +116,7 @@ M.breakpoints = function(opts)
116116
opts = core.set_header(opts, opts.headers or { "actions", "cwd" })
117117
opts = core.set_fzf_field_index(opts, "{3}", opts._is_skim and "{}" or "{..-2}")
118118

119-
core.fzf_exec(contents, opts)
119+
return core.fzf_exec(contents, opts)
120120
end
121121

122122
M.variables = function(opts)
@@ -147,7 +147,7 @@ M.variables = function(opts)
147147
end
148148
end
149149

150-
core.fzf_exec(entries, opts)
150+
return core.fzf_exec(entries, opts)
151151
end
152152

153153
M.frames = function(opts)
@@ -238,7 +238,7 @@ M.frames = function(opts)
238238
))
239239
end
240240

241-
core.fzf_exec(entries, opts)
241+
return core.fzf_exec(entries, opts)
242242
end
243243

244244
return M

lua/fzf-lua/providers/git.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ local function git_cmd(opts)
5959
opts = set_git_cwd_args(opts)
6060
if not opts.cwd then return end
6161
opts = core.set_header(opts, opts.headers or { "cwd" })
62-
core.fzf_exec(opts.cmd, opts)
62+
return core.fzf_exec(opts.cmd, opts)
6363
end
6464

6565
local function git_preview(opts, file)

lua/fzf-lua/providers/grep.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ M.grep = function(opts)
206206
opts = core.set_title_flags(opts, { "cmd" })
207207
opts = core.set_header(opts, opts.headers or { "actions", "cwd", "search" })
208208
opts = core.set_fzf_field_index(opts)
209-
core.fzf_exec(opts.cmd, opts)
209+
return core.fzf_exec(opts.cmd, opts)
210210
end
211211

212212
local function normalize_live_grep_opts(opts)

lua/fzf-lua/providers/helptags.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ M.helptags = function(opts)
9999
end)()
100100
end
101101

102-
core.fzf_exec(contents, opts)
102+
return core.fzf_exec(contents, opts)
103103
end
104104

105105
return M

lua/fzf-lua/providers/manpages.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ M.manpages = function(opts)
4141
return string.format("%-45s %s", man, desc)
4242
end
4343

44-
core.fzf_exec(opts.cmd, opts)
44+
return core.fzf_exec(opts.cmd, opts)
4545
end
4646

4747
return M
Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ M.metatable = function(opts)
3131
-- as the behavior might confuse users (#267)
3232
opts.no_resume = true
3333

34-
core.fzf_exec(methods, opts)
34+
return core.fzf_exec(methods, opts)
3535
end
3636

3737
---@param dir string
@@ -97,4 +97,55 @@ M.profiles = function(opts)
9797
return core.fzf_exec(contents, opts)
9898
end
9999

100+
M.combine = function(t)
101+
t = t or {}
102+
t.pickers = type(t.pickers) == "table" and type(t.pickers)
103+
or type(t.pickers) == "string" and utils.strsplit(t.pickers, "[,;]")
104+
or nil
105+
106+
-- First picker options set the tone
107+
local opts1 = (function()
108+
if t.pickers[1] then
109+
local ok, opts = pcall(config.normalize_opts, t, t.pickers[1])
110+
if not ok or not opts then
111+
utils.warn("Must specify at least one valid picker")
112+
else
113+
return opts
114+
end
115+
end
116+
end)()
117+
if not opts1 then return end
118+
119+
-- Let fzf_wrap know to NOT start the coroutine
120+
opts1._start = false
121+
122+
local cmds, opts = (function()
123+
local ret, opts = {}, nil
124+
for i, p in ipairs(t.pickers) do
125+
-- local ok, msg, cmd, o = pcall(FzfLua[p], opts1)
126+
-- if not ok or not cmd then
127+
local _, cmd, o = FzfLua[p](opts1)
128+
if not cmd or not o then
129+
-- utils.warn(string.format("Error loading picker '%s', ignoring.\nError: %s", p, msg))
130+
utils.warn(string.format("Error loading picker '%s', ignoring.", p))
131+
else
132+
table.insert(ret, cmd)
133+
-- NOTE: we use the [first picker] modified opts after picker setup
134+
-- as pickers can modify opts / add important parts (fn_pre_fzf, etc)
135+
if not opts then opts = o end
136+
end
137+
end
138+
return ret, opts
139+
end)()
140+
if not opts then return end
141+
142+
-- Let fzf_wrap know to START the coroutine
143+
opts._start = nil
144+
145+
-- _G.dump(cmds)
146+
local contents = table.concat(cmds, utils.__IS_WINDOWS and "&" or ";")
147+
148+
return core.fzf_wrap(contents, opts)
149+
end
150+
100151
return M

0 commit comments

Comments
 (0)