Feature: add a combined picker between buffers & git_files/files
Have you RTFM'd?
- [x] I have done proper research
Feature Request
I'd love a picker that would show me my open buffers at the top, then show me files (or git_files, I'm not so sure). I tried building it from the public API but most utility functions are local which makes it quite complicated to implement robustly and maintain with future changes. More generally (but probably harder), it would be interesting to be able to combine multiple pickers, and be able to specify the ordering.
Note: a way for me to build something like this in my config would be to expose the contents for specific pickers, that I could retrieve and try to combine myself
For now, I put this together, but I'm still missing the icons for the buffers and some robustness:
function FzfLuaSmart(opts)
local config = require('fzf-lua.config')
local core = require('fzf-lua.core')
local path = require('fzf-lua.path')
local libuv = require('fzf-lua.libuv')
local make_entry = require('fzf-lua.make_entry')
opts = config.normalize_opts(opts, 'git.files')
if not opts then
return
end
opts.cwd = path.git_root(opts)
opts.git_icons = true
opts.file_icons = true
if not opts.cwd then
return
end
local git_cmd = core.mt_cmd_wrapper(opts)
local git_fn = libuv.spawn_nvim_fzf_cmd({
cmd = git_cmd,
cwd = opts.cwd,
cb_pid = function(pid)
opts.__pid = pid
end,
})
local contents = function(x, cb, y)
make_entry.preprocess(opts)
for _, buf_id in ipairs(vim.api.nvim_list_bufs()) do
if
vim.api.nvim_buf_is_loaded(buf_id) and vim.fn.buflisted(buf_id) == 1
then
local p = vim.api.nvim_buf_get_name(buf_id)
local exists, stats = pcall(vim.uv.fs_stat, p)
if exists and stats and stats.type == 'file' then
cb(make_entry.file(p .. '\n', opts))
end
end
end
git_fn(x, cb, y)
end
opts = core.set_header(opts, opts.headers or { 'cwd' })
return core.fzf_exec(contents, opts)
end
Maybe in this way you can get icons for buffer:
@@ -31,7 +31,7 @@ function FzfLuaSmart(opts)
local p = vim.api.nvim_buf_get_name(buf_id)
local exists, stats = pcall(vim.uv.fs_stat, p)
if exists and stats and stats.type == "file" then
- cb(make_entry.file(p .. "\n", opts))
+ x(make_entry.file(p, opts))
end
end
end
Maybe there's other ways for this purpose, e.g. give a higher priority for atime when using fd/find/fzf (but they seems don't support this feature natively...)
Thanks ! This works for the icons.
As a skim maintainer, I can see a few way to do something like sorting using the atime` (using nth/with-nth for instance), but I don't think that's really what I want for now.
Note: I wasn't able to find much about these arguments (hence the x and y). Where can I find some to better understand it ?
Note: a way for me to build something like this in my config would be to expose the contents for specific pickers, that I could retrieve and try to combine myself
That’s def the better approach which I started working towards, lsp_finder has been using a contents array for a long time now:
https://github.com/ibhagwan/fzf-lua/blob/15d5cd9a74da7f8739030a5c411c046c70f66a60/lua/fzf-lua/core.lua#L149-L152
The issue I’m facing with these type of pickers is combing buffers which is lua type contents with files that is an external shell command (with a neovim headless wrapper), ATM these can’t be combined as it means I’d have to transfer the entire current state of the main instance to the headless instance to get buffers working properly.
Obviously we can use the simple approach and call vim.system for the files enumeration but that wouldn’t be performant and thus defeating the purpose IMHO.
Note: I wasn't able to find much about these arguments (hence the x and y). Where can I find some to better understand it ?
https://github.com/ibhagwan/fzf-lua/blob/15d5cd9a74da7f8739030a5c411c046c70f66a60/lua/fzf-lua/fzf.lua#L171-L174
We could always improve on docs and annotations, these didn’t even exist properly with lua_la when I started this project…
I've come here looking for exactly such a function! thanks so much!
FYI, once #2152 is merged (still needs work but it’s getting there), we’ll be able to combine pickers as easy as :FzfLua combine pickers=oldfiles,files (I’m not 100% set on the syntax/naming but something like this).
The PR still needs more work but you can try it out now in refactor_contents branch, and use:
:FzfLua combine pickers=buffers,git_files
-- Can even do something as useless as:
:FzfLua combine pickers=buffers,lsp_finder,git_status
This is just the first commit on this so expect bugs :-)
Closed via #2152, probably needs improvements, will open new issues for bugs/improvements.